Skip to content
Snippets Groups Projects
Commit b84eeb25 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 53ae6b7e
No related branches found
No related tags found
No related merge requests found
Showing
with 251 additions and 71 deletions
Loading
Loading
@@ -200,7 +200,7 @@
 
.use-pg9:
services:
- name: postgres:9.6
- name: postgres:9.6.17
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:alpine
variables:
Loading
Loading
@@ -209,7 +209,7 @@
.use-pg10:
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.5-golang-1.12-git-2.24-lfs-2.9-chrome-73.0-node-12.x-yarn-1.21-postgresql-10-graphicsmagick-1.3.34"
services:
- name: postgres:10.9
- name: postgres:10.12
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:alpine
variables:
Loading
Loading
@@ -217,7 +217,7 @@
 
.use-pg9-ee:
services:
- name: postgres:9.6
- name: postgres:9.6.17
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:alpine
- name: elasticsearch:6.4.2
Loading
Loading
@@ -227,7 +227,7 @@
.use-pg10-ee:
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.5-golang-1.12-git-2.24-lfs-2.9-chrome-73.0-node-12.x-yarn-1.21-postgresql-10-graphicsmagick-1.3.34"
services:
- name: postgres:10.9
- name: postgres:10.12
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:alpine
- name: elasticsearch:6.4.2
Loading
Loading
Loading
Loading
@@ -3,7 +3,7 @@
* This is tightly coupled to projects/issues/_issue.html.haml,
* any changes done to the haml need to be reflected here.
*/
import { escape, isNumber } from 'underscore';
import { escape, isNumber } from 'lodash';
import { GlLink, GlTooltipDirective as GlTooltip } from '@gitlab/ui';
import {
dateInWords,
Loading
Loading
@@ -19,8 +19,6 @@ import { mergeUrlParams } from '~/lib/utils/url_utility';
import Icon from '~/vue_shared/components/icon.vue';
import IssueAssignees from '~/vue_shared/components/issue/issue_assignees.vue';
 
const ISSUE_TOKEN = '#';
export default {
components: {
Icon,
Loading
Loading
@@ -119,8 +117,7 @@ export default {
);
},
referencePath() {
// TODO: The API should return the reference path (it doesn't now) https://gitlab.com/gitlab-org/gitlab/issues/31301
return `${ISSUE_TOKEN}${this.issuable.iid}`;
return this.issuable.references.relative;
},
updatedDateString() {
return formatDate(new Date(this.issuable.updated_at), 'mmm d, yyyy h:MMtt');
Loading
Loading
@@ -230,7 +227,7 @@ export default {
</div>
 
<div class="issuable-info">
<span>{{ referencePath }}</span>
<span class="js-ref-path">{{ referencePath }}</span>
 
<span class="d-none d-sm-inline-block mr-1">
&middot;
Loading
Loading
Loading
Loading
@@ -62,9 +62,21 @@ export default {
return (
report.existing_failures.length > 0 ||
report.new_failures.length > 0 ||
report.resolved_failures.length > 0
report.resolved_failures.length > 0 ||
report.existing_errors.length > 0 ||
report.new_errors.length > 0 ||
report.resolved_errors.length > 0
);
},
unresolvedIssues(report) {
return report.existing_failures.concat(report.existing_errors);
},
newIssues(report) {
return report.new_failures.concat(report.new_errors);
},
resolvedIssues(report) {
return report.resolved_failures.concat(report.resolved_errors);
},
},
};
</script>
Loading
Loading
@@ -87,9 +99,9 @@ export default {
<issues-list
v-if="shouldRenderIssuesList(report)"
:key="`issues-list-${i}`"
:unresolved-issues="report.existing_failures"
:new-issues="report.new_failures"
:resolved-issues="report.resolved_failures"
:unresolved-issues="unresolvedIssues(report)"
:new-issues="newIssues(report)"
:resolved-issues="resolvedIssues(report)"
:component="$options.componentNames.TestIssueBody"
class="report-block-group-list"
/>
Loading
Loading
Loading
Loading
@@ -16,6 +16,7 @@ export default {
state.summary.total = response.summary.total;
state.summary.resolved = response.summary.resolved;
state.summary.failed = response.summary.failed;
state.summary.errored = response.summary.errored;
 
state.status = response.status;
state.reports = response.suites;
Loading
Loading
@@ -29,6 +30,7 @@ export default {
total: 0,
resolved: 0,
failed: 0,
errored: 0,
};
state.status = null;
},
Loading
Loading
Loading
Loading
@@ -13,6 +13,7 @@ export default () => ({
total: 0,
resolved: 0,
failed: 0,
errored: 0,
},
 
/**
Loading
Loading
@@ -23,10 +24,14 @@ export default () => ({
* total: {Number},
* resolved: {Number},
* failed: {Number},
* errored: {Number},
* },
* new_failures: {Array.<Object>},
* resolved_failures: {Array.<Object>},
* existing_failures: {Array.<Object>},
* new_errors: {Array.<Object>},
* resolved_errors: {Array.<Object>},
* existing_errors: {Array.<Object>},
* }
*/
reports: [],
Loading
Loading
Loading
Loading
@@ -8,10 +8,11 @@ import {
} from '../constants';
 
const textBuilder = results => {
const { failed, resolved, total } = results;
const { failed, errored, resolved, total } = results;
 
const failedString = failed
? n__('%d failed/error test result', '%d failed/error test results', failed)
const failedOrErrored = (failed || 0) + (errored || 0);
const failedString = failedOrErrored
? n__('%d failed/error test result', '%d failed/error test results', failedOrErrored)
: null;
const resolvedString = resolved
? n__('%d fixed test result', '%d fixed test results', resolved)
Loading
Loading
@@ -20,7 +21,7 @@ const textBuilder = results => {
 
let resultsString = s__('Reports|no changed test results');
 
if (failed) {
if (failedOrErrored) {
if (resolved) {
resultsString = sprintf(s__('Reports|%{failedString} and %{resolvedString}'), {
failedString,
Loading
Loading
Loading
Loading
@@ -86,8 +86,12 @@ module Boards
head(:forbidden) unless can?(current_user, :admin_issue, board)
end
 
def serializer_options(issues)
{}
end
def render_issues(issues, metadata)
data = { issues: serialize_as_json(issues) }
data = { issues: serialize_as_json(issues, opts: serializer_options(issues)) }
data.merge!(metadata)
 
render json: data
Loading
Loading
@@ -133,8 +137,10 @@ module Boards
IssueSerializer.new(current_user: current_user)
end
 
def serialize_as_json(resource)
serializer.represent(resource, serializer: 'board', include_full_project_path: board.group_board?)
def serialize_as_json(resource, opts: {})
opts.merge!(include_full_project_path: board.group_board?, serializer: 'board')
serializer.represent(resource, opts)
end
 
def whitelist_query_limiting
Loading
Loading
# frozen_string_literal: true
module Mutations
module Notes
class Update < Base
graphql_name 'UpdateNote'
authorize :admin_note
argument :id,
GraphQL::ID_TYPE,
required: true,
description: 'The global id of the note to update'
argument :body,
GraphQL::STRING_TYPE,
required: true,
description: copy_field_description(Types::Notes::NoteType, :body)
def resolve(args)
note = authorized_find!(id: args[:id])
check_object_is_note!(note)
note = ::Notes::UpdateService.new(
note.project,
current_user,
{ note: args[:body] }
).execute(note)
{
note: note.reset,
errors: errors_on_object(note)
}
end
end
end
end
# frozen_string_literal: true
module Mutations
module Notes
module Update
# This is a Base class for the Note update mutations and is not
# mounted as a GraphQL mutation itself.
class Base < Mutations::Notes::Base
authorize :admin_note
argument :id,
GraphQL::ID_TYPE,
required: true,
description: 'The global id of the note to update'
def resolve(args)
note = authorized_find!(id: args[:id])
pre_update_checks!(note, args)
updated_note = ::Notes::UpdateService.new(
note.project,
current_user,
note_params(note, args)
).execute(note)
# It's possible for updated_note to be `nil`, in the situation
# where the note is deleted within `Notes::UpdateService` due to
# the body of the note only containing Quick Actions.
{
note: updated_note&.reset,
errors: updated_note ? errors_on_object(updated_note) : []
}
end
private
def pre_update_checks!(_note, _args)
raise NotImplementedError
end
def note_params(_note, args)
{ note: args[:body] }.compact
end
end
end
end
end
# frozen_string_literal: true
module Mutations
module Notes
module Update
class ImageDiffNote < Mutations::Notes::Update::Base
graphql_name 'UpdateImageDiffNote'
argument :body,
GraphQL::STRING_TYPE,
required: false,
description: copy_field_description(Types::Notes::NoteType, :body)
argument :position,
Types::Notes::UpdateDiffImagePositionInputType,
required: false,
description: copy_field_description(Types::Notes::NoteType, :position)
def ready?(**args)
# As both arguments are optional, validate here that one of the
# arguments are present.
#
# This may be able to be done using InputUnions in the future
# if this RFC is merged:
# https://github.com/graphql/graphql-spec/blob/master/rfcs/InputUnion.md
if args.values_at(:body, :position).compact.blank?
raise Gitlab::Graphql::Errors::ArgumentError,
'body or position arguments are required'
end
super(args)
end
private
def pre_update_checks!(note, args)
unless note.is_a?(DiffNote) && note.position.on_image?
raise Gitlab::Graphql::Errors::ResourceNotAvailable,
'Resource is not an ImageDiffNote'
end
end
def note_params(note, args)
super(note, args).merge(
position: position_params(note, args)
).compact
end
def position_params(note, args)
new_position = args[:position]&.to_h&.compact
return unless new_position
original_position = note.position.to_h
Gitlab::Diff::Position.new(original_position.merge(new_position))
end
end
end
end
end
# frozen_string_literal: true
module Mutations
module Notes
module Update
class Note < Mutations::Notes::Update::Base
graphql_name 'UpdateNote'
argument :body,
GraphQL::STRING_TYPE,
required: true,
description: copy_field_description(Types::Notes::NoteType, :body)
private
def pre_update_checks!(note, _args)
check_object_is_note!(note)
end
end
end
end
end
Loading
Loading
@@ -4,7 +4,7 @@ module Types
class MutationType < BaseObject
include Gitlab::Graphql::MountMutation
 
graphql_name "Mutation"
graphql_name 'Mutation'
 
mount_mutation Mutations::AwardEmojis::Add
mount_mutation Mutations::AwardEmojis::Remove
Loading
Loading
@@ -20,7 +20,14 @@ module Types
mount_mutation Mutations::Notes::Create::Note, calls_gitaly: true
mount_mutation Mutations::Notes::Create::DiffNote, calls_gitaly: true
mount_mutation Mutations::Notes::Create::ImageDiffNote, calls_gitaly: true
mount_mutation Mutations::Notes::Update
mount_mutation Mutations::Notes::Update::Note,
description: 'Updates a Note. If the body of the Note contains only quick actions, ' \
'the Note will be destroyed during the update, and no Note will be ' \
'returned'
mount_mutation Mutations::Notes::Update::ImageDiffNote,
description: 'Updates a DiffNote on an image (a `Note` where the `position.positionType` is `"image"`). ' \
'If the body of the Note contains only quick actions, the Note will be ' \
'destroyed during the update, and no Note will be returned'
mount_mutation Mutations::Notes::Destroy
mount_mutation Mutations::Todos::MarkDone
mount_mutation Mutations::Todos::Restore
Loading
Loading
Loading
Loading
@@ -29,10 +29,10 @@ module Types
 
# Fields for image positions
field :x, GraphQL::INT_TYPE, null: true,
description: 'X position on which the comment was made',
description: 'X position of the note',
resolve: -> (position, _args, _ctx) { position.x if position.on_image? }
field :y, GraphQL::INT_TYPE, null: true,
description: 'Y position on which the comment was made',
description: 'Y position of the note',
resolve: -> (position, _args, _ctx) { position.y if position.on_image? }
field :width, GraphQL::INT_TYPE, null: true,
description: 'Total width of the image',
Loading
Loading
# frozen_string_literal: true
module Types
module Notes
# InputType used for updateImageDiffNote mutation.
#
# rubocop: disable Graphql/AuthorizeTypes
class UpdateDiffImagePositionInputType < BaseInputObject
graphql_name 'UpdateDiffImagePositionInput'
argument :x, GraphQL::INT_TYPE,
required: false,
description: copy_field_description(Types::Notes::DiffPositionType, :x)
argument :y, GraphQL::INT_TYPE,
required: false,
description: copy_field_description(Types::Notes::DiffPositionType, :y)
argument :width, GraphQL::INT_TYPE,
required: false,
description: copy_field_description(Types::Notes::DiffPositionType, :width)
argument :height, GraphQL::INT_TYPE,
required: false,
description: copy_field_description(Types::Notes::DiffPositionType, :height)
end
# rubocop: enable Graphql/AuthorizeTypes
end
end
Loading
Loading
@@ -720,8 +720,7 @@ module ProjectsHelper
end
 
def settings_container_registry_expiration_policy_available?(project)
Feature.enabled?(:registry_retention_policies_settings, project) &&
Gitlab.config.registry.enabled &&
Gitlab.config.registry.enabled &&
can?(current_user, :destroy_container_image, project)
end
end
Loading
Loading
@@ -15,7 +15,13 @@ module Emails
def pipeline_mail(pipeline, recipients, status)
@project = pipeline.project
@pipeline = pipeline
@merge_request = pipeline.all_merge_requests.first
@merge_request = if pipeline.merge_request?
pipeline.merge_request
else
pipeline.merge_requests_as_head_pipeline.first
end
add_headers
 
# We use bcc here because we don't want to generate these emails for a
Loading
Loading
Loading
Loading
@@ -15,8 +15,8 @@ module Analytics
validates :name, exclusion: { in: Gitlab::Analytics::CycleAnalytics::DefaultStages.names }, if: :custom?
validates :start_event_identifier, presence: true
validates :end_event_identifier, presence: true
validates :start_event_label, presence: true, if: :start_event_label_based?
validates :end_event_label, presence: true, if: :end_event_label_based?
validates :start_event_label_id, presence: true, if: :start_event_label_based?
validates :end_event_label_id, presence: true, if: :end_event_label_based?
validate :validate_stage_event_pairs
validate :validate_labels
 
Loading
Loading
@@ -109,8 +109,8 @@ module Analytics
end
 
def validate_labels
validate_label_within_group(:start_event_label, start_event_label_id) if start_event_label_id_changed?
validate_label_within_group(:end_event_label, end_event_label_id) if end_event_label_id_changed?
validate_label_within_group(:start_event_label_id, start_event_label_id) if start_event_label_id_changed?
validate_label_within_group(:end_event_label_id, end_event_label_id) if end_event_label_id_changed?
end
 
def validate_label_within_group(association_name, label_id)
Loading
Loading
Loading
Loading
@@ -7,6 +7,7 @@ class TestReportsComparerEntity < Grape::Entity
expose :total_count, as: :total
expose :resolved_count, as: :resolved
expose :failed_count, as: :failed
expose :error_count, as: :errored
end
 
expose :suite_comparers, as: :suites, using: TestSuiteComparerEntity
Loading
Loading
Loading
Loading
@@ -11,6 +11,7 @@ class TestSuiteComparerEntity < Grape::Entity
expose :total_count, as: :total
expose :resolved_count, as: :resolved
expose :failed_count, as: :failed
expose :error_count, as: :errored
end
 
# rubocop: disable CodeReuse/ActiveRecord
Loading
Loading
@@ -28,6 +29,20 @@ class TestSuiteComparerEntity < Grape::Entity
max_tests(suite.new_failures, suite.existing_failures))
end
 
expose :new_errors, using: TestCaseEntity do |suite|
suite.new_errors.take(max_tests)
end
expose :existing_errors, using: TestCaseEntity do |suite|
suite.existing_errors.take(
max_tests(suite.new_errors))
end
expose :resolved_errors, using: TestCaseEntity do |suite|
suite.resolved_errors.take(
max_tests(suite.new_errors, suite.existing_errors))
end
private
 
def max_tests(*used)
Loading
Loading
Loading
Loading
@@ -24,7 +24,9 @@ module Snippets
spam_check(snippet, current_user)
 
snippet_saved = snippet.with_transaction_returning_status do
snippet.save
if snippet.save && snippet.store_mentions!
create_repository_for(snippet, current_user)
end
end
 
if snippet_saved
Loading
Loading
@@ -36,5 +38,11 @@ module Snippets
snippet_error_response(snippet, 400)
end
end
private
def create_repository_for(snippet, user)
snippet.create_repository if Feature.enabled?(:version_snippets, user)
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment