Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-01-15 00:10:37 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-01-15 00:10:37 +0300
commit8f534e1e960eef1f4cfcb7c6d723840523515ffb (patch)
tree884401cb4e5db9dd9b301e57f588d17df2a92966
parentea3306a15e945e694afba62dc93b17500ffaec7f (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue55
-rw-r--r--app/assets/javascripts/projects/pipelines/charts/components/app_legacy.vue80
-rw-r--r--app/assets/javascripts/projects/pipelines/charts/index.js94
-rw-r--r--app/controllers/projects/pipelines_controller.rb18
-rw-r--r--app/graphql/mutations/merge_requests/update.rb2
-rw-r--r--app/models/diff_note.rb4
-rw-r--r--app/services/notes/create_service.rb2
-rw-r--r--app/services/notes/destroy_service.rb2
-rw-r--r--app/services/notes/update_service.rb2
-rw-r--r--app/views/projects/merge_requests/show.html.haml2
-rw-r--r--app/views/projects/pipelines/charts.html.haml13
-rw-r--r--app/views/projects/tracings/_tracing_button.html.haml2
-rw-r--r--app/views/shared/members/_invite_member.html.haml4
-rw-r--r--changelogs/unreleased/292822-track-comment-related-metrics-for-a-merge-request-2.yml5
-rw-r--r--changelogs/unreleased/296606-use-gl-badge-in-pipeline-url-component.yml5
-rw-r--r--changelogs/unreleased/jivanvl-remove-graphql-pipeline-analytics.yml5
-rw-r--r--changelogs/unreleased/tr-metric-image-delete.yml5
-rw-r--r--changelogs/unreleased/yo-gl-button-jaegar.yml5
-rw-r--r--changelogs/unreleased/yo-gl-button-members.yml5
-rw-r--r--config/feature_flags/development/graphql_pipeline_analytics.yml8
-rw-r--r--config/feature_flags/development/track_unique_wiki_page_views.yml2
-rw-r--r--config/feature_flags/development/usage_data_i_code_review_user_create_multiline_mr_comment.yml8
-rw-r--r--config/feature_flags/development/usage_data_i_code_review_user_edit_multiline_mr_comment.yml8
-rw-r--r--config/feature_flags/development/usage_data_i_code_review_user_remove_multiline_mr_comment.yml8
-rw-r--r--config/feature_flags/development/usage_data_i_testing_full_code_quality_report_total.yml8
-rw-r--r--config/feature_flags/development/wiki.yml2
-rw-r--r--config/feature_flags/development/wiki_front_matter.yml6
-rw-r--r--db/migrate/20190402150158_backport_enterprise_schema.rb4
-rw-r--r--doc/.vale/gitlab/spelling-exceptions.txt1
-rw-r--r--doc/api/issues.md23
-rw-r--r--doc/ci/runners/README.md9
-rw-r--r--doc/development/documentation/styleguide/index.md4
-rw-r--r--doc/raketasks/backup_restore.md1
-rw-r--r--doc/user/application_security/sast/analyzers.md24
-rw-r--r--doc/user/application_security/sast/index.md3
-rw-r--r--doc/user/application_security/secret_detection/index.md1
-rw-r--r--doc/user/group/index.md2
-rw-r--r--doc/user/packages/composer_repository/index.md2
-rw-r--r--doc/user/permissions.md2
-rw-r--r--doc/user/project/code_owners.md46
-rw-r--r--doc/user/project/img/optional_code_owners_sections_v13_8.pngbin0 -> 104264 bytes
-rw-r--r--doc/user/project/issues/issue_data_and_actions.md3
-rw-r--r--doc/user/project/merge_requests/getting_started.md53
-rw-r--r--doc/user/project/merge_requests/img/reviewer_approval_rules_form_v13_8.pngbin0 -> 42245 bytes
-rw-r--r--doc/user/project/merge_requests/img/reviewer_approval_rules_sidebar_v13_8.pngbin0 -> 38840 bytes
-rw-r--r--doc/user/project/requirements/index.md54
-rw-r--r--lib/backup/repositories.rb39
-rw-r--r--lib/gitlab/database/migration_helpers.rb6
-rw-r--r--lib/gitlab/diff/position.rb7
-rw-r--r--lib/gitlab/usage_data_counters/known_events/common.yml20
-rw-r--r--lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb24
-rw-r--r--locale/gitlab.pot9
-rw-r--r--spec/frontend/projects/pipelines/charts/components/app_legacy_spec.js53
-rw-r--r--spec/lib/gitlab/ci/config/entry/variables_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/position_spec.rb58
-rw-r--r--spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb43
-rw-r--r--spec/services/notes/create_service_spec.rb2
-rw-r--r--spec/services/notes/destroy_service_spec.rb2
-rw-r--r--spec/services/notes/update_service_spec.rb2
59 files changed, 512 insertions, 347 deletions
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue
index c0eff99af07..d1bac078642 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue
@@ -1,5 +1,5 @@
<script>
-import { GlLink, GlPopover, GlSprintf, GlTooltipDirective } from '@gitlab/ui';
+import { GlLink, GlPopover, GlSprintf, GlTooltipDirective, GlBadge } from '@gitlab/ui';
import { SCHEDULE_ORIGIN } from '../../constants';
export default {
@@ -7,6 +7,7 @@ export default {
GlLink,
GlPopover,
GlSprintf,
+ GlBadge,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -57,46 +58,49 @@ export default {
</gl-link>
<div class="label-container">
<gl-link v-if="isScheduled" :href="pipelineScheduleUrl" target="__blank">
- <span
+ <gl-badge
v-gl-tooltip
:title="__('This pipeline was triggered by a schedule.')"
- class="badge badge-info"
+ variant="info"
+ size="sm"
data-testid="pipeline-url-scheduled"
- >{{ __('Scheduled') }}</span
+ >{{ __('Scheduled') }}</gl-badge
>
</gl-link>
- <span
+ <gl-badge
v-if="pipeline.flags.latest"
v-gl-tooltip
:title="__('Latest pipeline for the most recent commit on this branch')"
- class="badge badge-success"
+ variant="success"
+ size="sm"
data-testid="pipeline-url-latest"
- >{{ __('latest') }}</span
+ >{{ __('latest') }}</gl-badge
>
- <span
+ <gl-badge
v-if="pipeline.flags.yaml_errors"
v-gl-tooltip
:title="pipeline.yaml_errors"
- class="badge badge-danger"
+ variant="danger"
+ size="sm"
data-testid="pipeline-url-yaml"
- >{{ __('yaml invalid') }}</span
+ >{{ __('yaml invalid') }}</gl-badge
>
- <span
+ <gl-badge
v-if="pipeline.flags.failure_reason"
v-gl-tooltip
:title="pipeline.failure_reason"
- class="badge badge-danger"
+ variant="danger"
+ size="sm"
data-testid="pipeline-url-failure"
- >{{ __('error') }}</span
+ >{{ __('error') }}</gl-badge
>
<gl-link
v-if="pipeline.flags.auto_devops"
:id="`pipeline-url-autodevops-${pipeline.id}`"
tabindex="0"
- class="badge badge-info autodevops-badge"
data-testid="pipeline-url-autodevops"
role="button"
- >{{ __('Auto DevOps') }}</gl-link
+ ><gl-badge variant="info" size="sm">{{ __('Auto DevOps') }}</gl-badge></gl-link
>
<gl-popover
:target="`pipeline-url-autodevops-${pipeline.id}`"
@@ -122,13 +126,14 @@ export default {
__('Learn more about Auto DevOps')
}}</gl-link>
</gl-popover>
- <span
+ <gl-badge
v-if="pipeline.flags.stuck"
- class="badge badge-warning"
+ variant="warning"
+ size="sm"
data-testid="pipeline-url-stuck"
- >{{ __('stuck') }}</span
+ >{{ __('stuck') }}</gl-badge
>
- <span
+ <gl-badge
v-if="pipeline.flags.detached_merge_request_pipeline"
v-gl-tooltip
:title="
@@ -136,17 +141,19 @@ export default {
'Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results.',
)
"
- class="badge badge-info"
+ variant="info"
+ size="sm"
data-testid="pipeline-url-detached"
- >{{ __('detached') }}</span
+ >{{ __('detached') }}</gl-badge
>
- <span
+ <gl-badge
v-if="isInFork"
v-gl-tooltip
:title="__('Pipeline ran in fork of project')"
- class="badge badge-info"
+ variant="info"
+ size="sm"
data-testid="pipeline-url-fork"
- >{{ __('fork') }}</span
+ >{{ __('fork') }}</gl-badge
>
</div>
</div>
diff --git a/app/assets/javascripts/projects/pipelines/charts/components/app_legacy.vue b/app/assets/javascripts/projects/pipelines/charts/components/app_legacy.vue
deleted file mode 100644
index 03e02659060..00000000000
--- a/app/assets/javascripts/projects/pipelines/charts/components/app_legacy.vue
+++ /dev/null
@@ -1,80 +0,0 @@
-<script>
-import { GlTabs, GlTab } from '@gitlab/ui';
-import PipelineCharts from './pipeline_charts.vue';
-
-export default {
- components: {
- GlTabs,
- GlTab,
- PipelineCharts,
- DeploymentFrequencyCharts: () =>
- import('ee_component/projects/pipelines/charts/components/deployment_frequency_charts.vue'),
- },
- inject: {
- shouldRenderDeploymentFrequencyCharts: {
- type: Boolean,
- default: false,
- },
- },
- props: {
- counts: {
- type: Object,
- required: true,
- },
- timesChartData: {
- type: Object,
- required: true,
- },
- lastWeekChartData: {
- type: Object,
- required: true,
- },
- lastMonthChartData: {
- type: Object,
- required: true,
- },
- lastYearChartData: {
- type: Object,
- required: true,
- },
- },
- data() {
- return {
- // this loading flag gives the echarts library just enough time
- // to ensure all DOM nodes have been mounted.
- //
- // https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1131
- loading: true,
- };
- },
- async mounted() {
- await this.$nextTick();
- this.loading = false;
- },
-};
-</script>
-<template>
- <gl-tabs v-if="shouldRenderDeploymentFrequencyCharts">
- <gl-tab :title="__('Pipelines')">
- <pipeline-charts
- :counts="counts"
- :last-week="lastWeekChartData"
- :last-month="lastMonthChartData"
- :last-year="lastYearChartData"
- :times-chart="timesChartData"
- :loading="loading"
- />
- </gl-tab>
- <gl-tab :title="__('Deployments')">
- <deployment-frequency-charts />
- </gl-tab>
- </gl-tabs>
- <pipeline-charts
- v-else
- :counts="counts"
- :last-week="lastWeekChartData"
- :last-month="lastMonthChartData"
- :last-year="lastYearChartData"
- :times-chart="timesChartData"
- />
-</template>
diff --git a/app/assets/javascripts/projects/pipelines/charts/index.js b/app/assets/javascripts/projects/pipelines/charts/index.js
index 12943e1c3c7..7e746423b6a 100644
--- a/app/assets/javascripts/projects/pipelines/charts/index.js
+++ b/app/assets/javascripts/projects/pipelines/charts/index.js
@@ -2,7 +2,6 @@ import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import { parseBoolean } from '~/lib/utils/common_utils';
-import ProjectPipelinesChartsLegacy from './components/app_legacy.vue';
import ProjectPipelinesCharts from './components/app.vue';
Vue.use(VueApollo);
@@ -12,107 +11,24 @@ const apolloProvider = new VueApollo({
});
const mountPipelineChartsApp = (el) => {
- // Not all of the values will be defined since some them will be
- // empty depending on the value of the graphql_pipeline_analytics
- // feature flag, once the rollout of the feature flag is completed
- // the undefined values will be deleted
- const {
- countsFailed,
- countsSuccess,
- countsTotal,
- countsTotalDuration,
- successRatio,
- timesChartLabels,
- timesChartValues,
- lastWeekChartLabels,
- lastWeekChartTotals,
- lastWeekChartSuccess,
- lastMonthChartLabels,
- lastMonthChartTotals,
- lastMonthChartSuccess,
- lastYearChartLabels,
- lastYearChartTotals,
- lastYearChartSuccess,
- projectPath,
- } = el.dataset;
+ const { projectPath } = el.dataset;
const shouldRenderDeploymentFrequencyCharts = parseBoolean(
el.dataset.shouldRenderDeploymentFrequencyCharts,
);
- const parseAreaChartData = (labels, totals, success) => {
- let parsedData = {};
-
- try {
- parsedData = {
- labels: JSON.parse(labels),
- totals: JSON.parse(totals),
- success: JSON.parse(success),
- };
- } catch {
- parsedData = {};
- }
-
- return parsedData;
- };
-
- if (gon?.features?.graphqlPipelineAnalytics) {
- return new Vue({
- el,
- name: 'ProjectPipelinesChartsApp',
- components: {
- ProjectPipelinesCharts,
- },
- apolloProvider,
- provide: {
- projectPath,
- shouldRenderDeploymentFrequencyCharts,
- },
- render: (createElement) => createElement(ProjectPipelinesCharts, {}),
- });
- }
-
return new Vue({
el,
- name: 'ProjectPipelinesChartsAppLegacy',
+ name: 'ProjectPipelinesChartsApp',
components: {
- ProjectPipelinesChartsLegacy,
+ ProjectPipelinesCharts,
},
+ apolloProvider,
provide: {
projectPath,
shouldRenderDeploymentFrequencyCharts,
},
- render: (createElement) =>
- createElement(ProjectPipelinesChartsLegacy, {
- props: {
- counts: {
- failed: countsFailed,
- success: countsSuccess,
- total: countsTotal,
- successRatio,
- totalDuration: countsTotalDuration,
- },
- timesChartData: {
- labels: JSON.parse(timesChartLabels),
- values: JSON.parse(timesChartValues),
- },
- lastWeekChartData: parseAreaChartData(
- lastWeekChartLabels,
- lastWeekChartTotals,
- lastWeekChartSuccess,
- ),
- lastMonthChartData: parseAreaChartData(
- lastMonthChartLabels,
- lastMonthChartTotals,
- lastMonthChartSuccess,
- ),
- lastYearChartData: parseAreaChartData(
- lastYearChartLabels,
- lastYearChartTotals,
- lastYearChartSuccess,
- ),
- },
- }),
+ render: (createElement) => createElement(ProjectPipelinesCharts, {}),
});
};
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index 832f850121e..e44c00e501e 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -17,7 +17,6 @@ class Projects::PipelinesController < Projects::ApplicationController
push_frontend_feature_flag(:new_pipeline_form, project, default_enabled: true)
push_frontend_feature_flag(:graphql_pipeline_header, project, type: :development, default_enabled: false)
push_frontend_feature_flag(:graphql_pipeline_details, project, type: :development, default_enabled: false)
- push_frontend_feature_flag(:graphql_pipeline_analytics, project, type: :development)
push_frontend_feature_flag(:new_pipeline_form_prefilled_vars, project, type: :development, default_enabled: true)
end
before_action :ensure_pipeline, only: [:show]
@@ -189,23 +188,6 @@ class Projects::PipelinesController < Projects::ApplicationController
end
end
- def charts
- @charts = {}
- @counts = {}
-
- return if Feature.enabled?(:graphql_pipeline_analytics)
-
- @charts[:week] = Gitlab::Ci::Charts::WeekChart.new(project)
- @charts[:month] = Gitlab::Ci::Charts::MonthChart.new(project)
- @charts[:year] = Gitlab::Ci::Charts::YearChart.new(project)
- @charts[:pipeline_times] = Gitlab::Ci::Charts::PipelineTime.new(project)
-
- @counts[:total] = @project.all_pipelines.count(:all)
- @counts[:success] = @project.all_pipelines.success.count(:all)
- @counts[:failed] = @project.all_pipelines.failed.count(:all)
- @counts[:total_duration] = @project.all_pipelines.total_duration
- end
-
def test_report
respond_to do |format|
format.html do
diff --git a/app/graphql/mutations/merge_requests/update.rb b/app/graphql/mutations/merge_requests/update.rb
index b583fdfca9b..4721ebab41b 100644
--- a/app/graphql/mutations/merge_requests/update.rb
+++ b/app/graphql/mutations/merge_requests/update.rb
@@ -20,7 +20,7 @@ module Mutations
description: copy_field_description(Types::MergeRequestType, :description)
def resolve(args)
- merge_request = authorized_find!(args.slice(:project_path, :iid))
+ merge_request = authorized_find!(**args.slice(:project_path, :iid))
attributes = args.slice(:title, :description, :target_branch).compact
::MergeRequests::UpdateService
diff --git a/app/models/diff_note.rb b/app/models/diff_note.rb
index 944a64f5419..c8a0773cc5b 100644
--- a/app/models/diff_note.rb
+++ b/app/models/diff_note.rb
@@ -111,6 +111,10 @@ class DiffNote < Note
super.merge(suggestions_filter_enabled: true)
end
+ def multiline?
+ position&.multiline?
+ end
+
private
def enqueue_diff_file_creation_job
diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb
index 00a7788794e..04b7fba207b 100644
--- a/app/services/notes/create_service.rb
+++ b/app/services/notes/create_service.rb
@@ -122,7 +122,7 @@ module Notes
end
def track_note_creation_usage_for_merge_requests(note)
- Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter.track_create_comment_action(user: note.author)
+ Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter.track_create_comment_action(note: note)
end
end
end
diff --git a/app/services/notes/destroy_service.rb b/app/services/notes/destroy_service.rb
index 1f90205aacb..85f54a39add 100644
--- a/app/services/notes/destroy_service.rb
+++ b/app/services/notes/destroy_service.rb
@@ -19,7 +19,7 @@ module Notes
end
def track_note_removal_usage_for_merge_requests(note)
- Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter.track_remove_comment_action(user: note.author)
+ Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter.track_remove_comment_action(note: note)
end
end
end
diff --git a/app/services/notes/update_service.rb b/app/services/notes/update_service.rb
index 53b1a72d462..857ffbb6965 100644
--- a/app/services/notes/update_service.rb
+++ b/app/services/notes/update_service.rb
@@ -98,7 +98,7 @@ module Notes
end
def track_note_edit_usage_for_merge_requests(note)
- Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter.track_edit_comment_action(user: note.author)
+ Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter.track_edit_comment_action(note: note)
end
end
end
diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml
index c70fc624dde..164393ea79a 100644
--- a/app/views/projects/merge_requests/show.html.haml
+++ b/app/views/projects/merge_requests/show.html.haml
@@ -57,6 +57,8 @@
= render "projects/merge_requests/awards_block"
- if mr_action === "show"
- add_page_startup_api_call discussions_path(@merge_request)
+ - add_page_startup_api_call widget_project_json_merge_request_path(@project, @merge_request, format: :json)
+ - add_page_startup_api_call cached_widget_project_json_merge_request_path(@project, @merge_request, format: :json)
#js-vue-mr-discussions{ data: { notes_data: notes_data(@merge_request).to_json,
noteable_data: serialize_issuable(@merge_request, serializer: 'noteable'),
noteable_type: 'MergeRequest',
diff --git a/app/views/projects/pipelines/charts.html.haml b/app/views/projects/pipelines/charts.html.haml
index 711928c963b..ff728ab2fb3 100644
--- a/app/views/projects/pipelines/charts.html.haml
+++ b/app/views/projects/pipelines/charts.html.haml
@@ -1,13 +1,4 @@
- page_title _('CI / CD Analytics')
-- if Feature.enabled?(:graphql_pipeline_analytics)
- #js-project-pipelines-charts-app{ data: { project_path: @project.full_path,
- should_render_deployment_frequency_charts: should_render_deployment_frequency_charts.to_s } }
-- else
- #js-project-pipelines-charts-app{ data: { counts: @counts, success_ratio: success_ratio(@counts),
- times_chart: { labels: @charts[:pipeline_times].labels, values: @charts[:pipeline_times].pipeline_times },
- last_week_chart: { labels: @charts[:week].labels, totals: @charts[:week].total, success: @charts[:week].success },
- last_month_chart: { labels: @charts[:month].labels, totals: @charts[:month].total, success: @charts[:month].success },
- last_year_chart: { labels: @charts[:year].labels, totals: @charts[:year].total, success: @charts[:year].success },
- project_path: @project.full_path,
- should_render_deployment_frequency_charts: should_render_deployment_frequency_charts.to_s } }
+#js-project-pipelines-charts-app{ data: { project_path: @project.full_path,
+ should_render_deployment_frequency_charts: should_render_deployment_frequency_charts.to_s } }
diff --git a/app/views/projects/tracings/_tracing_button.html.haml b/app/views/projects/tracings/_tracing_button.html.haml
index c9a6afd3761..b0ab6fa21e1 100644
--- a/app/views/projects/tracings/_tracing_button.html.haml
+++ b/app/views/projects/tracings/_tracing_button.html.haml
@@ -1,2 +1,2 @@
-= link_to project_settings_operations_path(@project), title: _('Configure Tracing'), class: 'btn btn-success' do
+= link_to project_settings_operations_path(@project), title: _('Configure Tracing'), class: 'gl-button btn btn-success' do
= _('Add Jaeger URL')
diff --git a/app/views/shared/members/_invite_member.html.haml b/app/views/shared/members/_invite_member.html.haml
index 59b0600e2dd..0302b2fc3cf 100644
--- a/app/views/shared/members/_invite_member.html.haml
+++ b/app/views/shared/members/_invite_member.html.haml
@@ -23,6 +23,6 @@
.clearable-input
= text_field_tag :expires_at, nil, class: 'form-control js-access-expiration-date', placeholder: 'Expiration date'
= sprite_icon('close', size: 16, css_class: 'clear-icon js-clear-input gl-text-gray-200')
- = submit_tag _("Invite"), class: "btn btn-success", data: { qa_selector: 'invite_member_button' }
+ = submit_tag _("Invite"), class: "gl-button btn btn-success", data: { qa_selector: 'invite_member_button' }
- if can_import_members
- = link_to _("Import"), import_path, class: "btn btn-default", title: _("Import members from another project")
+ = link_to _("Import"), import_path, class: "gl-button btn btn-default", title: _("Import members from another project")
diff --git a/changelogs/unreleased/292822-track-comment-related-metrics-for-a-merge-request-2.yml b/changelogs/unreleased/292822-track-comment-related-metrics-for-a-merge-request-2.yml
new file mode 100644
index 00000000000..91d50ba2ac6
--- /dev/null
+++ b/changelogs/unreleased/292822-track-comment-related-metrics-for-a-merge-request-2.yml
@@ -0,0 +1,5 @@
+---
+title: Add metrics to creating, editing or removing multiline comments on merge requests
+merge_request: 51098
+author:
+type: other
diff --git a/changelogs/unreleased/296606-use-gl-badge-in-pipeline-url-component.yml b/changelogs/unreleased/296606-use-gl-badge-in-pipeline-url-component.yml
new file mode 100644
index 00000000000..bae97d7a576
--- /dev/null
+++ b/changelogs/unreleased/296606-use-gl-badge-in-pipeline-url-component.yml
@@ -0,0 +1,5 @@
+---
+title: Use GlBadge for badges in pipeline_url.vue
+merge_request: 51058
+author: Kev @KevSlashNull
+type: changed
diff --git a/changelogs/unreleased/jivanvl-remove-graphql-pipeline-analytics.yml b/changelogs/unreleased/jivanvl-remove-graphql-pipeline-analytics.yml
new file mode 100644
index 00000000000..ca3efa64a5e
--- /dev/null
+++ b/changelogs/unreleased/jivanvl-remove-graphql-pipeline-analytics.yml
@@ -0,0 +1,5 @@
+---
+title: Update pipeline graphs on CI/CD Analytics page to use GraphQL endpoint
+merge_request: 51504
+author:
+type: changed
diff --git a/changelogs/unreleased/tr-metric-image-delete.yml b/changelogs/unreleased/tr-metric-image-delete.yml
new file mode 100644
index 00000000000..a10625297ff
--- /dev/null
+++ b/changelogs/unreleased/tr-metric-image-delete.yml
@@ -0,0 +1,5 @@
+---
+title: Add delete metric image REST API endpoint
+merge_request: 50043
+author:
+type: added
diff --git a/changelogs/unreleased/yo-gl-button-jaegar.yml b/changelogs/unreleased/yo-gl-button-jaegar.yml
new file mode 100644
index 00000000000..4b82ec7953c
--- /dev/null
+++ b/changelogs/unreleased/yo-gl-button-jaegar.yml
@@ -0,0 +1,5 @@
+---
+title: Add gl-button to Add Jaeger URL
+merge_request: 51553
+author: Yogi (@yo)
+type: other
diff --git a/changelogs/unreleased/yo-gl-button-members.yml b/changelogs/unreleased/yo-gl-button-members.yml
new file mode 100644
index 00000000000..5d67ad6b11f
--- /dev/null
+++ b/changelogs/unreleased/yo-gl-button-members.yml
@@ -0,0 +1,5 @@
+---
+title: Update to new GitLab UI button in members invite page
+merge_request: 51300
+author: Yogi (@yo)
+type: other
diff --git a/config/feature_flags/development/graphql_pipeline_analytics.yml b/config/feature_flags/development/graphql_pipeline_analytics.yml
deleted file mode 100644
index f91475fcbd7..00000000000
--- a/config/feature_flags/development/graphql_pipeline_analytics.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: graphql_pipeline_analytics
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48267
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/290153
-milestone: '13.7'
-type: development
-group: group::continuos integration
-default_enabled: false
diff --git a/config/feature_flags/development/track_unique_wiki_page_views.yml b/config/feature_flags/development/track_unique_wiki_page_views.yml
index eb2bf1304d9..39d25352e73 100644
--- a/config/feature_flags/development/track_unique_wiki_page_views.yml
+++ b/config/feature_flags/development/track_unique_wiki_page_views.yml
@@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44622
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/267162
milestone: '13.5'
type: development
-group: group::knowledge
+group: group::editor
default_enabled: true
diff --git a/config/feature_flags/development/usage_data_i_code_review_user_create_multiline_mr_comment.yml b/config/feature_flags/development/usage_data_i_code_review_user_create_multiline_mr_comment.yml
new file mode 100644
index 00000000000..4777926d4b1
--- /dev/null
+++ b/config/feature_flags/development/usage_data_i_code_review_user_create_multiline_mr_comment.yml
@@ -0,0 +1,8 @@
+---
+name: usage_data_i_code_review_user_create_multiline_mr_comment
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51098
+rollout_issue_url:
+milestone: '13.8'
+type: development
+group: group::code review
+default_enabled: true
diff --git a/config/feature_flags/development/usage_data_i_code_review_user_edit_multiline_mr_comment.yml b/config/feature_flags/development/usage_data_i_code_review_user_edit_multiline_mr_comment.yml
new file mode 100644
index 00000000000..b4b34b4e166
--- /dev/null
+++ b/config/feature_flags/development/usage_data_i_code_review_user_edit_multiline_mr_comment.yml
@@ -0,0 +1,8 @@
+---
+name: usage_data_i_code_review_user_edit_multiline_mr_comment
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51098
+rollout_issue_url:
+milestone: '13.8'
+type: development
+group: group::code review
+default_enabled: true
diff --git a/config/feature_flags/development/usage_data_i_code_review_user_remove_multiline_mr_comment.yml b/config/feature_flags/development/usage_data_i_code_review_user_remove_multiline_mr_comment.yml
new file mode 100644
index 00000000000..b8ec5984788
--- /dev/null
+++ b/config/feature_flags/development/usage_data_i_code_review_user_remove_multiline_mr_comment.yml
@@ -0,0 +1,8 @@
+---
+name: usage_data_i_code_review_user_remove_multiline_mr_comment
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51098
+rollout_issue_url:
+milestone: '13.8'
+type: development
+group: group::code review
+default_enabled: true
diff --git a/config/feature_flags/development/usage_data_i_testing_full_code_quality_report_total.yml b/config/feature_flags/development/usage_data_i_testing_full_code_quality_report_total.yml
new file mode 100644
index 00000000000..38bce2529dd
--- /dev/null
+++ b/config/feature_flags/development/usage_data_i_testing_full_code_quality_report_total.yml
@@ -0,0 +1,8 @@
+---
+name: usage_data_i_testing_full_code_quality_report_total
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49079
+rollout_issue_url:
+milestone: '13.8'
+type: development
+group: group::testing
+default_enabled: true
diff --git a/config/feature_flags/development/wiki.yml b/config/feature_flags/development/wiki.yml
index 5904e6838f3..008852d2c13 100644
--- a/config/feature_flags/development/wiki.yml
+++ b/config/feature_flags/development/wiki.yml
@@ -4,5 +4,5 @@ introduced_by_url:
rollout_issue_url:
milestone:
type: development
-group:
+group: group::editor
default_enabled: true
diff --git a/config/feature_flags/development/wiki_front_matter.yml b/config/feature_flags/development/wiki_front_matter.yml
index 66add349c44..39196440d17 100644
--- a/config/feature_flags/development/wiki_front_matter.yml
+++ b/config/feature_flags/development/wiki_front_matter.yml
@@ -1,8 +1,8 @@
---
name: wiki_front_matter
-introduced_by_url:
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27706
rollout_issue_url:
-milestone:
+milestone: '12.10'
type: development
-group:
+group: group::editor
default_enabled: false
diff --git a/db/migrate/20190402150158_backport_enterprise_schema.rb b/db/migrate/20190402150158_backport_enterprise_schema.rb
index e7c415efdf2..c4fbb4b2ab9 100644
--- a/db/migrate/20190402150158_backport_enterprise_schema.rb
+++ b/db/migrate/20190402150158_backport_enterprise_schema.rb
@@ -226,10 +226,10 @@ class BackportEnterpriseSchema < ActiveRecord::Migration[5.0]
end
end
- def create_table_if_not_exists(name, *args, &block)
+ def create_table_if_not_exists(name, **args, &block)
return if table_exists?(name)
- create_table(name, *args, &block)
+ create_table(name, **args, &block)
end
def add_concurrent_foreign_key(source, target, column:, on_delete: nil, name: nil)
diff --git a/doc/.vale/gitlab/spelling-exceptions.txt b/doc/.vale/gitlab/spelling-exceptions.txt
index 3d8e9b1ef72..777faaa324a 100644
--- a/doc/.vale/gitlab/spelling-exceptions.txt
+++ b/doc/.vale/gitlab/spelling-exceptions.txt
@@ -94,6 +94,7 @@ crosslinking
crosslinks
Crossplane
CrowdIn
+CSV
Dangerfile
datetime
Debian
diff --git a/doc/api/issues.md b/doc/api/issues.md
index 3e23460740d..1abb4fe3b4a 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -2211,3 +2211,26 @@ Example response:
}
]
```
+
+## Delete metric image
+
+Available only for Incident issues.
+
+```plaintext
+DELETE /projects/:id/issues/:issue_iid/metric_images/:image_id
+```
+
+| Attribute | Type | Required | Description |
+|-------------|---------|----------|--------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
+| `issue_iid` | integer | yes | The internal ID of a project's issue |
+| `image_id` | integer | yes | The ID of the image |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" --request DELETE "https://gitlab.example.com/api/v4/projects/5/issues/93/metric_images/1"
+```
+
+Can return the following status codes:
+
+- `204 No Content`, if the image was deleted successfully.
+- `400 Bad Request`, if the image could not be deleted.
diff --git a/doc/ci/runners/README.md b/doc/ci/runners/README.md
index 5e9f5476ac1..d6ea4d83825 100644
--- a/doc/ci/runners/README.md
+++ b/doc/ci/runners/README.md
@@ -269,6 +269,15 @@ by a project that has jobs with a long timeout (for example, one week).
When not configured, runners do not override the project timeout.
+On GitLab.com, you cannot override the job timeout for shared runners and must use the [project defined timeout](../pipelines/settings.md#timeout).
+
+To set the maximum job timeout:
+
+1. In a project, go to **Settings > CI/CD > Runners**.
+1. Select your specific runner to edit the settings.
+1. Enter a value under **Maximum job timeout**.
+1. Select **Save changes**.
+
How this feature works:
**Example 1 - Runner timeout bigger than project timeout**
diff --git a/doc/development/documentation/styleguide/index.md b/doc/development/documentation/styleguide/index.md
index baa85a78db6..bba94c7de7e 100644
--- a/doc/development/documentation/styleguide/index.md
+++ b/doc/development/documentation/styleguide/index.md
@@ -529,11 +529,11 @@ You can use these fake tokens as examples:
| Usage | Guidance |
|-----------------------|----------|
| above | Try to avoid extra words when referring to an example or table in a documentation page, but if required, use **previously** instead. |
-| admin, admin area | Use **administration**, **administrator**, **administer**, or **Admin Area** instead. |
+| admin, admin area | Use **administration**, **administrator**, **administer**, or **Admin Area** instead. ([Vale](../testing.md#vale) rule: [`Admin.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/Admin.yml)) |
| allow, enable | Try to avoid, unless you are talking about security-related features. For example, instead of "This feature allows you to create a pipeline," use "Use this feature to create a pipeline." This phrasing is more active and is from the user perspective, rather than the person who implemented the feature. [View details](https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/a/allow-allows). |
| and/or | Use **or** instead, or another sensible construction. |
| below | Try to avoid extra words when referring to an example or table in a documentation page, but if required, use **following** instead. |
-| currently | Do not use when talking about the product or its features. The documentation describes the product as it is today. |
+| currently | Do not use when talking about the product or its features. The documentation describes the product as it is today. ([Vale](../testing.md#vale) rule: [`CurrentStatus.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/CurrentStatus.yml)) |
| easily | Do not use. If the user doesn't find the process to be these things, we lose their trust. |
| e.g. | Do not use Latin abbreviations. Use **for example**, **such as**, **for instance**, or **like** instead. ([Vale](../testing.md#vale) rule: [`LatinTerms.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/LatinTerms.yml)) |
| future tense | When possible, use present tense instead. For example, use `after you execute this command, GitLab displays the result` instead of `after you execute this command, GitLab will display the result`. ([Vale](../testing.md#vale) rule: [`FutureTense.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/FutureTense.yml)) |
diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md
index 53c29f46bfa..8a01975f771 100644
--- a/doc/raketasks/backup_restore.md
+++ b/doc/raketasks/backup_restore.md
@@ -61,6 +61,7 @@ including:
- Container Registry images
- GitLab Pages content
- Snippets
+- Group wikis **(PREMIUM)**
WARNING:
GitLab does not back up any configuration files, SSL certificates, or system
diff --git a/doc/user/application_security/sast/analyzers.md b/doc/user/application_security/sast/analyzers.md
index 15412473ab1..1f0b461c91b 100644
--- a/doc/user/application_security/sast/analyzers.md
+++ b/doc/user/application_security/sast/analyzers.md
@@ -68,6 +68,10 @@ the official analyzers.
### Selecting specific analyzers
+WARNING:
+`SAST_DEFAULT_ANALYZERS` is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50872) in GitLab 13.8,
+and is scheduled for [removal in GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/290777).
+
You can select the official analyzers you want to run. Here's how to enable
`bandit` and `flawfinder` while disabling all the other default ones.
In `.gitlab-ci.yml` define:
@@ -83,9 +87,9 @@ variables:
`bandit` runs first. When merging the reports, SAST
removes the duplicates and keeps the `bandit` entries.
-### Disabling default analyzers
+### Disabling all default analyzers
-Setting `SAST_DEFAULT_ANALYZERS` to an empty string disables all the official
+Setting `SAST_DISABLED` to `true` disables all the official
default analyzers. In `.gitlab-ci.yml` define:
```yaml
@@ -93,11 +97,25 @@ include:
- template: Security/SAST.gitlab-ci.yml
variables:
- SAST_DEFAULT_ANALYZERS: ""
+ SAST_DISABLED: true
```
That's needed when one totally relies on [custom analyzers](#custom-analyzers).
+### Disabling specific default analyzers
+
+Set `SAST_EXCLUDED_ANALYZERS` to a comma-delimited string that includes the official
+default analyzers that you want to avoid running. In `.gitlab-ci.yml` define the
+following to prevent the `eslint` analyzer from running:
+
+```yaml
+include:
+ - template: Security/SAST.gitlab-ci.yml
+
+variables:
+ SAST_EXCLUDED_ANALYZERS: "eslint"
+```
+
## Custom Analyzers
You can provide your own analyzers by
diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md
index 49f04251c44..59887c95c67 100644
--- a/doc/user/application_security/sast/index.md
+++ b/doc/user/application_security/sast/index.md
@@ -431,7 +431,8 @@ The following are Docker image-related variables.
|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------|
| `SECURE_ANALYZERS_PREFIX` | Override the name of the Docker registry providing the default images (proxy). Read more about [customizing analyzers](analyzers.md). |
| `SAST_ANALYZER_IMAGE_TAG` | **DEPRECATED:** Override the Docker tag of the default images. Read more about [customizing analyzers](analyzers.md). |
-| `SAST_DEFAULT_ANALYZERS` | Override the names of default images. Read more about [customizing analyzers](analyzers.md). |
+| `SAST_DEFAULT_ANALYZERS` | **DEPRECATED:** Override the names of default images. Scheduled for [removal in GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/290777). |
+| `SAST_EXCLUDED_ANALYZERS` | Names of default images that should never run. Read more about [customizing analyzers](analyzers.md). |
#### Vulnerability filters
diff --git a/doc/user/application_security/secret_detection/index.md b/doc/user/application_security/secret_detection/index.md
index 8f57e2c5535..0ae038924ec 100644
--- a/doc/user/application_security/secret_detection/index.md
+++ b/doc/user/application_security/secret_detection/index.md
@@ -53,6 +53,7 @@ The [default ruleset provided by Gitleaks](https://gitlab.com/gitlab-org/securit
- Twitter API
- Cloud SaaS vendors:
- GitHub API
+ - Shopify API
- Slack Token
- Slack Webhook
- Stripe API
diff --git a/doc/user/group/index.md b/doc/user/group/index.md
index 74406d3e5cf..069dea40ba5 100644
--- a/doc/user/group/index.md
+++ b/doc/user/group/index.md
@@ -460,7 +460,7 @@ and above.
There are a few limitations compared to project wikis:
- Git LFS is not supported.
-- Group wikis are not included in global search, group exports, backups, and Geo replication.
+- Group wikis are not included in global search, group exports, and Geo replication.
- Changes to group wikis don't show up in the group's activity feed.
- Group wikis [can't be moved](../../api/project_repository_storage_moves.md#limitations) using the project
repository moves API.
diff --git a/doc/user/packages/composer_repository/index.md b/doc/user/packages/composer_repository/index.md
index 5e60f919efd..6159ea395fa 100644
--- a/doc/user/packages/composer_repository/index.md
+++ b/doc/user/packages/composer_repository/index.md
@@ -272,6 +272,6 @@ Output indicates that the package has been successfully installed.
WARNING:
Never commit the `auth.json` file to your repository. To install packages from a CI/CD job,
-consider using the [`composer config`](https://getcomposer.org/doc/articles/handling-private-packages-with-satis.md#authentication) tool with your personal access token
+consider using the [`composer config`](https://getcomposer.org/doc/articles/handling-private-packages.md#satis) tool with your personal access token
stored in a [GitLab CI/CD environment variable](../../../ci/variables/README.md) or in
[HashiCorp Vault](../../../ci/secrets/index.md).
diff --git a/doc/user/permissions.md b/doc/user/permissions.md
index 816b0e5ab82..3dbae78ccc4 100644
--- a/doc/user/permissions.md
+++ b/doc/user/permissions.md
@@ -95,7 +95,7 @@ The following table depicts the various user permission levels in a project.
| View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ |
| Archive/reopen requirements **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
| Create/edit requirements **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| Import requirements **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
+| Import/export requirements **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
| Create new [test case](../ci/test_cases/index.md) | | ✓ | ✓ | ✓ | ✓ |
| Archive [test case](../ci/test_cases/index.md) | | ✓ | ✓ | ✓ | ✓ |
| Move [test case](../ci/test_cases/index.md) | | ✓ | ✓ | ✓ | ✓ |
diff --git a/doc/user/project/code_owners.md b/doc/user/project/code_owners.md
index d0e89400d88..63ea84e42c9 100644
--- a/doc/user/project/code_owners.md
+++ b/doc/user/project/code_owners.md
@@ -225,6 +225,52 @@ the rules for "Groups" and "Documentation" sections:
![MR widget - Sectional Code Owners](img/sectional_code_owners_v13.2.png)
+#### Optional Code Owners Sections **(PREMIUM)**
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/232995) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.8 behind a feature flag, enabled by default.
+
+When you want to make a certain section optional, you can do so by adding a code owners section prepended with the caret `^` character. Approvals from owners listed in the section will **not** be required. For example:
+
+```plaintext
+[Documentation]
+*.md @root
+
+[Ruby]
+*.rb @root
+
+^[Go]
+*.go @root
+```
+
+The optional code owners section will be displayed in merge requests under the **Approval Rules** area:
+
+![MR widget - Optional Code Owners Sections](img/optional_code_owners_sections_v13_8.png)
+
+If a section is duplicated in the file, and one of them is marked as optional and the other isn't, the requirement prevails.
+
+For example, the code owners of the "Documentation" section below will still be required to approve merge requests:
+
+```plaintext
+[Documentation]
+*.md @root
+
+[Ruby]
+*.rb @root
+
+^[Go]
+*.go @root
+
+^[Documentation]
+*.txt @root
+```
+
+Optional sections in the code owners file are currently treated as optional only
+when changes are submitted via merge requests. If a change is submitted directly
+to the protected branch, approval from code owners will still be required, even if the
+section is marked as optional. We plan to change this in a
+[future release](https://gitlab.com/gitlab-org/gitlab/-/issues/297638),
+where direct pushes to the protected branch will be allowed for sections marked as optional.
+
## Example `CODEOWNERS` file
```plaintext
diff --git a/doc/user/project/img/optional_code_owners_sections_v13_8.png b/doc/user/project/img/optional_code_owners_sections_v13_8.png
new file mode 100644
index 00000000000..7a5a2fab6e3
--- /dev/null
+++ b/doc/user/project/img/optional_code_owners_sections_v13_8.png
Binary files differ
diff --git a/doc/user/project/issues/issue_data_and_actions.md b/doc/user/project/issues/issue_data_and_actions.md
index 875ea352f99..4c8630581f5 100644
--- a/doc/user/project/issues/issue_data_and_actions.md
+++ b/doc/user/project/issues/issue_data_and_actions.md
@@ -179,7 +179,8 @@ for the issue. Notifications are automatically enabled after you participate in
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18816) in GitLab 13.8.
-Guest users can see a button to copy the email address for the issue. Sending an email to this address creates a comment containing the email body.
+Guest users can see a button in the right sidebar to copy the email address for the issue.
+Sending an email to this address creates a comment containing the email body.
### Edit
diff --git a/doc/user/project/merge_requests/getting_started.md b/doc/user/project/merge_requests/getting_started.md
index 467b58d0b5b..bc718ae867f 100644
--- a/doc/user/project/merge_requests/getting_started.md
+++ b/doc/user/project/merge_requests/getting_started.md
@@ -62,7 +62,7 @@ request's page at the top-right side:
- Enable the [squash commits when merge request is accepted](squash_and_merge.md) option to combine all the commits into one before merging, thus keep a clean commit history in your repository.
- Set the merge request as a [**Draft**](work_in_progress_merge_requests.md) to avoid accidental merges before it is ready.
-Once you have created the merge request, you can also:
+After you have created the merge request, you can also:
- [Discuss](../../discussions/index.md) your implementation with your team in the merge request thread.
- [Perform inline code reviews](reviewing_and_managing_merge_requests.md#perform-inline-code-reviews).
@@ -70,7 +70,7 @@ Once you have created the merge request, you can also:
- Preview continuous integration [pipelines on the merge request widget](reviewing_and_managing_merge_requests.md#pipeline-status-in-merge-requests-widgets).
- Preview how your changes look directly on your deployed application with [Review Apps](reviewing_and_managing_merge_requests.md#live-preview-with-review-apps).
- [Allow collaboration on merge requests across forks](allow_collaboration.md).
-- Perform a [Review](../../discussions/index.md#merge-request-reviews) in order to create multiple comments on a diff and publish them once you're ready.
+- Perform a [Review](../../discussions/index.md#merge-request-reviews) to create multiple comments on a diff and publish them when you're ready.
- Add [code suggestions](../../discussions/index.md#suggest-changes) to change the content of merge requests directly into merge request threads, and easily apply them to the codebase directly from the UI.
- Add a time estimation and the time spent with that merge request with [Time Tracking](../time_tracking.md#time-tracking).
@@ -161,6 +161,53 @@ Feature.disable(:merge_request_reviewers)
Feature.disable(:merge_request_reviewers, Project.find(<project id>))
```
+#### Reviewer approval rules
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233736) in GitLab 13.8.
+> - It was [deployed behind a feature flag](../../../user/feature_flags.md), disabled by default.
+> - [Became enabled by default](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51183) in GitLab 13.8.
+> - It's enabled on GitLab.com.
+> - It's recommended for production use.
+> - It can be enabled or disabled for a single project.
+> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-reviewer-approval-rules). **(CORE ONLY)**
+
+When editing the **Reviewers** field in a new or existing merge request, this feature
+displays the name of the matching [approval rule](merge_request_approvals.md#approval-rules)
+below the name of each suggested reviewer. [Code Owners](../code_owners.md) are displayed as `Codeowner` without group detail. We intend to iterate on this feature in future releases.
+
+This example shows reviewers and approval rules when creating a new merge request:
+
+![Reviewer approval rules in new/edit form](img/reviewer_approval_rules_form_v13_8.png)
+
+This example shows reviewers and approval rules in a merge request sidebar:
+
+![Reviewer approval rules in sidebar](img/reviewer_approval_rules_sidebar_v13_8.png)
+
+##### Enable or disable Reviewer Approval Rules **(CORE ONLY)**
+
+Merge Request Reviewers is under development and ready for production use.
+It is deployed behind a feature flag that is **enabled by default**.
+[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
+can opt to disable it.
+
+To enable it:
+
+```ruby
+# For the instance
+Feature.enable(:reviewer_approval_rules)
+# For a single project
+Feature.enable(:reviewer_approval_rules, Project.find(<project id>))
+```
+
+To disable it:
+
+```ruby
+# For the instance
+Feature.disable(:reviewer_approval_rules)
+# For a single project
+Feature.disable(:reviewer_approval_rules, Project.find(<project id>))
+```
+
### Merge requests to close issues
If the merge request is being created to resolve an issue, you can
@@ -200,5 +247,5 @@ is set for deletion, the merge request widget displays the
at once. By doing so, you save pipeline minutes.
- Delete feature branches on merge or after merging them to keep your repository clean.
- Take one thing at a time and ship the smallest changes possible. By doing so,
- you'll have faster reviews and your changes will be less prone to errors.
+ reviews are faster and your changes are less prone to errors.
- Do not use capital letters nor special chars in branch names.
diff --git a/doc/user/project/merge_requests/img/reviewer_approval_rules_form_v13_8.png b/doc/user/project/merge_requests/img/reviewer_approval_rules_form_v13_8.png
new file mode 100644
index 00000000000..c2aa0689d65
--- /dev/null
+++ b/doc/user/project/merge_requests/img/reviewer_approval_rules_form_v13_8.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/reviewer_approval_rules_sidebar_v13_8.png b/doc/user/project/merge_requests/img/reviewer_approval_rules_sidebar_v13_8.png
new file mode 100644
index 00000000000..3828868965b
--- /dev/null
+++ b/doc/user/project/merge_requests/img/reviewer_approval_rules_sidebar_v13_8.png
Binary files differ
diff --git a/doc/user/project/requirements/index.md b/doc/user/project/requirements/index.md
index 9d75c4ab071..c99b0d91523 100644
--- a/doc/user/project/requirements/index.md
+++ b/doc/user/project/requirements/index.md
@@ -34,7 +34,7 @@ Users with Reporter or higher [permissions](../../permissions.md) can create req
To create a requirement:
-1. From your project page, go to **Requirements**.
+1. In a project, go to **Requirements**.
1. Select **New requirement**.
1. Enter a title and description and select **Create requirement**.
@@ -200,10 +200,10 @@ requirements_confirmation:
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/246857) in GitLab 13.7.
-You can import requirements to a project by uploading a CSV file with the columns
-`title` and `description`.
+You can import requirements to a project by uploading a [CSV file](https://en.wikipedia.org/wiki/Comma-separated_values)
+with the columns `title` and `description`.
-The user uploading the CSV file will be set as the author of the imported requirements.
+After the import, the user uploading the CSV file is set as the author of the imported requirements.
Users with Reporter or higher [permissions](../../permissions.md) can import requirements.
@@ -213,20 +213,20 @@ Before you import your file:
- Consider importing a test file containing only a few requirements. There is no way to undo a large
import without using the GitLab API.
-- Ensure your CSV file meets the [file format](#csv-file-format) requirements.
+- Ensure your CSV file meets the [file format](#imported-csv-file-format) requirements.
To import requirements:
-1. Navigate to a project's Requirements page.
- - If the project already has existing requirements, click the import icon (**{import}**) at the
+1. In a project, go to **Requirements**.
+ - If the project already has existing requirements, select the import icon (**{import}**) in the
top right.
- - For a project without any requirements, click **Import CSV** in the middle of the page.
-1. Select the file and click **Import requirements**.
+ - For a project without any requirements, select **Import CSV** in the middle of the page.
+1. Select the file and select **Import requirements**.
The file is processed in the background and a notification email is sent
to you after the import is complete.
-### CSV file format
+### Imported CSV file format
When importing requirements from a CSV file, it must be formatted in a certain way:
@@ -257,3 +257,37 @@ Another Title,"A description, with a comma"
The limit depends on the configuration value of Max Attachment Size for the GitLab instance.
For GitLab.com, it is set to 10 MB.
+
+## Export requirements to a CSV file
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/290813) in GitLab 13.8.
+
+You can export GitLab requirements to a
+[CSV file](https://en.wikipedia.org/wiki/Comma-separated_values) sent to your default notification
+email as an attachment.
+
+By exporting requirements, you and your team can import them into another tool or share them with
+your customers. Exporting requirements can aid collaboration with higher-level systems, as well as
+audit and regulatory compliance tasks.
+
+Users with Reporter or higher [permissions](../../permissions.md) can export requirements.
+
+To export requirements:
+
+1. In a project, go to **Requirements**.
+1. Select the **Export as CSV** icon (**{export}**) in the top right. A confirmation modal appears.
+1. Select **Export requirements**. The exported CSV file is sent to the email address associated with your user.
+
+### Exported CSV file format
+
+You can preview the exported CSV file in a spreadsheet editor, such as Microsoft Excel,
+OpenOffice Calc, or Google Sheets.
+
+The exported CSV file contains the following columns:
+
+- Requirement ID
+- Title
+- Description
+- Author Username
+- Latest Test Report State
+- Latest Test Report Created At (UTC)
diff --git a/lib/backup/repositories.rb b/lib/backup/repositories.rb
index 4248a86dc7c..d15114a72a3 100644
--- a/lib/backup/repositories.rb
+++ b/lib/backup/repositories.rb
@@ -40,31 +40,42 @@ module Backup
end
def restore
+ restore_project_repositories
+ restore_snippets
+
+ restore_object_pools
+ end
+
+ private
+
+ def restore_project_repositories
Project.find_each(batch_size: 1000) do |project|
restore_repository(project, Gitlab::GlRepository::PROJECT)
restore_repository(project, Gitlab::GlRepository::WIKI)
restore_repository(project, Gitlab::GlRepository::DESIGN)
end
+ end
+ def restore_snippets
invalid_ids = Snippet.find_each(batch_size: 1000)
.map { |snippet| restore_snippet_repository(snippet) }
.compact
cleanup_snippets_without_repositories(invalid_ids)
-
- restore_object_pools
end
- private
-
def check_valid_storages!
- [ProjectRepository, SnippetRepository].each do |klass|
+ repository_storage_klasses.each do |klass|
if klass.excluding_repository_storage(Gitlab.config.repositories.storages.keys).exists?
raise Error, "repositories.storages in gitlab.yml does not include all storages used by #{klass}"
end
end
end
+ def repository_storage_klasses
+ [ProjectRepository, SnippetRepository]
+ end
+
def backup_repos_path
@backup_repos_path ||= File.join(Gitlab.config.backup.path, 'repositories')
end
@@ -103,12 +114,7 @@ module Backup
end
begin
- case container
- when Project
- dump_project(container)
- when Snippet
- dump_snippet(container)
- end
+ dump_container(container)
rescue => e
errors << e
break
@@ -130,6 +136,15 @@ module Backup
end
end
+ def dump_container(container)
+ case container
+ when Project
+ dump_project(container)
+ when Snippet
+ dump_snippet(container)
+ end
+ end
+
def dump_project(project)
backup_repository(project, Gitlab::GlRepository::PROJECT)
backup_repository(project, Gitlab::GlRepository::WIKI)
@@ -308,3 +323,5 @@ module Backup
end
end
end
+
+Backup::Repositories.prepend_if_ee('EE::Backup::Repositories')
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb
index f080348455d..6b169a504f3 100644
--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -1165,9 +1165,9 @@ module Gitlab
Arel::Nodes::SqlLiteral.new(replace.to_sql)
end
- def remove_foreign_key_if_exists(*args)
- if foreign_key_exists?(*args)
- remove_foreign_key(*args)
+ def remove_foreign_key_if_exists(...)
+ if foreign_key_exists?(...)
+ remove_foreign_key(...)
end
end
diff --git a/lib/gitlab/diff/position.rb b/lib/gitlab/diff/position.rb
index e43f301c280..74c33c46598 100644
--- a/lib/gitlab/diff/position.rb
+++ b/lib/gitlab/diff/position.rb
@@ -19,6 +19,7 @@ module Gitlab
:height,
:x,
:y,
+ :line_range,
:position_type, to: :formatter
# A position can belong to a text line or to an image coordinate
@@ -167,6 +168,12 @@ module Gitlab
end
end
+ def multiline?
+ return unless on_text? && line_range
+
+ line_range['start'] != line_range['end']
+ end
+
private
def find_diff_file(repository)
diff --git a/lib/gitlab/usage_data_counters/known_events/common.yml b/lib/gitlab/usage_data_counters/known_events/common.yml
index 4b033d909e0..e478f0c75ed 100644
--- a/lib/gitlab/usage_data_counters/known_events/common.yml
+++ b/lib/gitlab/usage_data_counters/known_events/common.yml
@@ -258,6 +258,11 @@
redis_slot: testing
aggregation: weekly
feature_flag: usage_data_i_testing_group_code_coverage_visit_total
+- name: i_testing_full_code_quality_report_total
+ category: testing
+ redis_slot: testing
+ aggregation: weekly
+ feature_flag: usage_data_i_testing_full_code_quality_report_total
# Project Management group
- name: g_project_management_issue_title_changed
category: issues_edit
@@ -496,6 +501,21 @@
category: code_review
aggregation: weekly
feature_flag: usage_data_i_code_review_user_publish_review
+- name: i_code_review_user_create_multiline_mr_comment
+ redis_slot: code_review
+ category: code_review
+ aggregation: weekly
+ feature_flag: usage_data_i_code_review_user_create_multiline_mr_comment
+- name: i_code_review_user_edit_multiline_mr_comment
+ redis_slot: code_review
+ category: code_review
+ aggregation: weekly
+ feature_flag: usage_data_i_code_review_user_edit_multiline_mr_comment
+- name: i_code_review_user_remove_multiline_mr_comment
+ redis_slot: code_review
+ category: code_review
+ aggregation: weekly
+ feature_flag: usage_data_i_code_review_user_remove_multiline_mr_comment
# Terraform
- name: p_terraform_state_api_unique_users
category: terraform
diff --git a/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb b/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb
index 6309ca0201a..11d59257ed9 100644
--- a/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb
+++ b/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb
@@ -15,6 +15,9 @@ module Gitlab
MR_REMOVE_COMMENT_ACTION = 'i_code_review_user_remove_mr_comment'
MR_CREATE_REVIEW_NOTE_ACTION = 'i_code_review_user_create_review_note'
MR_PUBLISH_REVIEW_ACTION = 'i_code_review_user_publish_review'
+ MR_CREATE_MULTILINE_COMMENT_ACTION = 'i_code_review_user_create_multiline_mr_comment'
+ MR_EDIT_MULTILINE_COMMENT_ACTION = 'i_code_review_user_edit_multiline_mr_comment'
+ MR_REMOVE_MULTILINE_COMMENT_ACTION = 'i_code_review_user_remove_multiline_mr_comment'
class << self
def track_mr_diffs_action(merge_request:)
@@ -42,16 +45,19 @@ module Gitlab
track_unique_action_by_user(MR_REOPEN_ACTION, user)
end
- def track_create_comment_action(user:)
- track_unique_action_by_user(MR_CREATE_COMMENT_ACTION, user)
+ def track_create_comment_action(note:)
+ track_unique_action_by_user(MR_CREATE_COMMENT_ACTION, note.author)
+ track_multiline_unique_action(MR_CREATE_MULTILINE_COMMENT_ACTION, note)
end
- def track_edit_comment_action(user:)
- track_unique_action_by_user(MR_EDIT_COMMENT_ACTION, user)
+ def track_edit_comment_action(note:)
+ track_unique_action_by_user(MR_EDIT_COMMENT_ACTION, note.author)
+ track_multiline_unique_action(MR_EDIT_MULTILINE_COMMENT_ACTION, note)
end
- def track_remove_comment_action(user:)
- track_unique_action_by_user(MR_REMOVE_COMMENT_ACTION, user)
+ def track_remove_comment_action(note:)
+ track_unique_action_by_user(MR_REMOVE_COMMENT_ACTION, note.author)
+ track_multiline_unique_action(MR_REMOVE_MULTILINE_COMMENT_ACTION, note)
end
def track_create_review_note_action(user:)
@@ -77,6 +83,12 @@ module Gitlab
def track_unique_action(action, value)
Gitlab::UsageDataCounters::HLLRedisCounter.track_usage_event(action, value)
end
+
+ def track_multiline_unique_action(action, note)
+ return unless note.is_a?(DiffNote) && note.multiline?
+
+ track_unique_action_by_user(action, note.author)
+ end
end
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 0e177b97ddb..540de49f41c 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -15042,6 +15042,9 @@ msgstr ""
msgid "Incidents|Must start with http or https"
msgstr ""
+msgid "Incidents|There was an issue deleting the image."
+msgstr ""
+
msgid "Incidents|There was an issue loading metric images."
msgstr ""
@@ -15054,6 +15057,12 @@ msgstr ""
msgid "Incident|Alert details"
msgstr ""
+msgid "Incident|Are you sure you wish to delete this image?"
+msgstr ""
+
+msgid "Incident|Deleting %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
diff --git a/spec/frontend/projects/pipelines/charts/components/app_legacy_spec.js b/spec/frontend/projects/pipelines/charts/components/app_legacy_spec.js
deleted file mode 100644
index 23f37073a0f..00000000000
--- a/spec/frontend/projects/pipelines/charts/components/app_legacy_spec.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import Component from '~/projects/pipelines/charts/components/app_legacy.vue';
-import PipelineCharts from '~/projects/pipelines/charts/components/pipeline_charts.vue';
-import {
- counts,
- timesChartData,
- areaChartData as lastWeekChartData,
- areaChartData as lastMonthChartData,
- lastYearChartData,
-} from '../mock_data';
-
-describe('ProjectsPipelinesChartsApp', () => {
- let wrapper;
-
- beforeEach(() => {
- wrapper = shallowMount(Component, {
- propsData: {
- counts,
- timesChartData,
- lastWeekChartData,
- lastMonthChartData,
- lastYearChartData,
- },
- provide: {
- projectPath: 'test/project',
- shouldRenderDeploymentFrequencyCharts: true,
- },
- stubs: {
- DeploymentFrequencyCharts: true,
- },
- });
- });
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- describe('pipelines charts', () => {
- it('displays the pipeline charts', () => {
- const chart = wrapper.find(PipelineCharts);
-
- expect(chart.exists()).toBe(true);
- expect(chart.props()).toMatchObject({
- counts,
- lastWeek: lastWeekChartData,
- lastMonth: lastMonthChartData,
- lastYear: lastYearChartData,
- timesChart: timesChartData,
- });
- });
- });
-});
diff --git a/spec/lib/gitlab/ci/config/entry/variables_spec.rb b/spec/lib/gitlab/ci/config/entry/variables_spec.rb
index 426a38e2ef7..78d37e228df 100644
--- a/spec/lib/gitlab/ci/config/entry/variables_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/variables_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Ci::Config::Entry::Variables do
let(:metadata) { {} }
- subject { described_class.new(config, metadata) }
+ subject { described_class.new(config, **metadata) }
shared_examples 'valid config' do
describe '#value' do
diff --git a/spec/lib/gitlab/diff/position_spec.rb b/spec/lib/gitlab/diff/position_spec.rb
index a7f6ea0cbfb..c9a20f40462 100644
--- a/spec/lib/gitlab/diff/position_spec.rb
+++ b/spec/lib/gitlab/diff/position_spec.rb
@@ -752,4 +752,62 @@ RSpec.describe Gitlab::Diff::Position do
expect(subject.file_hash).to eq(Digest::SHA1.hexdigest(subject.file_path))
end
end
+
+ describe '#multiline?' do
+ let(:end_line_code) { "ab09011fa121d0a2bb9fa4ca76094f2482b902b7_#{end_old_line}_#{end_new_line}" }
+
+ let(:line_range) do
+ {
+ "start" => {
+ "line_code" => "ab09011fa121d0a2bb9fa4ca76094f2482b902b7_18_18",
+ "type" => nil,
+ "old_line" => 18,
+ "new_line" => 18
+ },
+ "end" => {
+ "line_code" => end_line_code,
+ "type" => nil,
+ "old_line" => end_old_line,
+ "new_line" => end_new_line
+ }
+ }
+ end
+
+ subject(:multiline) do
+ described_class.new(
+ line_range: line_range,
+ position_type: position_type
+ )
+ end
+
+ let(:end_old_line) { 20 }
+ let(:end_new_line) { 20 }
+
+ context 'when the position type is text' do
+ let(:position_type) { "text" }
+
+ context 'when the start lines equal the end lines' do
+ let(:end_old_line) { 18 }
+ let(:end_new_line) { 18 }
+
+ it "returns true" do
+ expect(subject.multiline?).to be_falsey
+ end
+ end
+
+ context 'when the start lines do not equal the end lines' do
+ it "returns true" do
+ expect(subject.multiline?).to be_truthy
+ end
+ end
+ end
+
+ context 'when the position type is not text' do
+ let(:position_type) { "image" }
+
+ it "returns false" do
+ expect(subject.multiline?).to be_falsey
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb
index 0dec9dbfeea..c7b208cfb31 100644
--- a/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb
@@ -5,6 +5,7 @@ require 'spec_helper'
RSpec.describe Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter, :clean_gitlab_redis_shared_state do
let(:merge_request) { build(:merge_request, id: 1) }
let(:user) { build(:user, id: 1) }
+ let(:note) { build(:note, author: user) }
shared_examples_for 'a tracked merge request unique event' do
specify do
@@ -73,27 +74,63 @@ RSpec.describe Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter, :cl
end
describe '.track_create_comment_action' do
- subject { described_class.track_create_comment_action(user: user) }
+ subject { described_class.track_create_comment_action(note: note) }
it_behaves_like 'a tracked merge request unique event' do
let(:action) { described_class::MR_CREATE_COMMENT_ACTION }
end
+
+ context 'when the note is multiline diff note' do
+ let(:note) { build(:diff_note_on_merge_request, author: user) }
+
+ before do
+ allow(note).to receive(:multiline?).and_return(true)
+ end
+
+ it_behaves_like 'a tracked merge request unique event' do
+ let(:action) { described_class::MR_CREATE_MULTILINE_COMMENT_ACTION }
+ end
+ end
end
describe '.track_edit_comment_action' do
- subject { described_class.track_edit_comment_action(user: user) }
+ subject { described_class.track_edit_comment_action(note: note) }
it_behaves_like 'a tracked merge request unique event' do
let(:action) { described_class::MR_EDIT_COMMENT_ACTION }
end
+
+ context 'when the note is multiline diff note' do
+ let(:note) { build(:diff_note_on_merge_request, author: user) }
+
+ before do
+ allow(note).to receive(:multiline?).and_return(true)
+ end
+
+ it_behaves_like 'a tracked merge request unique event' do
+ let(:action) { described_class::MR_EDIT_MULTILINE_COMMENT_ACTION }
+ end
+ end
end
describe '.track_remove_comment_action' do
- subject { described_class.track_remove_comment_action(user: user) }
+ subject { described_class.track_remove_comment_action(note: note) }
it_behaves_like 'a tracked merge request unique event' do
let(:action) { described_class::MR_REMOVE_COMMENT_ACTION }
end
+
+ context 'when the note is multiline diff note' do
+ let(:note) { build(:diff_note_on_merge_request, author: user) }
+
+ before do
+ allow(note).to receive(:multiline?).and_return(true)
+ end
+
+ it_behaves_like 'a tracked merge request unique event' do
+ let(:action) { described_class::MR_REMOVE_MULTILINE_COMMENT_ACTION }
+ end
+ end
end
describe '.track_create_review_note_action' do
diff --git a/spec/services/notes/create_service_spec.rb b/spec/services/notes/create_service_spec.rb
index 451615c6f53..20f06619e02 100644
--- a/spec/services/notes/create_service_spec.rb
+++ b/spec/services/notes/create_service_spec.rb
@@ -120,7 +120,7 @@ RSpec.describe Notes::CreateService do
end
it 'tracks merge request usage data' do
- expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter).to receive(:track_create_comment_action).with(user: user)
+ expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter).to receive(:track_create_comment_action).with(note: kind_of(Note))
described_class.new(project_with_repo, user, new_opts).execute
end
diff --git a/spec/services/notes/destroy_service_spec.rb b/spec/services/notes/destroy_service_spec.rb
index a19840af7a7..eebbdcc33b8 100644
--- a/spec/services/notes/destroy_service_spec.rb
+++ b/spec/services/notes/destroy_service_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe Notes::DestroyService do
it 'tracks merge request usage data' do
mr = create(:merge_request, source_project: project)
note = create(:note, project: project, noteable: mr)
- expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter).to receive(:track_remove_comment_action).with(user: user)
+ expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter).to receive(:track_remove_comment_action).with(note: note)
described_class.new(project, user).execute(note)
end
diff --git a/spec/services/notes/update_service_spec.rb b/spec/services/notes/update_service_spec.rb
index 2ebf0c29686..902fd9958f8 100644
--- a/spec/services/notes/update_service_spec.rb
+++ b/spec/services/notes/update_service_spec.rb
@@ -69,7 +69,7 @@ RSpec.describe Notes::UpdateService do
let(:note) { create(:note, project: project, noteable: merge_request, author: user, note: "Old note #{user2.to_reference}") }
it 'tracks merge request usage data' do
- expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter).to receive(:track_edit_comment_action).with(user: user)
+ expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter).to receive(:track_edit_comment_action).with(note: note)
update_note(note: 'new text')
end