diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-01-15 00:10:37 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-01-15 00:10:37 +0300 |
commit | 8f534e1e960eef1f4cfcb7c6d723840523515ffb (patch) | |
tree | 884401cb4e5db9dd9b301e57f588d17df2a92966 | |
parent | ea3306a15e945e694afba62dc93b17500ffaec7f (diff) |
Add latest changes from gitlab-org/gitlab@master
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 Binary files differnew file mode 100644 index 00000000000..7a5a2fab6e3 --- /dev/null +++ b/doc/user/project/img/optional_code_owners_sections_v13_8.png 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 Binary files differnew file mode 100644 index 00000000000..c2aa0689d65 --- /dev/null +++ b/doc/user/project/merge_requests/img/reviewer_approval_rules_form_v13_8.png 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 Binary files differnew file mode 100644 index 00000000000..3828868965b --- /dev/null +++ b/doc/user/project/merge_requests/img/reviewer_approval_rules_sidebar_v13_8.png 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 |