diff --git a/app/assets/javascripts/content_editor/components/suggestions_dropdown.vue b/app/assets/javascripts/content_editor/components/suggestions_dropdown.vue index c4617983488..043db617452 100644 --- a/app/assets/javascripts/content_editor/components/suggestions_dropdown.vue +++ b/app/assets/javascripts/content_editor/components/suggestions_dropdown.vue @@ -57,6 +57,22 @@ export default { return this.isReference && this.nodeProps.referenceType === 'issue'; }, + isLabel() { + return this.isReference && this.nodeProps.referenceType === 'label'; + }, + + isEpic() { + return this.isReference && this.nodeProps.referenceType === 'epic'; + }, + + isSnippet() { + return this.isReference && this.nodeProps.referenceType === 'snippet'; + }, + + isVulnerability() { + return this.isReference && this.nodeProps.referenceType === 'vulnerability'; + }, + isMergeRequest() { return this.isReference && this.nodeProps.referenceType === 'merge_request'; }, @@ -86,10 +102,17 @@ export default { case 'issue': case 'merge_request': return `${this.char}${item.iid}`; + case 'snippet': + return `${this.char}${item.id}`; case 'milestone': + case 'label': return `${this.char}${item.title}`; case 'command': return `${this.char}${item.name} `; + case 'epic': + return `${item.reference}`; + case 'vulnerability': + return `[vulnerability:${item.id}]`; default: return ''; } @@ -184,16 +207,32 @@ export default { {{ item.iid }} {{ item.title }} + + {{ item.id }} + {{ item.title }} + + + {{ item.reference }} + {{ item.title }} + {{ item.title }} + + + {{ item.title }} + /{{ item.name }} {{ item.params[0] }}
{{ item.description }}
-
+
{{ item.e }}
{{ item.name }}
diff --git a/app/assets/javascripts/content_editor/extensions/suggestions.js b/app/assets/javascripts/content_editor/extensions/suggestions.js index ef7f64e573e..1b345a36c7e 100644 --- a/app/assets/javascripts/content_editor/extensions/suggestions.js +++ b/app/assets/javascripts/content_editor/extensions/suggestions.js @@ -121,7 +121,6 @@ export default Node.create({ dataSource: gl.GfmAutoComplete?.dataSources.members, nodeType: 'reference', nodeProps: { - className: 'gfm gfm-project_member', referenceType: 'user', }, search: (query) => ({ name, username }) => find(name, query) || find(username, query), @@ -132,18 +131,56 @@ export default Node.create({ dataSource: gl.GfmAutoComplete?.dataSources.issues, nodeType: 'reference', nodeProps: { - className: 'gfm gfm-issue', referenceType: 'issue', }, search: (query) => ({ iid, title }) => find(iid, query) || find(title, query), }), + createSuggestionPlugin({ + editor: this.editor, + char: '$', + dataSource: gl.GfmAutoComplete?.dataSources.snippets, + nodeType: 'reference', + nodeProps: { + referenceType: 'snippet', + }, + search: (query) => ({ id, title }) => find(id, query) || find(title, query), + }), + createSuggestionPlugin({ + editor: this.editor, + char: '~', + dataSource: gl.GfmAutoComplete?.dataSources.labels, + nodeType: 'reference', + nodeProps: { + referenceType: 'label', + }, + search: (query) => ({ title }) => find(title, query), + }), + createSuggestionPlugin({ + editor: this.editor, + char: '&', + dataSource: gl.GfmAutoComplete?.dataSources.epics, + nodeType: 'reference', + nodeProps: { + referenceType: 'epic', + }, + search: (query) => ({ iid, title }) => find(iid, query) || find(title, query), + }), + createSuggestionPlugin({ + editor: this.editor, + char: '[vulnerability:', + dataSource: gl.GfmAutoComplete?.dataSources.vulnerabilities, + nodeType: 'reference', + nodeProps: { + referenceType: 'vulnerability', + }, + search: (query) => ({ id, title }) => find(id, query) || find(title, query), + }), createSuggestionPlugin({ editor: this.editor, char: '!', dataSource: gl.GfmAutoComplete?.dataSources.mergeRequests, nodeType: 'reference', nodeProps: { - className: 'gfm gfm-issue', referenceType: 'merge_request', }, search: (query) => ({ iid, title }) => find(iid, query) || find(title, query), @@ -154,7 +191,6 @@ export default Node.create({ dataSource: gl.GfmAutoComplete?.dataSources.milestones, nodeType: 'reference', nodeProps: { - className: 'gfm gfm-milestone', referenceType: 'milestone', }, search: (query) => ({ iid, title }) => find(iid, query) || find(title, query), diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js index 7b523c95c74..5234be44b05 100644 --- a/app/assets/javascripts/diffs/store/actions.js +++ b/app/assets/javascripts/diffs/store/actions.js @@ -202,6 +202,7 @@ export const fetchDiffFilesMeta = ({ commit, state }) => { const worker = new TreeWorker(); const urlParams = { view: 'inline', + w: state.showWhitespace ? '0' : '1', }; commit(types.SET_LOADING, true); diff --git a/app/assets/stylesheets/components/related_items_list.scss b/app/assets/stylesheets/components/related_items_list.scss index 3bb889b6ba0..293caf6fc87 100644 --- a/app/assets/stylesheets/components/related_items_list.scss +++ b/app/assets/stylesheets/components/related_items_list.scss @@ -75,19 +75,6 @@ $item-remove-button-space: 42px; } } -.item-body, -.card-header { - .health-label-short { - max-width: 0; - } -} - -.card-header { - .health-label-short { - display: initial; - } -} - .item-meta { flex-basis: 100%; font-size: $gl-font-size; @@ -212,11 +199,6 @@ $item-remove-button-space: 42px; max-width: 90%; } - .card-header { - .health-label-short { - max-width: 30px; - } - } } /* Small devices (landscape phones, 768px and up) */ @@ -239,11 +221,6 @@ $item-remove-button-space: 42px; } } - .card-header { - .health-label-short { - max-width: 60px; - } - } } /* Medium devices (desktops, 992px and up) */ @@ -257,12 +234,6 @@ $item-remove-button-space: 42px; font-size: inherit; // Base size given to `item-meta` is `$gl-font-size-small` } } - - .card-header { - .health-label-short { - max-width: 100px; - } - } } /* Large devices (large desktops, 1200px and up) */ @@ -309,15 +280,3 @@ $item-remove-button-space: 42px; flex-basis: auto; } } - -@media only screen and (min-width: 1500px) { - .card-header { - .health-label-short { - display: none; - } - - .health-label-long { - display: block; - } - } -} diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index d7319b0726f..9c139733248 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -554,7 +554,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo end def endpoint_metadata_url(project, merge_request) - params = request.query_parameters.merge(view: 'inline', diff_head: true) + params = request.query_parameters.merge(view: 'inline', diff_head: true, w: current_user&.show_whitespace_in_diffs ? '0' : '1') diffs_metadata_project_json_merge_request_path(project, merge_request, 'json', params) end diff --git a/app/graphql/resolvers/concerns/resolves_merge_requests.rb b/app/graphql/resolvers/concerns/resolves_merge_requests.rb index b6510e7c5fa..d56951bc821 100644 --- a/app/graphql/resolvers/concerns/resolves_merge_requests.rb +++ b/app/graphql/resolvers/concerns/resolves_merge_requests.rb @@ -52,7 +52,8 @@ module ResolvesMergeRequests head_pipeline: [:merge_request_diff, { head_pipeline: [:merge_request] }], timelogs: [:timelogs], pipelines: [:merge_request_diffs], # used by `recent_diff_head_shas` to load pipelines - committers: [merge_request_diff: [:merge_request_diff_commits]] + committers: [merge_request_diff: [:merge_request_diff_commits]], + suggested_reviewers: [:predictions] } end end diff --git a/app/graphql/types/ci/config_variable_type.rb b/app/graphql/types/ci/config_variable_type.rb index 87ae026c2c1..5b5890fd5a5 100644 --- a/app/graphql/types/ci/config_variable_type.rb +++ b/app/graphql/types/ci/config_variable_type.rb @@ -17,6 +17,10 @@ module Types field :value, GraphQL::Types::String, null: true, description: 'Value of the variable.' + + field :value_options, [GraphQL::Types::String], + null: true, + description: 'Value options for the variable.' end end end diff --git a/app/services/bulk_imports/create_pipeline_trackers_service.rb b/app/services/bulk_imports/create_pipeline_trackers_service.rb index e6b2e5e0e05..f5b944e6df5 100644 --- a/app/services/bulk_imports/create_pipeline_trackers_service.rb +++ b/app/services/bulk_imports/create_pipeline_trackers_service.rb @@ -58,7 +58,8 @@ module BulkImports pipeline_name: pipeline[:pipeline], minimum_source_version: minimum_version, maximum_source_version: maximum_version, - source_version: source_version.to_s + source_version: source_version.to_s, + importer: 'gitlab_migration' ) end diff --git a/app/services/incident_management/issuable_escalation_statuses/prepare_update_service.rb b/app/services/incident_management/issuable_escalation_statuses/prepare_update_service.rb index 58777848151..d495ec5cab6 100644 --- a/app/services/incident_management/issuable_escalation_statuses/prepare_update_service.rb +++ b/app/services/incident_management/issuable_escalation_statuses/prepare_update_service.rb @@ -11,7 +11,7 @@ module IncidentManagement @issuable = issuable @param_errors = [] - super(project: issuable.project, current_user: current_user, params: Hash(params)) + super(project: issuable.project, current_user: current_user, params: params) end def execute diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb index 40c7742a3aa..887c9ec84f5 100644 --- a/app/services/issuable_base_service.rb +++ b/app/services/issuable_base_service.rb @@ -154,10 +154,13 @@ class IssuableBaseService < ::BaseProjectService end def filter_escalation_status(issuable) + status_params = params.delete(:escalation_status) || {} + status_params.permit! if status_params.respond_to?(:permit!) + result = ::IncidentManagement::IssuableEscalationStatuses::PrepareUpdateService.new( issuable, current_user, - params.delete(:escalation_status) + status_params ).execute return unless result.success? && result[:escalation_status].present? @@ -270,8 +273,9 @@ class IssuableBaseService < ::BaseProjectService # To be overridden by subclasses end - def after_update(issuable) + def after_update(issuable, old_associations) handle_description_updated(issuable) + handle_label_changes(issuable, old_associations[:labels]) end def handle_description_updated(issuable) @@ -327,7 +331,7 @@ class IssuableBaseService < ::BaseProjectService affected_assignees = (old_associations[:assignees] + new_assignees) - (old_associations[:assignees] & new_assignees) invalidate_cache_counts(issuable, users: affected_assignees.compact) - after_update(issuable) + after_update(issuable, old_associations) issuable.create_new_cross_references!(current_user) execute_hooks( issuable, @@ -367,7 +371,8 @@ class IssuableBaseService < ::BaseProjectService handle_task_changes(issuable) invalidate_cache_counts(issuable, users: issuable.assignees.to_a) - after_update(issuable) + # not passing old_associations here to keep `update_task` as fast as possible + after_update(issuable, {}) execute_hooks(issuable, 'update', old_associations: nil) if issuable.is_a?(MergeRequest) @@ -542,6 +547,8 @@ class IssuableBaseService < ::BaseProjectService end def has_label_changes?(issuable, old_labels) + return false if old_labels.nil? + Set.new(issuable.labels) != Set.new(old_labels) end @@ -553,12 +560,15 @@ class IssuableBaseService < ::BaseProjectService # override if needed def handle_label_changes(issuable, old_labels) - return unless has_label_changes?(issuable, old_labels) + return false unless has_label_changes?(issuable, old_labels) # reset to preserve the label sort order (title ASC) issuable.labels.reset GraphqlTriggers.issuable_labels_updated(issuable) + + # return true here to avoid checking for label changes in sub classes + true end # override if needed diff --git a/app/services/issues/base_service.rb b/app/services/issues/base_service.rb index d75e74f3b19..28ea6b0ebf8 100644 --- a/app/services/issues/base_service.rb +++ b/app/services/issues/base_service.rb @@ -68,6 +68,19 @@ module Issues rebalance_if_needed(issue) end + def handle_escalation_status_change(issue) + return unless issue.supports_escalation? + + if issue.escalation_status + ::IncidentManagement::IssuableEscalationStatuses::AfterUpdateService.new( + issue, + current_user + ).execute + else + ::IncidentManagement::IssuableEscalationStatuses::CreateService.new(issue).execute + end + end + def issuable_for_positioning(id, positioning_scope) return unless id diff --git a/app/services/issues/create_service.rb b/app/services/issues/create_service.rb index e2cd007d16c..89b35bbab24 100644 --- a/app/services/issues/create_service.rb +++ b/app/services/issues/create_service.rb @@ -65,7 +65,7 @@ module Issues user_agent_detail_service.create handle_add_related_issue(issue) resolve_discussions_with_issue(issue) - create_escalation_status(issue) + handle_escalation_status_change(issue) create_timeline_event(issue) try_to_associate_contacts(issue) @@ -102,10 +102,6 @@ module Issues attr_reader :spam_params, :extra_params - def create_escalation_status(issue) - ::IncidentManagement::IssuableEscalationStatuses::CreateService.new(issue).execute if issue.supports_escalation? - end - def create_timeline_event(issue) return unless issue.incident? diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb index 46c28d82ddc..e5feb4422f6 100644 --- a/app/services/issues/update_service.rb +++ b/app/services/issues/update_service.rb @@ -63,7 +63,6 @@ module Issues handle_assignee_changes(issue, old_assignees) handle_confidential_change(issue) - handle_label_changes(issue, old_labels) handle_added_labels(issue, old_labels) handle_milestone_change(issue) handle_added_mentions(issue, old_mentioned_users) @@ -201,15 +200,6 @@ module Issues ::IncidentManagement::AddSeveritySystemNoteWorker.perform_async(issue.id, current_user.id) end - def handle_escalation_status_change(issue) - return unless issue.supports_escalation? && issue.escalation_status - - ::IncidentManagement::IssuableEscalationStatuses::AfterUpdateService.new( - issue, - current_user - ).execute - end - def create_confidentiality_note(issue) SystemNoteService.change_issue_confidentiality(issue, issue.project, current_user) end diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb index 98b120360cd..bc832690aa1 100644 --- a/app/services/merge_requests/update_service.rb +++ b/app/services/merge_requests/update_service.rb @@ -38,7 +38,6 @@ module MergeRequests handle_target_branch_change(merge_request) handle_milestone_change(merge_request) handle_draft_status_change(merge_request, changed_fields) - handle_label_changes(merge_request, old_labels) track_title_and_desc_edits(changed_fields) track_discussion_lock_toggle(merge_request, changed_fields) @@ -71,7 +70,7 @@ module MergeRequests MergeRequests::CloseService end - def after_update(issuable) + def after_update(issuable, old_associations) super issuable.cache_merge_request_closes_issues!(current_user) end diff --git a/app/services/work_items/update_service.rb b/app/services/work_items/update_service.rb index e87a19422cb..f66639b0149 100644 --- a/app/services/work_items/update_service.rb +++ b/app/services/work_items/update_service.rb @@ -49,7 +49,7 @@ module WorkItems super end - def after_update(work_item) + def after_update(work_item, old_associations) super GraphqlTriggers.issuable_title_updated(work_item) if work_item.previous_changes.key?(:title) diff --git a/app/workers/bulk_imports/entity_worker.rb b/app/workers/bulk_imports/entity_worker.rb index 78a45b15416..ada3210624c 100644 --- a/app/workers/bulk_imports/entity_worker.rb +++ b/app/workers/bulk_imports/entity_worker.rb @@ -18,7 +18,8 @@ module BulkImports bulk_import_entity_id: entity_id, bulk_import_id: bulk_import_id(entity_id), current_stage: current_stage, - message: 'Stage running' + message: 'Stage running', + importer: 'gitlab_migration' ) ) @@ -30,7 +31,8 @@ module BulkImports bulk_import_entity_id: entity_id, bulk_import_id: bulk_import_id(entity_id), current_stage: current_stage, - message: 'Stage starting' + message: 'Stage starting', + importer: 'gitlab_migration' ) ) @@ -47,12 +49,13 @@ module BulkImports bulk_import_entity_id: entity_id, bulk_import_id: bulk_import_id(entity_id), current_stage: current_stage, - message: e.message + message: e.message, + importer: 'gitlab_migration' ) ) Gitlab::ErrorTracking.track_exception( - e, bulk_import_entity_id: entity_id, bulk_import_id: bulk_import_id(entity_id) + e, bulk_import_entity_id: entity_id, bulk_import_id: bulk_import_id(entity_id), importer: 'gitlab_migration' ) end diff --git a/app/workers/bulk_imports/export_request_worker.rb b/app/workers/bulk_imports/export_request_worker.rb index 1f830a0530d..d2a7eee1064 100644 --- a/app/workers/bulk_imports/export_request_worker.rb +++ b/app/workers/bulk_imports/export_request_worker.rb @@ -42,7 +42,9 @@ module BulkImports structured_payload( log_attributes(exception, entity).merge( bulk_import_id: entity.bulk_import_id, - bulk_import_entity_type: entity.source_type + bulk_import_entity_type: entity.source_type, + message: "Request to export #{entity.source_type} failed", + importer: 'gitlab_migration' ) ) ) @@ -83,7 +85,8 @@ module BulkImports log_attributes(e, entity).merge( message: 'Failed to fetch source entity id', bulk_import_id: entity.bulk_import_id, - bulk_import_entity_type: entity.source_type + bulk_import_entity_type: entity.source_type, + importer: 'gitlab_migration' ) ) ) diff --git a/app/workers/bulk_imports/pipeline_worker.rb b/app/workers/bulk_imports/pipeline_worker.rb index 873bd7c377a..6d314774cff 100644 --- a/app/workers/bulk_imports/pipeline_worker.rb +++ b/app/workers/bulk_imports/pipeline_worker.rb @@ -21,7 +21,9 @@ module BulkImports structured_payload( bulk_import_entity_id: pipeline_tracker.entity.id, bulk_import_id: pipeline_tracker.entity.bulk_import_id, - pipeline_name: pipeline_tracker.pipeline_name + pipeline_name: pipeline_tracker.pipeline_name, + message: 'Pipeline starting', + importer: 'gitlab_migration' ) ) @@ -32,7 +34,8 @@ module BulkImports bulk_import_entity_id: entity_id, bulk_import_id: bulk_import_id(entity_id), pipeline_tracker_id: pipeline_tracker_id, - message: 'Unstarted pipeline not found' + message: 'Unstarted pipeline not found', + importer: 'gitlab_migration' ) ) end @@ -74,7 +77,8 @@ module BulkImports bulk_import_entity_id: pipeline_tracker.entity.id, bulk_import_id: pipeline_tracker.entity.bulk_import_id, pipeline_name: pipeline_tracker.pipeline_name, - message: exception.message + message: exception.message, + importer: 'gitlab_migration' ) ) @@ -82,7 +86,8 @@ module BulkImports exception, bulk_import_entity_id: pipeline_tracker.entity.id, bulk_import_id: pipeline_tracker.entity.bulk_import_id, - pipeline_name: pipeline_tracker.pipeline_name + pipeline_name: pipeline_tracker.pipeline_name, + importer: 'gitlab_migration' ) BulkImports::Failure.create( @@ -150,7 +155,8 @@ module BulkImports bulk_import_entity_id: pipeline_tracker.entity.id, bulk_import_id: pipeline_tracker.entity.bulk_import_id, pipeline_name: pipeline_tracker.pipeline_name, - message: "Retrying error: #{exception.message}" + message: "Retrying error: #{exception.message}", + importer: 'gitlab_migration' ) ) @@ -165,7 +171,8 @@ module BulkImports bulk_import_entity_id: pipeline_tracker.entity.id, bulk_import_id: pipeline_tracker.entity.bulk_import_id, pipeline_name: pipeline_tracker.pipeline_name, - message: 'Skipping pipeline due to failed entity' + message: 'Skipping pipeline due to failed entity', + importer: 'gitlab_migration' ) ) diff --git a/doc/administration/operations/rails_console.md b/doc/administration/operations/rails_console.md index 11ddc674b7b..829760903b4 100644 --- a/doc/administration/operations/rails_console.md +++ b/doc/administration/operations/rails_console.md @@ -680,3 +680,18 @@ unlike with issues or merge requests. ```ruby ApplicationSetting.current ``` + +### Open object in `irb` + +Sometimes it is easier to go through a method if you are in the context of the object. You can shim into the namespace of `Object` to let you open `irb` in the context of any object: + +```ruby +Object.define_method(:irb) { binding.irb } + +project = Project.last +# => #> +project.irb +# Notice new context +irb(#)> web_url +# => "https://gitlab-example/root/discard" +``` diff --git a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md index 55dae5dcad1..f52f979a002 100644 --- a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md +++ b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md @@ -62,21 +62,6 @@ Notify.test_email(e, "Test email for #{n}", 'Test email').deliver_now Notify.test_email(u.email, "Test email for #{u.name}", 'Test email').deliver_now ``` -## Open object in `irb` - -Sometimes it is easier to go through a method if you are in the context of the object. You can shim into the namespace of `Object` to let you open `irb` in the context of any object: - -```ruby -Object.define_method(:irb) { binding.irb } - -project = Project.last -# => #> -project.irb -# Notice new context -irb(#)> web_url -# => "https://gitlab-example/root/discard" -``` - ## Time an operation ```ruby @@ -359,37 +344,6 @@ repeat the above procedure after, and report the output to [GitLab Support](https://about.gitlab.com/support/). -## Repository - -### Search sequence of pushes to a repository - -If it seems that a commit has gone "missing", search the sequence of pushes to a repository. -[This StackOverflow article](https://stackoverflow.com/questions/13468027/the-mystery-of-the-missing-commit-across-merges) -describes how you can end up in this state without a force push. Another cause can be a misconfigured [server hook](../server_hooks.md) that changes a HEAD ref via a `git reset` operation. - -If you look at the output from the sample code below for the target branch, you -see a discontinuity in the from/to commits as you step through the output. The `commit_from` of each new push should equal the `commit_to` of the previous push. A break in that sequence indicates one or more commits have been "lost" from the repository history. - -The following example checks the last 100 pushes and prints the `commit_from` and `commit_to` entries: - -```ruby -p = Project.find_by_full_path('u/p') -p.events.pushed_action.last(100).each do |e| - printf "%-20.20s %8s...%8s (%s) -", e.push_event_payload[:ref], e.push_event_payload[:commit_from], e.push_event_payload[:commit_to], e.author.try(:username) -end -``` - -Example output showing break in sequence at line 4: - -```plaintext -master f21b07713251e04575908149bdc8ac1f105aabc3...6bc56c1f46244792222f6c85b11606933af171de (root) -master 6bc56c1f46244792222f6c85b11606933af171de...132da6064f5d3453d445fd7cb452b148705bdc1b (root) -master 132da6064f5d3453d445fd7cb452b148705bdc1b...a62e1e693150a2e46ace0ce696cd4a52856dfa65 (root) -master 58b07b719a4b0039fec810efa52f479ba1b84756...f05321a5b5728bd8a89b7bf530aa44043c951dce (root) -master f05321a5b5728bd8a89b7bf530aa44043c951dce...7d02e575fd790e76a3284ee435368279a5eb3773 (root) -``` - ## Mirrors ### Find mirrors with "bad decrypt" errors diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 1dda66a2e43..4a9cf3df5fc 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -10406,6 +10406,7 @@ CI/CD config variables. | `description` | [`String`](#string) | Description for the CI/CD config variable. | | `key` | [`String`](#string) | Name of the variable. | | `value` | [`String`](#string) | Value of the variable. | +| `valueOptions` | [`[String!]`](#string) | Value options for the variable. | ### `CiGroup` diff --git a/doc/architecture/blueprints/pods/2022-10-05-Pods-Organizations-Iteration0.png b/doc/architecture/blueprints/pods/2022-10-05-Pods-Organizations-Iteration0.png deleted file mode 100644 index 48a1a8fc893..00000000000 Binary files a/doc/architecture/blueprints/pods/2022-10-05-Pods-Organizations-Iteration0.png and /dev/null differ diff --git a/doc/architecture/blueprints/pods/index.md b/doc/architecture/blueprints/pods/index.md index 523616a9354..e565bd3e478 100644 --- a/doc/architecture/blueprints/pods/index.md +++ b/doc/architecture/blueprints/pods/index.md @@ -24,6 +24,8 @@ We use the following terms to describe components and properties of the Pods arc A Pod is a set of infrastructure components that contains multiple top-level namespaces that belong to different organizations. The components include both datastores (PostgreSQL, Redis etc.) and stateless services (web etc.). The infrastructure components provided within a Pod are shared among organizations and their top-level namespaces but not shared with other Pods. This isolation of infrastructure components means that Pods are independent from each other. +![Term Pod](term-pod.png) + #### Pod properties - Each pod is independent from the others @@ -40,6 +42,14 @@ Discouraged synonyms: GitLab instance, cluster, shard A cluster is a collection of Pods. +![Term Cluster](term-cluster.png) + +#### Cluster properties + +- A cluster holds cluster-wide metadata, for example Users, Routes, Settings. + +Discouraged synonyms: whale + ### Organizations GitLab references [Organizations in the initial set up](../../../topics/set_up_organization.md) and users can add a (free text) organization to their profile. There is no Organization entity established in the GitLab codebase. @@ -54,6 +64,9 @@ Organizations work under the following assumptions: 1. Features need to work within an organization. 1. Only few features need to work across organizations. 1. Users understand that the majority of pages they view are only scoped to a single organization at a time. +1. Organizations are located on a single pod. + +![Term Organization](term-organization.png) #### Organization properties @@ -81,6 +94,8 @@ Top-level namespaces may [be replaced by workspaces](https://gitlab.com/gitlab-o Discouraged synonyms: Root-level namespace +![Term Top-level Namespace](term-top-level-namespace.png) + #### Top-level namespace properties - Top-level namespaces belonging to an organization are located on the same Pod @@ -174,7 +189,7 @@ Organizations solve the following problems: 1. Self-managed instances would set a default organization. 1. Organizations can control user-profiles in a central way. This could be achieved by having an organization specific user-profile. Such a profile makes it possible for the organization administrators to control the user role in a company, enforce user emails, or show a graphical indicator of a user being part of the organization. An example would be a "GitLab Employee stamp" on comments. -![Move to Organizations](2022-10-05-Pods-Organizations-Iteration0.png) +![Move to Organizations](iteration0-organizations-introduction.png) #### Why would customers opt-in to Organizations? diff --git a/doc/architecture/blueprints/pods/iteration0-organizations-introduction.png b/doc/architecture/blueprints/pods/iteration0-organizations-introduction.png new file mode 100644 index 00000000000..5f5cad7b169 Binary files /dev/null and b/doc/architecture/blueprints/pods/iteration0-organizations-introduction.png differ diff --git a/doc/architecture/blueprints/pods/term-cluster.png b/doc/architecture/blueprints/pods/term-cluster.png new file mode 100644 index 00000000000..f52e31b52ad Binary files /dev/null and b/doc/architecture/blueprints/pods/term-cluster.png differ diff --git a/doc/architecture/blueprints/pods/term-organization.png b/doc/architecture/blueprints/pods/term-organization.png new file mode 100644 index 00000000000..f605adb124d Binary files /dev/null and b/doc/architecture/blueprints/pods/term-organization.png differ diff --git a/doc/architecture/blueprints/pods/term-pod.png b/doc/architecture/blueprints/pods/term-pod.png new file mode 100644 index 00000000000..d8f79df2f29 Binary files /dev/null and b/doc/architecture/blueprints/pods/term-pod.png differ diff --git a/doc/architecture/blueprints/pods/term-top-level-namespace.png b/doc/architecture/blueprints/pods/term-top-level-namespace.png new file mode 100644 index 00000000000..c1cd317d878 Binary files /dev/null and b/doc/architecture/blueprints/pods/term-top-level-namespace.png differ diff --git a/doc/ci/runners/runners_scope.md b/doc/ci/runners/runners_scope.md index c998980a4c1..e5526b4e396 100644 --- a/doc/ci/runners/runners_scope.md +++ b/doc/ci/runners/runners_scope.md @@ -172,8 +172,12 @@ To create a group runner: 1. [Install GitLab Runner](https://docs.gitlab.com/runner/install/). 1. On the top bar, select **Main menu > Groups** and find your group. 1. On the left sidebar, select **CI/CD > Runners**. -1. Note the URL and token. -1. [Register the runner](https://docs.gitlab.com/runner/register/). +1. In the top-right corner, select **Register a group runner**. +1. Select **Show runner installation and registration instructions**. + These instructions include the token, URL, and a command to register a runner. + +Alternately, you can copy the registration token and follow the documentation for +how to [register a runner](https://docs.gitlab.com/runner/register/). ### View and manage group runners diff --git a/doc/ci/runners/saas/macos_saas_runner.md b/doc/ci/runners/saas/macos_saas_runner.md index bbc8da23e58..50c24349712 100644 --- a/doc/ci/runners/saas/macos_saas_runner.md +++ b/doc/ci/runners/saas/macos_saas_runner.md @@ -14,10 +14,6 @@ Use these runners to build, test, and deploy apps for the Apple ecosystem (macOS of all the capabilities of the GitLab single DevOps platform and not have to manage or operate a build environment. -CI/CD minutes used on GitLab SaaS macOS runners are included in your CI/CD minute consumption totals. CI jobs that run on macOS **will** consume CI minutes at a faster rate than CI jobs on the GitLab SaaS runners on Linux. - -Refer to the CI/CD minutes [cost factor](../../../ci/pipelines/cicd_minutes.md#cost-factor) for the cost factor applied to the GitLab SaaS macOS runners. - Jobs handled by macOS shared runners on GitLab.com **time out after 2 hours**, regardless of the timeout configured in a project. ## Access request process diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md index 938d70c73a5..aff4dfbb67b 100644 --- a/doc/ci/yaml/index.md +++ b/doc/ci/yaml/index.md @@ -2165,7 +2165,7 @@ This example creates four paths of execution: explicitly defined for all jobs that use the `needs` keyword, or are referenced in a job's `needs` section. - In GitLab 13.9 and older, if `needs` refers to a job that might not be added to - a pipeline because of `only`, `except`, or `rules`, the pipeline might fail to create. + a pipeline because of `only`, `except`, or `rules`, the pipeline might fail to create. In GitLab 13.10 and later, use the [`needs:optional`](#needsoptional) keyword to resolve a failed pipeline creation. #### `needs:artifacts` diff --git a/doc/development/cicd/index.md b/doc/development/cicd/index.md index be633eaa12e..cd31038ddd1 100644 --- a/doc/development/cicd/index.md +++ b/doc/development/cicd/index.md @@ -96,6 +96,9 @@ when transitioning to the `pending` state. This job is responsible for creating a multi-project or child pipeline. The workflow loop starts again from the `CreatePipelineService` every time a downstream pipeline is triggered. + +You can watch a walkthrough of the architecture in [CI Backend Architectural Walkthrough](https://www.youtube.com/watch?v=ew4BwohS5OY). + ## Job scheduling When a Pipeline is created all its jobs are created at once for all stages, with an initial state of `created`. This makes it possible to visualize the full content of a pipeline. diff --git a/doc/development/code_review.md b/doc/development/code_review.md index 3c129645756..6d919b486d5 100644 --- a/doc/development/code_review.md +++ b/doc/development/code_review.md @@ -149,7 +149,7 @@ with [domain expertise](#domain-experts). | `~UX` user-facing changes (*3*) | [Product Designer](https://about.gitlab.com/handbook/engineering/projects/#gitlab_reviewers_UX). Refer to the [design and user interface guidelines](contributing/design.md) for details. | | Adding a new JavaScript library (*1*) | - [Frontend foundations member](https://about.gitlab.com/direction/ecosystem/foundations/) if the library significantly increases the [bundle size](https://gitlab.com/gitlab-org/frontend/playground/webpack-memory-metrics/-/blob/master/doc/report.md).
- A [legal department member](https://about.gitlab.com/handbook/legal/) if the license used by the new library hasn't been approved for use in GitLab.

More information about license compatibility can be found in our [GitLab Licensing and Compatibility documentation](licensing.md). | | A new dependency or a file system change | - [Distribution team member](https://about.gitlab.com/company/team/). See how to work with the [Distribution team](https://about.gitlab.com/handbook/engineering/development/enablement/systems/distribution/#how-to-work-with-distribution) for more details.
- For Rubygems, request an [AppSec review](gemfile.md#request-an-appsec-review). | -| `~documentation` changes | [Technical writer](https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments) based on assignments in the appropriate [DevOps stage group](https://about.gitlab.com/handbook/product/categories/#devops-stages). | +| `~documentation` or `~UI text` changes | [Technical writer](https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments) based on assignments in the appropriate [DevOps stage group](https://about.gitlab.com/handbook/product/categories/#devops-stages). | | Changes to development guidelines | Follow the [review process](development_processes.md#development-guidelines-review) and get the approvals accordingly. | | End-to-end **and** non-end-to-end changes (*4*) | [Software Engineer in Test](https://about.gitlab.com/handbook/engineering/quality/#individual-contributors). | | Only End-to-end changes (*4*) **or** if the MR author is a [Software Engineer in Test](https://about.gitlab.com/handbook/engineering/quality/#individual-contributors) | [Quality maintainer](https://about.gitlab.com/handbook/engineering/projects/#gitlab_maintainers_qa). | diff --git a/doc/user/project/code_owners.md b/doc/user/project/code_owners.md index f36e1444909..aeeacd495a7 100644 --- a/doc/user/project/code_owners.md +++ b/doc/user/project/code_owners.md @@ -335,8 +335,10 @@ If you update the `CODEOWNERS` file, close the merge request and create a new on ### User not shown as possible approver -A user might not show as an approver on the Code Owner merge request approval rules. +A user might not show as an approver on the Code Owner merge request approval rules +if any of these conditions are true: -This result occurs when a rule prevents the specific user from approving the merge request. -Check the project -[merge request approval setting](merge_requests/approvals/settings.md#edit-merge-request-approval-settings). +- A rule prevents the specific user from approving the merge request. + Check the project [merge request approval](merge_requests/approvals/settings.md#edit-merge-request-approval-settings) settings. +- A Code Owner group has a visibility of **private**, and the current user is not a + member of the Code Owner group. diff --git a/doc/user/project/repository/index.md b/doc/user/project/repository/index.md index 7d83800659b..bcdb626d0f2 100644 --- a/doc/user/project/repository/index.md +++ b/doc/user/project/repository/index.md @@ -306,3 +306,33 @@ The same approach should also allow misidentified file types to be fixed. ``` `*.txt` files have an entry in the heuristics file. This example prevents parsing of these files. + +### Search sequence of pushes to a repository + +If it seems that a commit has gone "missing", search the sequence of pushes to a repository. +[This StackOverflow article](https://stackoverflow.com/questions/13468027/the-mystery-of-the-missing-commit-across-merges) +describes how you can end up in this state without a force push. Another cause can be a misconfigured [server hook](../../../administration/server_hooks.md) that changes a HEAD ref in a `git reset` operation. + +If you look at the output from the sample code below for the target branch, you +see a discontinuity in the from/to commits as you step through the output. +The `commit_from` of each new push should equal the `commit_to` of the previous push. +A break in that sequence indicates one or more commits have been "lost" from the repository history. + +Using the [rails console](../../../administration/operations/rails_console.md#starting-a-rails-console-session), the following example checks the last 100 pushes and prints the `commit_from` and `commit_to` entries: + +```ruby +p = Project.find_by_full_path('project/path') +p.events.pushed_action.last(100).each do |e| + puts "%-20.20s %8s...%8s (%s)", e.push_event_payload[:ref], e.push_event_payload[:commit_from], e.push_event_payload[:commit_to], e.author.try(:username) +end ; nil +``` + +Example output showing break in sequence at line 4: + +```plaintext +master f21b07713251e04575908149bdc8ac1f105aabc3...6bc56c1f46244792222f6c85b11606933af171de root +master 6bc56c1f46244792222f6c85b11606933af171de...132da6064f5d3453d445fd7cb452b148705bdc1b root +master 132da6064f5d3453d445fd7cb452b148705bdc1b...a62e1e693150a2e46ace0ce696cd4a52856dfa65 root +master 58b07b719a4b0039fec810efa52f479ba1b84756...f05321a5b5728bd8a89b7bf530aa44043c951dce root +master f05321a5b5728bd8a89b7bf530aa44043c951dce...7d02e575fd790e76a3284ee435368279a5eb3773 root +``` diff --git a/lib/bulk_imports/common/pipelines/entity_finisher.rb b/lib/bulk_imports/common/pipelines/entity_finisher.rb index 02237078ba7..5066f622d57 100644 --- a/lib/bulk_imports/common/pipelines/entity_finisher.rb +++ b/lib/bulk_imports/common/pipelines/entity_finisher.rb @@ -28,7 +28,8 @@ module BulkImports bulk_import_entity_id: context.entity.id, bulk_import_entity_type: context.entity.source_type, pipeline_class: self.class.name, - message: "Entity #{entity.status_name}" + message: "Entity #{entity.status_name}", + importer: 'gitlab_migration' ) context.portable.try(:after_import) diff --git a/lib/bulk_imports/pipeline/runner.rb b/lib/bulk_imports/pipeline/runner.rb index a60df8a2a9d..ef9575d1e96 100644 --- a/lib/bulk_imports/pipeline/runner.rb +++ b/lib/bulk_imports/pipeline/runner.rb @@ -54,7 +54,8 @@ module BulkImports skip!( 'Skipping pipeline due to failed entity', pipeline_step: step, - step_class: class_name + step_class: class_name, + importer: 'gitlab_migration' ) rescue BulkImports::NetworkError => e if e.retriable?(context.tracker) @@ -111,7 +112,9 @@ module BulkImports bulk_import_id: context.bulk_import_id, pipeline_step: step, exception_class: exception.class.to_s, - exception_message: exception.message + exception_message: exception.message, + message: "Pipeline failed", + importer: 'gitlab_migration' ) BulkImports::Failure.create(attributes) @@ -135,7 +138,8 @@ module BulkImports bulk_import_entity_id: context.entity.id, bulk_import_entity_type: context.entity.source_type, pipeline_class: pipeline, - context_extra: context.extra + context_extra: context.extra, + importer: 'gitlab_migration' } defaults diff --git a/lib/gitlab/ci/config/entry/root.rb b/lib/gitlab/ci/config/entry/root.rb index b1b42cad74c..1d7d8617c74 100644 --- a/lib/gitlab/ci/config/entry/root.rb +++ b/lib/gitlab/ci/config/entry/root.rb @@ -50,7 +50,7 @@ module Gitlab entry :variables, Entry::Variables, description: 'Environment variables that will be used.', - metadata: { allowed_value_data: %i[value description] }, + metadata: { allowed_value_data: %i[value description], allow_array_value: true }, reserved: true entry :stages, Entry::Stages, diff --git a/lib/gitlab/ci/config/entry/variable.rb b/lib/gitlab/ci/config/entry/variable.rb index 253888aadeb..54c153c8b07 100644 --- a/lib/gitlab/ci/config/entry/variable.rb +++ b/lib/gitlab/ci/config/entry/variable.rb @@ -10,6 +10,7 @@ module Gitlab class Variable < ::Gitlab::Config::Entry::Simplifiable strategy :SimpleVariable, if: -> (config) { SimpleVariable.applies_to?(config) } strategy :ComplexVariable, if: -> (config) { ComplexVariable.applies_to?(config) } + strategy :ComplexArrayVariable, if: -> (config) { ComplexArrayVariable.applies_to?(config) } class SimpleVariable < ::Gitlab::Config::Entry::Node include ::Gitlab::Config::Entry::Validatable @@ -39,7 +40,7 @@ module Gitlab class << self def applies_to?(config) - config.is_a?(Hash) + config.is_a?(Hash) && !config[:value].is_a?(Array) end end @@ -86,6 +87,34 @@ module Gitlab end end + class ComplexArrayVariable < ComplexVariable + include ::Gitlab::Config::Entry::Validatable + + class << self + def applies_to?(config) + config.is_a?(Hash) && config[:value].is_a?(Array) + end + end + + validations do + validates :config_value, array_of_strings: true, allow_nil: false, if: :config_value_defined? + + validate do + next if opt(:allow_array_value) + + errors.add(:config, 'value must be an alphanumeric string') + end + end + + def value + config_value.first + end + + def value_with_data + super.merge(value_options: config_value).compact + end + end + class UnknownStrategy < ::Gitlab::Config::Entry::Node def errors ["variable definition must be either a string or a hash"] diff --git a/lib/gitlab/ci/config/entry/variables.rb b/lib/gitlab/ci/config/entry/variables.rb index 7fa0ee00066..4430a11dda7 100644 --- a/lib/gitlab/ci/config/entry/variables.rb +++ b/lib/gitlab/ci/config/entry/variables.rb @@ -36,7 +36,7 @@ module Gitlab end def composable_metadata - { allowed_value_data: opt(:allowed_value_data) } + { allowed_value_data: opt(:allowed_value_data), allow_array_value: opt(:allow_array_value) } end end end diff --git a/lib/gitlab/graphql/pagination/keyset/connection.rb b/lib/gitlab/graphql/pagination/keyset/connection.rb index 987a5e7b74b..eca4d42fb9a 100644 --- a/lib/gitlab/graphql/pagination/keyset/connection.rb +++ b/lib/gitlab/graphql/pagination/keyset/connection.rb @@ -151,7 +151,7 @@ module Gitlab def limit_value # note: only first _or_ last can be specified, not both - @limit_value ||= [first, last, max_page_size, GitlabSchema.default_max_page_size].compact.min + @limit_value ||= [first, last, max_page_size || GitlabSchema.default_max_page_size].compact.min end def loaded?(items) diff --git a/lib/sidebars/projects/menus/infrastructure_menu.rb b/lib/sidebars/projects/menus/infrastructure_menu.rb index 63eea0ea500..2181d89262b 100644 --- a/lib/sidebars/projects/menus/infrastructure_menu.rb +++ b/lib/sidebars/projects/menus/infrastructure_menu.rb @@ -89,12 +89,12 @@ module Sidebars ::Sidebars::MenuItem.new( title: _('Google Cloud'), link: project_google_cloud_configuration_path(context.project), - active_routes: { controller: [ - :configuration, - :service_accounts, - :databases, - :deployments, - :gcp_regions + active_routes: { controller: %w[ + projects/google_cloud/configuration + projects/google_cloud/service_accounts + projects/google_cloud/databases + projects/google_cloud/deployments + projects/google_cloud/gcp_regions ] }, item_id: :google_cloud ) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index cb04770f9c5..3c11ce1031a 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -46905,9 +46905,6 @@ msgstr "" msgid "at least the Reporter role, the author, and assignees" msgstr "" -msgid "at risk" -msgstr "" - msgid "attach a new file" msgstr "" @@ -48294,9 +48291,6 @@ msgstr "" msgid "my-topic" msgstr "" -msgid "need attention" -msgstr "" - msgid "needs to be between 10 minutes and 1 month" msgstr "" @@ -48345,9 +48339,6 @@ msgstr "" msgid "nounSeries|%{item}, and %{lastItem}" msgstr "" -msgid "on track" -msgstr "" - msgid "only %{parent_types} can be parent of Task." msgstr "" diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index 9c4baeae836..2751f6a52f2 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -77,7 +77,8 @@ RSpec.describe Projects::MergeRequestsController do merge_request, 'json', diff_head: true, - view: 'inline')) + view: 'inline', + w: '0')) end context 'when diff files were cleaned' do diff --git a/spec/frontend/content_editor/components/suggestions_dropdown_spec.js b/spec/frontend/content_editor/components/suggestions_dropdown_spec.js index f25f183a013..fbf00b8dd41 100644 --- a/spec/frontend/content_editor/components/suggestions_dropdown_spec.js +++ b/spec/frontend/content_editor/components/suggestions_dropdown_spec.js @@ -1,17 +1,21 @@ import { GlAvatarLabeled, GlDropdownItem } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; +import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import SuggestionsDropdown from '~/content_editor/components/suggestions_dropdown.vue'; describe('~/content_editor/components/suggestions_dropdown', () => { let wrapper; - const buildWrapper = ({ propsData = {} } = {}) => { - wrapper = shallowMount(SuggestionsDropdown, { - propsData: { - nodeType: 'reference', - ...propsData, - }, - }); + const buildWrapper = ({ propsData } = {}) => { + wrapper = extendedWrapper( + shallowMount(SuggestionsDropdown, { + propsData: { + nodeType: 'reference', + command: jest.fn(), + ...propsData, + }, + }), + ); }; const exampleUser = { username: 'root', avatar_url: 'root_avatar.png', type: 'User' }; @@ -23,6 +27,25 @@ describe('~/content_editor/components/suggestions_dropdown', () => { description: 'Set due date', params: [''], }; + const exampleEpic = { + iid: 8884, + title: '❓ Remote Development | Solution validation', + reference: 'gitlab-org&8884', + }; + const exampleLabel = { + title: 'devops::create', + color: '#E44D2A', + type: 'GroupLabel', + textColor: '#FFFFFF', + }; + const exampleVulnerability = { + id: 60850147, + title: 'System procs network activity', + }; + const exampleSnippet = { + id: 2420859, + title: 'Project creation QueryRecorder logs', + }; const exampleEmoji = { c: 'people', e: '😃', @@ -40,13 +63,17 @@ describe('~/content_editor/components/suggestions_dropdown', () => { describe('on item select', () => { it.each` - nodeType | referenceType | char | reference | insertedText | insertedProps - ${'reference'} | ${'user'} | ${'@'} | ${exampleUser} | ${`@root`} | ${{}} - ${'reference'} | ${'issue'} | ${'#'} | ${exampleIssue} | ${`#123`} | ${{}} - ${'reference'} | ${'merge_request'} | ${'!'} | ${exampleMergeRequest} | ${`!224`} | ${{}} - ${'reference'} | ${'milestone'} | ${'%'} | ${exampleMilestone} | ${`%1.3`} | ${{}} - ${'reference'} | ${'command'} | ${'/'} | ${exampleCommand} | ${'/due '} | ${{}} - ${'emoji'} | ${'emoji'} | ${':'} | ${exampleEmoji} | ${`😃`} | ${insertedEmojiProps} + nodeType | referenceType | char | reference | insertedText | insertedProps + ${'reference'} | ${'user'} | ${'@'} | ${exampleUser} | ${`@root`} | ${{}} + ${'reference'} | ${'issue'} | ${'#'} | ${exampleIssue} | ${`#123`} | ${{}} + ${'reference'} | ${'merge_request'} | ${'!'} | ${exampleMergeRequest} | ${`!224`} | ${{}} + ${'reference'} | ${'milestone'} | ${'%'} | ${exampleMilestone} | ${`%1.3`} | ${{}} + ${'reference'} | ${'command'} | ${'/'} | ${exampleCommand} | ${'/due '} | ${{}} + ${'reference'} | ${'epic'} | ${'&'} | ${exampleEpic} | ${`gitlab-org&8884`} | ${{}} + ${'reference'} | ${'label'} | ${'~'} | ${exampleLabel} | ${`~devops::create`} | ${{}} + ${'reference'} | ${'vulnerability'} | ${'[vulnerability:'} | ${exampleVulnerability} | ${`[vulnerability:60850147]`} | ${{}} + ${'reference'} | ${'snippet'} | ${'$'} | ${exampleSnippet} | ${`$2420859`} | ${{}} + ${'emoji'} | ${'emoji'} | ${':'} | ${exampleEmoji} | ${`😃`} | ${insertedEmojiProps} `( 'runs a command to insert the selected $referenceType', ({ char, nodeType, referenceType, reference, insertedText, insertedProps }) => { @@ -80,24 +107,21 @@ describe('~/content_editor/components/suggestions_dropdown', () => { describe('rendering user references', () => { it('displays avatar labeled component', () => { - const testUser = exampleUser; buildWrapper({ propsData: { char: '@', - command: jest.fn(), - nodeType: 'reference', nodeProps: { referenceType: 'user', }, - items: [testUser], + items: [exampleUser], }, }); expect(wrapper.findComponent(GlAvatarLabeled).attributes()).toEqual( expect.objectContaining({ - label: testUser.username, + label: exampleUser.username, shape: 'circle', - src: testUser.avatar_url, + src: exampleUser.avatar_url, }), ); }); @@ -112,7 +136,6 @@ describe('~/content_editor/components/suggestions_dropdown', () => { buildWrapper({ propsData: { char, - command: jest.fn(), nodeType: 'reference', nodeProps: { referenceType, @@ -127,13 +150,68 @@ describe('~/content_editor/components/suggestions_dropdown', () => { }); }); + describe.each` + referenceType | char | reference + ${'snippet'} | ${'$'} | ${exampleSnippet} + ${'vulnerability'} | ${'[vulnerability:'} | ${exampleVulnerability} + `('rendering $referenceType references', ({ referenceType, char, reference }) => { + it(`displays ${referenceType} ID and title`, () => { + buildWrapper({ + propsData: { + char, + nodeProps: { + referenceType, + }, + items: [reference], + }, + }); + + expect(wrapper.text()).toContain(`${reference.id}`); + expect(wrapper.text()).toContain(`${reference.title}`); + }); + }); + + describe('rendering label references', () => { + it('displays label title and color', () => { + buildWrapper({ + propsData: { + char: '~', + nodeProps: { + referenceType: 'label', + }, + items: [exampleLabel], + }, + }); + + expect(wrapper.text()).toContain(`${exampleLabel.title}`); + expect(wrapper.findByTestId('label-color-box').attributes().style).toEqual( + `background-color: rgb(228, 77, 42);`, // #E44D2A + ); + }); + }); + + describe('rendering epic references', () => { + it('displays epic title and reference', () => { + buildWrapper({ + propsData: { + char: '&', + nodeProps: { + referenceType: 'epic', + }, + items: [exampleEpic], + }, + }); + + expect(wrapper.text()).toContain(`${exampleEpic.reference}`); + expect(wrapper.text()).toContain(`${exampleEpic.title}`); + }); + }); + describe('rendering a command (quick action)', () => { it('displays command name with a slash', () => { buildWrapper({ propsData: { char: '/', - command: jest.fn(), - nodeType: 'reference', nodeProps: { referenceType: 'command', }, @@ -168,7 +246,6 @@ describe('~/content_editor/components/suggestions_dropdown', () => { buildWrapper({ propsData: { char: ':', - command: jest.fn(), nodeType: 'emoji', nodeProps: {}, items: testEmojis, diff --git a/spec/frontend/diffs/store/actions_spec.js b/spec/frontend/diffs/store/actions_spec.js index 9fb00d37060..bf75f956d7f 100644 --- a/spec/frontend/diffs/store/actions_spec.js +++ b/spec/frontend/diffs/store/actions_spec.js @@ -178,7 +178,7 @@ describe('DiffsStoreActions', () => { }); describe('fetchDiffFilesMeta', () => { - const endpointMetadata = '/fetch/diffs_metadata.json?view=inline'; + const endpointMetadata = '/fetch/diffs_metadata.json?view=inline&w=0'; const noFilesData = { ...diffMetadata }; beforeEach(() => { @@ -191,7 +191,7 @@ describe('DiffsStoreActions', () => { return testAction( diffActions.fetchDiffFilesMeta, {}, - { endpointMetadata, diffViewType: 'inline' }, + { endpointMetadata, diffViewType: 'inline', showWhitespace: true }, [ { type: types.SET_LOADING, payload: true }, { type: types.SET_LOADING, payload: false }, diff --git a/spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb b/spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb index affec45dd8b..9ea519d367e 100644 --- a/spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb +++ b/spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb @@ -17,7 +17,8 @@ RSpec.describe BulkImports::Common::Pipelines::EntityFinisher do bulk_import_entity_id: entity.id, bulk_import_entity_type: entity.source_type, pipeline_class: described_class.name, - message: 'Entity finished' + message: 'Entity finished', + importer: 'gitlab_migration' ) end diff --git a/spec/lib/bulk_imports/pipeline/runner_spec.rb b/spec/lib/bulk_imports/pipeline/runner_spec.rb index 55daafd4670..a5a01354d0e 100644 --- a/spec/lib/bulk_imports/pipeline/runner_spec.rb +++ b/spec/lib/bulk_imports/pipeline/runner_spec.rb @@ -60,7 +60,9 @@ RSpec.describe BulkImports::Pipeline::Runner do pipeline_step: :extractor, pipeline_class: 'BulkImports::MyPipeline', exception_class: exception_class, - exception_message: exception_message + exception_message: exception_message, + message: "Pipeline failed", + importer: 'gitlab_migration' ) ) end @@ -89,7 +91,8 @@ RSpec.describe BulkImports::Pipeline::Runner do log_params( context, message: 'Aborting entity migration due to pipeline failure', - pipeline_class: 'BulkImports::MyPipeline' + pipeline_class: 'BulkImports::MyPipeline', + importer: 'gitlab_migration' ) ) end @@ -293,6 +296,7 @@ RSpec.describe BulkImports::Pipeline::Runner do bulk_import_id: context.bulk_import_id, bulk_import_entity_id: context.entity.id, bulk_import_entity_type: context.entity.source_type, + importer: 'gitlab_migration', context_extra: context.extra }.merge(extra) end diff --git a/spec/lib/gitlab/ci/config/entry/root_spec.rb b/spec/lib/gitlab/ci/config/entry/root_spec.rb index 64438a1594a..a55e13e7c2d 100644 --- a/spec/lib/gitlab/ci/config/entry/root_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/root_spec.rb @@ -34,7 +34,11 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do image: 'image:1.0', default: {}, services: ['postgres:9.1', 'mysql:5.5'], - variables: { VAR: 'root', VAR2: { value: 'val 2', description: 'this is var 2' } }, + variables: { + VAR: 'root', + VAR2: { value: 'val 2', description: 'this is var 2' }, + VAR3: { value: %w[val3 val3b], description: 'this is var 3' } + }, after_script: ['make clean'], stages: %w(build pages release), cache: { key: 'k', untracked: true, paths: ['public/'] }, @@ -83,7 +87,7 @@ RSpec.describe Gitlab::Ci::Config::Entry::Root do end it 'sets correct variables value' do - expect(root.variables_value).to eq('VAR' => 'root', 'VAR2' => 'val 2') + expect(root.variables_value).to eq('VAR' => 'root', 'VAR2' => 'val 2', 'VAR3' => 'val3') end describe '#leaf?' do diff --git a/spec/lib/gitlab/ci/config/entry/variable_spec.rb b/spec/lib/gitlab/ci/config/entry/variable_spec.rb index 744a89d4509..076a5b32e92 100644 --- a/spec/lib/gitlab/ci/config/entry/variable_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/variable_spec.rb @@ -127,20 +127,6 @@ RSpec.describe Gitlab::Ci::Config::Entry::Variable do end end - context 'when config value is an array' do - let(:config) { { value: ['value'], description: 'description' } } - - describe '#valid?' do - it { is_expected.not_to be_valid } - end - - describe '#errors' do - subject(:errors) { entry.errors } - - it { is_expected.to include 'var1 config value must be an alphanumeric string' } - end - end - context 'when config description is a symbol' do let(:config) { { value: 'value', description: :description } } @@ -209,4 +195,42 @@ RSpec.describe Gitlab::Ci::Config::Entry::Variable do end end end + + describe 'ComplexArrayVariable' do + context 'when allow_array_value metadata is false' do + let(:config) { { value: %w[value value2], description: 'description' } } + let(:metadata) { { allow_array_value: false } } + + describe '#valid?' do + it { is_expected.not_to be_valid } + end + + describe '#errors' do + subject(:errors) { entry.errors } + + it { is_expected.to include 'var1 config value must be an alphanumeric string' } + end + end + + context 'when allow_array_value metadata is true' do + let(:config) { { value: %w[value value2], description: 'description' } } + let(:metadata) { { allowed_value_data: %i[value description], allow_array_value: true } } + + describe '#valid?' do + it { is_expected.to be_valid } + end + + describe '#value' do + subject(:value) { entry.value } + + it { is_expected.to eq('value') } + end + + describe '#value_with_data' do + subject(:value_with_data) { entry.value_with_data } + + it { is_expected.to eq(value: 'value', description: 'description', value_options: %w[value value2]) } + end + end + end end diff --git a/spec/lib/gitlab/ci/config/entry/variables_spec.rb b/spec/lib/gitlab/ci/config/entry/variables_spec.rb index ad7290d0589..085f304094e 100644 --- a/spec/lib/gitlab/ci/config/entry/variables_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/variables_spec.rb @@ -98,6 +98,62 @@ RSpec.describe Gitlab::Ci::Config::Entry::Variables do it_behaves_like 'invalid config', /must be either a string or a hash/ end + context 'when entry config value has unallowed value key-value pair and value is a string' do + let(:config) do + { 'VARIABLE_1' => { value: 'value', description: 'variable 1' } } + end + + context 'when there is no allowed_value_data metadata' do + it_behaves_like 'invalid config', /variable_1 config must be a string/ + end + + context 'when metadata has allow_array_value and allowed_value_data' do + let(:metadata) { { allowed_value_data: %i[value description], allow_array_value: true } } + + let(:result) do + { 'VARIABLE_1' => 'value' } + end + + it_behaves_like 'valid config' + + describe '#value_with_data' do + it 'returns variable with data' do + expect(entry.value_with_data).to eq( + 'VARIABLE_1' => { value: 'value', description: 'variable 1' } + ) + end + end + end + end + + context 'when entry config value has key-value pair and value is an array' do + let(:config) do + { 'VARIABLE_1' => { value: %w[value1 value2], description: 'variable 1' } } + end + + context 'when there is no allowed_value_data metadata' do + it_behaves_like 'invalid config', /variable_1 config value must be an alphanumeric string/ + end + + context 'when metadata has allow_array_value and allowed_value_data' do + let(:metadata) { { allowed_value_data: %i[value description], allow_array_value: true } } + + let(:result) do + { 'VARIABLE_1' => 'value1' } + end + + it_behaves_like 'valid config' + + describe '#value_with_data' do + it 'returns variable with data' do + expect(entry.value_with_data).to eq( + 'VARIABLE_1' => { value: 'value1', value_options: %w[value1 value2], description: 'variable 1' } + ) + end + end + end + end + context 'when entry config value has key-value pair and hash' do let(:config) do { 'VARIABLE_1' => { value: 'value 1', description: 'variable 1' }, diff --git a/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb b/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb index bf09e98331f..1124868bdae 100644 --- a/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb +++ b/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb @@ -51,6 +51,7 @@ RSpec.describe Gitlab::Graphql::Pagination::Keyset::Connection do before do stub_feature_flags(graphql_keyset_pagination_without_next_page_query: false) + allow(GitlabSchema).to receive(:default_max_page_size).and_return(2) end it 'invokes an extra query for the next page check' do diff --git a/spec/requests/api/graphql/ci/config_variables_spec.rb b/spec/requests/api/graphql/ci/config_variables_spec.rb index 2b5a5d0dc93..17133d7ea66 100644 --- a/spec/requests/api/graphql/ci/config_variables_spec.rb +++ b/spec/requests/api/graphql/ci/config_variables_spec.rb @@ -23,6 +23,7 @@ RSpec.describe 'Query.project(fullPath).ciConfigVariables(sha)' do ciConfigVariables(sha: "#{sha}") { key value + valueOptions description } } @@ -52,14 +53,22 @@ RSpec.describe 'Query.project(fullPath).ciConfigVariables(sha)' do post_graphql(query, current_user: user) expect(graphql_data.dig('project', 'ciConfigVariables')).to contain_exactly( + { + 'key' => 'KEY_VALUE_VAR', + 'value' => 'value x', + 'valueOptions' => nil, + 'description' => 'value of KEY_VALUE_VAR' + }, { 'key' => 'DB_NAME', 'value' => 'postgres', + 'valueOptions' => nil, 'description' => nil }, { 'key' => 'ENVIRONMENT_VAR', 'value' => 'env var value', + 'valueOptions' => ['env var value', 'env var value2'], 'description' => 'env var description' } ) diff --git a/spec/services/bulk_imports/create_pipeline_trackers_service_spec.rb b/spec/services/bulk_imports/create_pipeline_trackers_service_spec.rb index c64711aa710..0de962328c5 100644 --- a/spec/services/bulk_imports/create_pipeline_trackers_service_spec.rb +++ b/spec/services/bulk_imports/create_pipeline_trackers_service_spec.rb @@ -77,6 +77,7 @@ RSpec.describe BulkImports::CreatePipelineTrackersService do message: 'Pipeline skipped as source instance version not compatible with pipeline', bulk_import_entity_id: entity.id, bulk_import_id: entity.bulk_import_id, + importer: 'gitlab_migration', pipeline_name: 'PipelineClass4', minimum_source_version: '15.1.0', maximum_source_version: nil, @@ -87,6 +88,7 @@ RSpec.describe BulkImports::CreatePipelineTrackersService do message: 'Pipeline skipped as source instance version not compatible with pipeline', bulk_import_entity_id: entity.id, bulk_import_id: entity.bulk_import_id, + importer: 'gitlab_migration', pipeline_name: 'PipelineClass5', minimum_source_version: '16.0.0', maximum_source_version: nil, diff --git a/spec/services/incident_management/issuable_escalation_statuses/prepare_update_service_spec.rb b/spec/services/incident_management/issuable_escalation_statuses/prepare_update_service_spec.rb index 761cc5c92ea..e8208c410d5 100644 --- a/spec/services/incident_management/issuable_escalation_statuses/prepare_update_service_spec.rb +++ b/spec/services/incident_management/issuable_escalation_statuses/prepare_update_service_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' -RSpec.describe IncidentManagement::IssuableEscalationStatuses::PrepareUpdateService do +RSpec.describe IncidentManagement::IssuableEscalationStatuses::PrepareUpdateService, factory_default: :keep do + let_it_be(:project) { create_default(:project) } let_it_be(:escalation_status) { create(:incident_management_issuable_escalation_status, :triggered) } let_it_be(:user_with_permissions) { create(:user) } @@ -10,7 +11,7 @@ RSpec.describe IncidentManagement::IssuableEscalationStatuses::PrepareUpdateServ let(:issue) { escalation_status.issue } let(:status) { :acknowledged } let(:params) { { status: status } } - let(:service) { IncidentManagement::IssuableEscalationStatuses::PrepareUpdateService.new(issue, current_user, params) } + let(:service) { described_class.new(issue, current_user, params) } subject(:result) { service.execute } @@ -71,9 +72,17 @@ RSpec.describe IncidentManagement::IssuableEscalationStatuses::PrepareUpdateServ end end - context 'when called without params' do + context 'when called nil params' do let(:params) { nil } + it 'raises an exception' do + expect { result }.to raise_error NoMethodError + end + end + + context 'when called without params' do + let(:params) { {} } + it_behaves_like 'successful response', {} end diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb index 251deba40c5..20b1a1f58bb 100644 --- a/spec/services/issues/update_service_spec.rb +++ b/spec/services/issues/update_service_spec.rb @@ -852,6 +852,24 @@ RSpec.describe Issues::UpdateService, :mailer do service.execute(issue) end + # At the moment of writting old associations are not necessary for update_task + # and doing this will prevent fetching associations from the DB and comparing old and new labels + it 'does not pass old_associations to the after_update method' do + params = { + update_task: { + index: 1, + checked: false, + line_source: '- [x] Task 1', + line_number: 1 + } + } + service = described_class.new(project: project, current_user: user, params: params) + + expect(service).to receive(:after_update).with(issue, {}) + + service.execute(issue) + end + it 'creates system note about task status change' do note1 = find_note('marked the checklist item **Task 1** as completed') note2 = find_note('marked the checklist item **Task 2** as completed') diff --git a/spec/services/work_items/update_service_spec.rb b/spec/services/work_items/update_service_spec.rb index 39f9fe32693..92b304a4984 100644 --- a/spec/services/work_items/update_service_spec.rb +++ b/spec/services/work_items/update_service_spec.rb @@ -108,6 +108,24 @@ RSpec.describe WorkItems::UpdateService do end end + context 'when labels are updated' do + let_it_be(:label_a) { create(:label, project: project) } + let_it_be(:label_b) { create(:label, project: project) } + let(:issuable) { work_item } + + it_behaves_like 'broadcasting issuable labels updates' do + def update_issuable(update_params) + described_class.new( + project: project, + current_user: current_user, + params: update_params, + spam_params: spam_params, + widget_params: widget_params + ).execute(work_item) + end + end + end + context 'when updating state_event' do context 'when state_event is close' do let(:opts) { { state_event: 'close' } } diff --git a/spec/support/gitlab_stubs/gitlab_ci.yml b/spec/support/gitlab_stubs/gitlab_ci.yml index b6a66cfa2c6..94523591765 100644 --- a/spec/support/gitlab_stubs/gitlab_ci.yml +++ b/spec/support/gitlab_stubs/gitlab_ci.yml @@ -7,9 +7,12 @@ before_script: - bundle exec rake db:create variables: + KEY_VALUE_VAR: + value: 'value x' + description: 'value of KEY_VALUE_VAR' DB_NAME: postgres ENVIRONMENT_VAR: - value: 'env var value' + value: ['env var value', 'env var value2'] description: 'env var description' stages: diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml index b3b2376c1a8..c4377e368ee 100644 --- a/spec/support/rspec_order_todo.yml +++ b/spec/support/rspec_order_todo.yml @@ -10008,7 +10008,6 @@ - './spec/services/incident_management/issuable_escalation_statuses/after_update_service_spec.rb' - './spec/services/incident_management/issuable_escalation_statuses/build_service_spec.rb' - './spec/services/incident_management/issuable_escalation_statuses/create_service_spec.rb' -- './spec/services/incident_management/issuable_escalation_statuses/prepare_update_service_spec.rb' - './spec/services/incident_management/pager_duty/create_incident_issue_service_spec.rb' - './spec/services/incident_management/pager_duty/process_webhook_service_spec.rb' - './spec/services/incident_management/timeline_events/create_service_spec.rb' diff --git a/spec/support/services/issuable_update_service_shared_examples.rb b/spec/support/services/issuable_update_service_shared_examples.rb index c168df7a7d2..94061b140f4 100644 --- a/spec/support/services/issuable_update_service_shared_examples.rb +++ b/spec/support/services/issuable_update_service_shared_examples.rb @@ -47,7 +47,7 @@ RSpec.shared_examples 'broadcasting issuable labels updates' do it 'triggers the GraphQL subscription' do expect(GraphqlTriggers).to receive(:issuable_labels_updated).with(issuable) - update_issuable({ add_label_ids: [label_b.id] }) + update_issuable(add_label_ids: [label_b.id]) end end @@ -55,7 +55,7 @@ RSpec.shared_examples 'broadcasting issuable labels updates' do it 'triggers the GraphQL subscription' do expect(GraphqlTriggers).to receive(:issuable_labels_updated).with(issuable) - update_issuable({ remove_label_ids: [label_a.id] }) + update_issuable(remove_label_ids: [label_a.id]) end end @@ -63,7 +63,7 @@ RSpec.shared_examples 'broadcasting issuable labels updates' do it 'does not trigger the GraphQL subscription' do expect(GraphqlTriggers).not_to receive(:issuable_labels_updated).with(issuable) - update_issuable({ label_ids: [label_a.id] }) + update_issuable(label_ids: [label_a.id]) end end end diff --git a/spec/workers/bulk_imports/entity_worker_spec.rb b/spec/workers/bulk_imports/entity_worker_spec.rb index c4a95166007..0fcdbccc304 100644 --- a/spec/workers/bulk_imports/entity_worker_spec.rb +++ b/spec/workers/bulk_imports/entity_worker_spec.rb @@ -40,7 +40,8 @@ RSpec.describe BulkImports::EntityWorker do 'bulk_import_entity_id' => entity.id, 'bulk_import_id' => entity.bulk_import_id, 'current_stage' => nil, - 'message' => 'Stage starting' + 'message' => 'Stage starting', + 'importer' => 'gitlab_migration' ) ) end @@ -70,7 +71,8 @@ RSpec.describe BulkImports::EntityWorker do hash_including( 'bulk_import_entity_id' => entity.id, 'bulk_import_id' => entity.bulk_import_id, - 'current_stage' => nil + 'current_stage' => nil, + 'importer' => 'gitlab_migration' ) ) @@ -81,14 +83,20 @@ RSpec.describe BulkImports::EntityWorker do 'bulk_import_entity_id' => entity.id, 'bulk_import_id' => entity.bulk_import_id, 'current_stage' => nil, - 'message' => 'Error!' + 'message' => 'Error!', + 'importer' => 'gitlab_migration' ) ) end expect(Gitlab::ErrorTracking) .to receive(:track_exception) - .with(exception, bulk_import_entity_id: entity.id, bulk_import_id: entity.bulk_import_id) + .with( + exception, + bulk_import_entity_id: entity.id, + bulk_import_id: entity.bulk_import_id, + importer: 'gitlab_migration' + ) subject end @@ -105,7 +113,8 @@ RSpec.describe BulkImports::EntityWorker do 'bulk_import_entity_id' => entity.id, 'bulk_import_id' => entity.bulk_import_id, 'current_stage' => 0, - 'message' => 'Stage running' + 'message' => 'Stage running', + 'importer' => 'gitlab_migration' ) ) end @@ -133,7 +142,8 @@ RSpec.describe BulkImports::EntityWorker do hash_including( 'bulk_import_entity_id' => entity.id, 'bulk_import_id' => entity.bulk_import_id, - 'current_stage' => 0 + 'current_stage' => 0, + 'importer' => 'gitlab_migration' ) ) end diff --git a/spec/workers/bulk_imports/export_request_worker_spec.rb b/spec/workers/bulk_imports/export_request_worker_spec.rb index 8d78c2ca35c..bd9fce7935c 100644 --- a/spec/workers/bulk_imports/export_request_worker_spec.rb +++ b/spec/workers/bulk_imports/export_request_worker_spec.rb @@ -45,7 +45,8 @@ RSpec.describe BulkImports::ExportRequestWorker do 'exception_message' => 'Export error', 'correlation_id_value' => anything, 'bulk_import_id' => bulk_import.id, - 'bulk_import_entity_type' => entity.source_type + 'bulk_import_entity_type' => entity.source_type, + 'importer' => 'gitlab_migration' ) ).twice @@ -104,7 +105,8 @@ RSpec.describe BulkImports::ExportRequestWorker do 'exception_message' => "undefined method `model_id' for nil:NilClass", 'correlation_id_value' => anything, 'bulk_import_id' => bulk_import.id, - 'bulk_import_entity_type' => entity.source_type + 'bulk_import_entity_type' => entity.source_type, + 'importer' => 'gitlab_migration' ) ).twice diff --git a/spec/workers/bulk_imports/pipeline_worker_spec.rb b/spec/workers/bulk_imports/pipeline_worker_spec.rb index bbc0e2e11af..ee65775f170 100644 --- a/spec/workers/bulk_imports/pipeline_worker_spec.rb +++ b/spec/workers/bulk_imports/pipeline_worker_spec.rb @@ -38,7 +38,8 @@ RSpec.describe BulkImports::PipelineWorker do hash_including( 'pipeline_name' => 'FakePipeline', 'bulk_import_entity_id' => entity.id, - 'bulk_import_id' => entity.bulk_import_id + 'bulk_import_id' => entity.bulk_import_id, + 'importer' => 'gitlab_migration' ) ) end @@ -86,7 +87,8 @@ RSpec.describe BulkImports::PipelineWorker do 'pipeline_tracker_id' => pipeline_tracker.id, 'bulk_import_entity_id' => entity.id, 'bulk_import_id' => entity.bulk_import_id, - 'message' => 'Unstarted pipeline not found' + 'message' => 'Unstarted pipeline not found', + 'importer' => 'gitlab_migration' ) ) end @@ -124,7 +126,8 @@ RSpec.describe BulkImports::PipelineWorker do 'pipeline_name' => 'FakePipeline', 'bulk_import_entity_id' => entity.id, 'bulk_import_id' => entity.bulk_import_id, - 'message' => 'Error!' + 'message' => 'Error!', + 'importer' => 'gitlab_migration' ) ) end @@ -134,8 +137,9 @@ RSpec.describe BulkImports::PipelineWorker do .with( instance_of(StandardError), bulk_import_entity_id: entity.id, - bulk_import_id: entity.bulk_import.id, - pipeline_name: pipeline_tracker.pipeline_name + bulk_import_id: entity.bulk_import_id, + pipeline_name: pipeline_tracker.pipeline_name, + importer: 'gitlab_migration' ) expect(BulkImports::EntityWorker) @@ -184,7 +188,8 @@ RSpec.describe BulkImports::PipelineWorker do 'pipeline_name' => 'FakePipeline', 'bulk_import_entity_id' => entity.id, 'bulk_import_id' => entity.bulk_import_id, - 'message' => 'Skipping pipeline due to failed entity' + 'message' => 'Skipping pipeline due to failed entity', + 'importer' => 'gitlab_migration' ) ) end @@ -231,7 +236,8 @@ RSpec.describe BulkImports::PipelineWorker do hash_including( 'pipeline_name' => 'FakePipeline', 'bulk_import_entity_id' => entity.id, - 'bulk_import_id' => entity.bulk_import_id + 'bulk_import_id' => entity.bulk_import_id, + 'importer' => 'gitlab_migration' ) ) end @@ -356,7 +362,8 @@ RSpec.describe BulkImports::PipelineWorker do 'pipeline_name' => 'NdjsonPipeline', 'bulk_import_entity_id' => entity.id, 'message' => 'Pipeline timeout', - 'bulk_import_id' => entity.bulk_import_id + 'bulk_import_id' => entity.bulk_import_id, + 'importer' => 'gitlab_migration' ) ) end @@ -384,7 +391,8 @@ RSpec.describe BulkImports::PipelineWorker do 'pipeline_name' => 'NdjsonPipeline', 'bulk_import_entity_id' => entity.id, 'message' => 'Export from source instance failed: Error!', - 'bulk_import_id' => entity.bulk_import_id + 'bulk_import_id' => entity.bulk_import_id, + 'importer' => 'gitlab_migration' ) ) end diff --git a/workhorse/go.mod b/workhorse/go.mod index fd6a6e984d3..15f1360f8a1 100644 --- a/workhorse/go.mod +++ b/workhorse/go.mod @@ -108,7 +108,7 @@ require ( golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect - golang.org/x/text v0.3.7 // indirect + golang.org/x/text v0.3.8 // indirect golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/api v0.74.0 // indirect diff --git a/workhorse/go.sum b/workhorse/go.sum index c472a1933f2..52b63ebecb1 100644 --- a/workhorse/go.sum +++ b/workhorse/go.sum @@ -1280,8 +1280,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=