diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-04 21:09:22 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-04 21:09:22 +0300 |
commit | 7c221ba5ce130ca50b892e6dd32783e1327718df (patch) | |
tree | 2c11d688f89886c8ea37638061fe450c8b656e47 /app | |
parent | da602b32e45431234e592e8f7001c3ace1771765 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
47 files changed, 261 insertions, 102 deletions
diff --git a/app/assets/javascripts/alert_management/components/alert_management_table.vue b/app/assets/javascripts/alert_management/components/alert_management_table.vue index 2bad15faa85..dae52a530ac 100644 --- a/app/assets/javascripts/alert_management/components/alert_management_table.vue +++ b/app/assets/javascripts/alert_management/components/alert_management_table.vue @@ -23,14 +23,10 @@ import { } from '~/vue_shared/components/paginated_table_with_search_and_tabs/constants'; import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; import { convertToSnakeCase } from '~/lib/utils/text_utility'; +import AlertStatus from '~/vue_shared/alert_details/components/alert_status.vue'; import getAlertsQuery from '~/graphql_shared/queries/get_alerts.query.graphql'; import getAlertsCountByStatus from '../graphql/queries/get_count_by_status.query.graphql'; -import { - ALERTS_STATUS_TABS, - ALERTS_SEVERITY_LABELS, - trackAlertListViewsOptions, -} from '../constants'; -import AlertStatus from './alert_status.vue'; +import { ALERTS_STATUS_TABS, SEVERITY_LEVELS, trackAlertListViewsOptions } from '../constants'; const TH_TEST_ID = { 'data-testid': 'alert-management-severity-sort' }; @@ -96,7 +92,7 @@ export default { sortable: true, }, ], - severityLabels: ALERTS_SEVERITY_LABELS, + severityLabels: SEVERITY_LEVELS, statusTabs: ALERTS_STATUS_TABS, components: { GlAlert, diff --git a/app/assets/javascripts/alert_management/constants.js b/app/assets/javascripts/alert_management/constants.js index b79a64646eb..c98d3865621 100644 --- a/app/assets/javascripts/alert_management/constants.js +++ b/app/assets/javascripts/alert_management/constants.js @@ -1,12 +1,12 @@ import { s__ } from '~/locale'; -export const ALERTS_SEVERITY_LABELS = { - CRITICAL: s__('AlertManagement|Critical'), - HIGH: s__('AlertManagement|High'), - MEDIUM: s__('AlertManagement|Medium'), - LOW: s__('AlertManagement|Low'), - INFO: s__('AlertManagement|Info'), - UNKNOWN: s__('AlertManagement|Unknown'), +export const SEVERITY_LEVELS = { + CRITICAL: s__('severity|Critical'), + HIGH: s__('severity|High'), + MEDIUM: s__('severity|Medium'), + LOW: s__('severity|Low'), + INFO: s__('severity|Info'), + UNKNOWN: s__('severity|Unknown'), }; export const ALERTS_STATUS_TABS = [ @@ -46,20 +46,3 @@ export const trackAlertListViewsOptions = { category: 'Alert Management', action: 'view_alerts_list', }; - -/** - * Tracks snowplow event when user views alert details - */ -export const trackAlertsDetailsViewsOptions = { - category: 'Alert Management', - action: 'view_alert_details', -}; - -/** - * Tracks snowplow event when alert status is updated - */ -export const trackAlertStatusUpdateOptions = { - category: 'Alert Management', - action: 'update_alert_status', - label: 'Status', -}; diff --git a/app/assets/javascripts/alert_management/list.js b/app/assets/javascripts/alert_management/list.js index b484841ed2c..4b18dee7806 100644 --- a/app/assets/javascripts/alert_management/list.js +++ b/app/assets/javascripts/alert_management/list.js @@ -3,6 +3,7 @@ import VueApollo from 'vue-apollo'; import { defaultDataIdFromObject } from 'apollo-cache-inmemory'; import createDefaultClient from '~/lib/graphql'; import { parseBoolean } from '~/lib/utils/common_utils'; +import { PAGE_CONFIG } from '~/vue_shared/alert_details/constants'; import AlertManagementList from './components/alert_management_list_wrapper.vue'; Vue.use(VueApollo); @@ -59,6 +60,7 @@ export default () => { populatingAlertsHelpUrl, emptyAlertSvgPath, alertManagementEnabled: parseBoolean(alertManagementEnabled), + trackAlertStatusUpdateOptions: PAGE_CONFIG.OPERATIONS.TRACK_ALERT_STATUS_UPDATE_OPTIONS, userCanEnableAlertManagement: parseBoolean(userCanEnableAlertManagement), }, apolloProvider, diff --git a/app/assets/javascripts/graphql_shared/fragments/alert_note.fragment.graphql b/app/assets/javascripts/graphql_shared/fragments/alert_note.fragment.graphql index 74b425717a0..801311301ac 100644 --- a/app/assets/javascripts/graphql_shared/fragments/alert_note.fragment.graphql +++ b/app/assets/javascripts/graphql_shared/fragments/alert_note.fragment.graphql @@ -1,4 +1,4 @@ -#import "~/graphql_shared/fragments/author.fragment.graphql" +#import "./author.fragment.graphql" fragment AlertNote on Note { id diff --git a/app/assets/javascripts/graphql_shared/mutations/update_alert_status.mutation.graphql b/app/assets/javascripts/graphql_shared/mutations/alert_status_update.mutation.graphql index 42dc388c9d1..ba1e607bc10 100644 --- a/app/assets/javascripts/graphql_shared/mutations/update_alert_status.mutation.graphql +++ b/app/assets/javascripts/graphql_shared/mutations/alert_status_update.mutation.graphql @@ -1,4 +1,4 @@ -#import "~/graphql_shared/fragments/alert_note.fragment.graphql" +#import "../fragments/alert_note.fragment.graphql" mutation updateAlertStatus($projectPath: ID!, $status: AlertManagementStatus!, $iid: String!) { updateAlertStatus(input: { iid: $iid, status: $status, projectPath: $projectPath }) { diff --git a/app/assets/javascripts/pages/projects/alert_management/details/index.js b/app/assets/javascripts/pages/projects/alert_management/details/index.js index a20f6713c9d..183e07ca1fc 100644 --- a/app/assets/javascripts/pages/projects/alert_management/details/index.js +++ b/app/assets/javascripts/pages/projects/alert_management/details/index.js @@ -1,3 +1,3 @@ -import AlertDetails from '~/alert_management/details'; +import AlertDetails from '~/vue_shared/alert_details'; AlertDetails('#js-alert_details'); diff --git a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue index 1485c43f002..b258c885abb 100644 --- a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue @@ -78,11 +78,7 @@ export default { return `ci-badge-${escape(group.name)}`; }, isFadedOut(jobName) { - return ( - this.jobHovered && - this.highlightedJobs.length > 1 && - !this.highlightedJobs.includes(jobName) - ); + return this.highlightedJobs.length > 1 && !this.highlightedJobs.includes(jobName); }, }, }; @@ -126,12 +122,9 @@ export default { :class="{ 'gl-opacity-3': isFadedOut(group.name) }" @pipelineActionRequestComplete="$emit('refreshPipelineGraph')" /> - <job-group-dropdown - v-else - :group="group" - :pipeline-id="pipelineId" - :class="{ 'gl-opacity-3': isFadedOut(group.name) }" - /> + <div v-else :class="{ 'gl-opacity-3': isFadedOut(group.name) }"> + <job-group-dropdown :group="group" :pipeline-id="pipelineId" /> + </div> </div> </template> </main-graph-wrapper> diff --git a/app/assets/javascripts/reports/codequality_report/grouped_codequality_reports_app.vue b/app/assets/javascripts/reports/codequality_report/grouped_codequality_reports_app.vue index 42c6df44b5d..c1de1ab25c1 100644 --- a/app/assets/javascripts/reports/codequality_report/grouped_codequality_reports_app.vue +++ b/app/assets/javascripts/reports/codequality_report/grouped_codequality_reports_app.vue @@ -62,7 +62,7 @@ export default { helpPath: this.codequalityHelpPath, }); - this.fetchReports(this.glFeatures.codequalityMrDiff); + this.fetchReports(this.glFeatures.codequalityBackendComparison); }, methods: { ...mapActions(['fetchReports', 'setPaths']), diff --git a/app/assets/javascripts/alert_management/components/alert_details.vue b/app/assets/javascripts/vue_shared/alert_details/components/alert_details.vue index 5da4cae2439..673c6f4a1eb 100644 --- a/app/assets/javascripts/alert_management/components/alert_details.vue +++ b/app/assets/javascripts/vue_shared/alert_details/components/alert_details.vue @@ -21,11 +21,11 @@ import { visitUrl, joinPaths } from '~/lib/utils/url_utility'; import Tracking from '~/tracking'; import { toggleContainerClasses } from '~/lib/utils/dom_utils'; import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue'; -import alertQuery from '../graphql/queries/details.query.graphql'; -import sidebarStatusQuery from '../graphql/queries/sidebar_status.query.graphql'; -import { ALERTS_SEVERITY_LABELS, trackAlertsDetailsViewsOptions } from '../constants'; -import createIssueMutation from '../graphql/mutations/create_issue_from_alert.mutation.graphql'; -import toggleSidebarStatusMutation from '../graphql/mutations/toggle_sidebar_status.mutation.graphql'; +import alertQuery from '../graphql/queries/alert_details.query.graphql'; +import sidebarStatusQuery from '../graphql/queries/alert_sidebar_status.query.graphql'; +import { SEVERITY_LEVELS } from '../constants'; +import createIssueMutation from '../graphql/mutations/alert_issue_create.mutation.graphql'; +import toggleSidebarStatusMutation from '../graphql/mutations/alert_sidebar_status.mutation.graphql'; import SystemNote from './system_notes/system_note.vue'; import AlertSidebar from './alert_sidebar.vue'; import AlertMetrics from './alert_metrics.vue'; @@ -44,7 +44,7 @@ export default { directives: { SafeHtml: GlSafeHtmlDirective, }, - severityLabels: ALERTS_SEVERITY_LABELS, + severityLabels: SEVERITY_LEVELS, tabsConfig: [ { id: 'overview', @@ -89,6 +89,9 @@ export default { projectIssuesPath: { default: '', }, + trackAlertsDetailsViewsOptions: { + default: null, + }, }, apollo: { alert: { @@ -155,7 +158,9 @@ export default { }, }, mounted() { - this.trackPageViews(); + if (this.trackAlertsDetailsViewsOptions) { + this.trackPageViews(); + } toggleContainerClasses(containerEl, { 'issuable-bulk-update-sidebar': true, 'right-sidebar-expanded': true, @@ -217,7 +222,7 @@ export default { return joinPaths(this.projectIssuesPath, issueId); }, trackPageViews() { - const { category, action } = trackAlertsDetailsViewsOptions; + const { category, action } = this.trackAlertsDetailsViewsOptions; Tracking.event(category, action); }, }, diff --git a/app/assets/javascripts/alert_management/components/alert_metrics.vue b/app/assets/javascripts/vue_shared/alert_details/components/alert_metrics.vue index dd4faa03c00..dd4faa03c00 100644 --- a/app/assets/javascripts/alert_management/components/alert_metrics.vue +++ b/app/assets/javascripts/vue_shared/alert_details/components/alert_metrics.vue diff --git a/app/assets/javascripts/alert_management/components/alert_sidebar.vue b/app/assets/javascripts/vue_shared/alert_details/components/alert_sidebar.vue index aa98e34d424..12c58b582c5 100644 --- a/app/assets/javascripts/alert_management/components/alert_sidebar.vue +++ b/app/assets/javascripts/vue_shared/alert_details/components/alert_sidebar.vue @@ -1,5 +1,5 @@ <script> -import sidebarStatusQuery from '../graphql/queries/sidebar_status.query.graphql'; +import sidebarStatusQuery from '../graphql/queries/alert_sidebar_status.query.graphql'; import SidebarHeader from './sidebar/sidebar_header.vue'; import SidebarTodo from './sidebar/sidebar_todo.vue'; import SidebarStatus from './sidebar/sidebar_status.vue'; diff --git a/app/assets/javascripts/alert_management/components/alert_status.vue b/app/assets/javascripts/vue_shared/alert_details/components/alert_status.vue index 3d46ce07b53..5520f7ff045 100644 --- a/app/assets/javascripts/alert_management/components/alert_status.vue +++ b/app/assets/javascripts/vue_shared/alert_details/components/alert_status.vue @@ -2,8 +2,7 @@ import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; import { s__ } from '~/locale'; import Tracking from '~/tracking'; -import updateAlertStatusMutation from '~/graphql_shared/mutations/update_alert_status.mutation.graphql'; -import { trackAlertStatusUpdateOptions } from '../constants'; +import updateAlertStatusMutation from '~/graphql_shared/mutations/alert_status_update.mutation.graphql'; export default { i18n: { @@ -21,6 +20,11 @@ export default { GlDropdown, GlDropdownItem, }, + inject: { + trackAlertStatusUpdateOptions: { + default: null, + }, + }, props: { projectPath: { type: String, @@ -58,7 +62,9 @@ export default { }, }) .then((resp) => { - this.trackStatusUpdate(status); + if (this.trackAlertStatusUpdateOptions) { + this.trackStatusUpdate(status); + } const errors = resp.data?.updateAlertStatus?.errors || []; if (errors[0]) { @@ -81,7 +87,7 @@ export default { }); }, trackStatusUpdate(status) { - const { category, action, label } = trackAlertStatusUpdateOptions; + const { category, action, label } = this.trackAlertStatusUpdateOptions; Tracking.event(category, action, { label, property: status }); }, }, diff --git a/app/assets/javascripts/alert_management/components/alert_summary_row.vue b/app/assets/javascripts/vue_shared/alert_details/components/alert_summary_row.vue index 13835b7e2fa..13835b7e2fa 100644 --- a/app/assets/javascripts/alert_management/components/alert_summary_row.vue +++ b/app/assets/javascripts/vue_shared/alert_details/components/alert_summary_row.vue diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignee.vue index c39a72a45b9..c39a72a45b9 100644 --- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue +++ b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignee.vue diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignees.vue index 2a999b908f9..2a999b908f9 100644 --- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue +++ b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignees.vue diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_header.vue index fd40b5d9f65..fd40b5d9f65 100644 --- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue +++ b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_header.vue diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_status.vue index 0a2bad5510b..0a2bad5510b 100644 --- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue +++ b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_status.vue diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_todo.vue index 34d34f3d232..216b429fcbe 100644 --- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue +++ b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_todo.vue @@ -4,7 +4,7 @@ import { s__ } from '~/locale'; import Todo from '~/sidebar/components/todo_toggle/todo.vue'; import todoMarkDoneMutation from '~/graphql_shared/mutations/todo_mark_done.mutation.graphql'; import createAlertTodoMutation from '../../graphql/mutations/alert_todo_create.mutation.graphql'; -import alertQuery from '../../graphql/queries/details.query.graphql'; +import alertQuery from '../../graphql/queries/alert_details.query.graphql'; export default { i18n: { diff --git a/app/assets/javascripts/alert_management/components/system_notes/system_note.vue b/app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue index 3705e36a579..3705e36a579 100644 --- a/app/assets/javascripts/alert_management/components/system_notes/system_note.vue +++ b/app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue diff --git a/app/assets/javascripts/vue_shared/alert_details/constants.js b/app/assets/javascripts/vue_shared/alert_details/constants.js new file mode 100644 index 00000000000..56f79410064 --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/constants.js @@ -0,0 +1,29 @@ +import { s__ } from '~/locale'; + +export const SEVERITY_LEVELS = { + CRITICAL: s__('severity|Critical'), + HIGH: s__('severity|High'), + MEDIUM: s__('severity|Medium'), + LOW: s__('severity|Low'), + INFO: s__('severity|Info'), + UNKNOWN: s__('severity|Unknown'), +}; + +export const DEFAULT_PAGE = 'OPERATIONS'; + +/* eslint-disable @gitlab/require-i18n-strings */ +export const PAGE_CONFIG = { + OPERATIONS: { + // Tracks snowplow event when user views alert details + TRACK_ALERTS_DETAILS_VIEWS_OPTIONS: { + category: 'Alert Management', + action: 'view_alert_details', + }, + // Tracks snowplow event when alert status is updated + TRACK_ALERT_STATUS_UPDATE_OPTIONS: { + category: 'Alert Management', + action: 'update_alert_status', + label: 'Status', + }, + }, +}; diff --git a/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql b/app/assets/javascripts/vue_shared/alert_details/graphql/fragments/alert_detail_item.fragment.graphql index 9a9ae369519..9a9ae369519 100644 --- a/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql +++ b/app/assets/javascripts/vue_shared/alert_details/graphql/fragments/alert_detail_item.fragment.graphql diff --git a/app/assets/javascripts/alert_management/graphql/mutations/create_issue_from_alert.mutation.graphql b/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_issue_create.mutation.graphql index bc4d91a51d1..bc4d91a51d1 100644 --- a/app/assets/javascripts/alert_management/graphql/mutations/create_issue_from_alert.mutation.graphql +++ b/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_issue_create.mutation.graphql diff --git a/app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.mutation.graphql b/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_set_assignees.mutation.graphql index 63d952a4857..63d952a4857 100644 --- a/app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.mutation.graphql +++ b/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_set_assignees.mutation.graphql diff --git a/app/assets/javascripts/alert_management/graphql/mutations/toggle_sidebar_status.mutation.graphql b/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_sidebar_status.mutation.graphql index f666fcd6782..f666fcd6782 100644 --- a/app/assets/javascripts/alert_management/graphql/mutations/toggle_sidebar_status.mutation.graphql +++ b/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_sidebar_status.mutation.graphql diff --git a/app/assets/javascripts/alert_management/graphql/mutations/alert_todo_create.mutation.graphql b/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_todo_create.mutation.graphql index ac9858c104f..dc961b5eb90 100644 --- a/app/assets/javascripts/alert_management/graphql/mutations/alert_todo_create.mutation.graphql +++ b/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_todo_create.mutation.graphql @@ -1,4 +1,4 @@ -#import "../fragments/detail_item.fragment.graphql" +#import "../fragments/alert_detail_item.fragment.graphql" mutation alertTodoCreate($projectPath: ID!, $iid: String!) { alertTodoCreate(input: { iid: $iid, projectPath: $projectPath }) { diff --git a/app/assets/javascripts/alert_management/graphql/queries/details.query.graphql b/app/assets/javascripts/vue_shared/alert_details/graphql/queries/alert_details.query.graphql index 8881f49b689..5ee2cf7ca44 100644 --- a/app/assets/javascripts/alert_management/graphql/queries/details.query.graphql +++ b/app/assets/javascripts/vue_shared/alert_details/graphql/queries/alert_details.query.graphql @@ -1,4 +1,4 @@ -#import "../fragments/detail_item.fragment.graphql" +#import "../fragments/alert_detail_item.fragment.graphql" query alertDetails($fullPath: ID!, $alertId: String) { project(fullPath: $fullPath) { diff --git a/app/assets/javascripts/alert_management/graphql/queries/sidebar_status.query.graphql b/app/assets/javascripts/vue_shared/alert_details/graphql/queries/alert_sidebar_status.query.graphql index 61c570c5cd0..61c570c5cd0 100644 --- a/app/assets/javascripts/alert_management/graphql/queries/sidebar_status.query.graphql +++ b/app/assets/javascripts/vue_shared/alert_details/graphql/queries/alert_sidebar_status.query.graphql diff --git a/app/assets/javascripts/alert_management/details.js b/app/assets/javascripts/vue_shared/alert_details/index.js index 4217b702d0a..643d6b3a3fe 100644 --- a/app/assets/javascripts/alert_management/details.js +++ b/app/assets/javascripts/vue_shared/alert_details/index.js @@ -4,14 +4,15 @@ import Vue from 'vue'; import VueApollo from 'vue-apollo'; import createDefaultClient from '~/lib/graphql'; import AlertDetails from './components/alert_details.vue'; -import sidebarStatusQuery from './graphql/queries/sidebar_status.query.graphql'; +import sidebarStatusQuery from './graphql/queries/alert_sidebar_status.query.graphql'; import createRouter from './router'; +import { DEFAULT_PAGE, PAGE_CONFIG } from './constants'; Vue.use(VueApollo); export default (selector) => { const domEl = document.querySelector(selector); - const { alertId, projectPath, projectIssuesPath, projectId } = domEl.dataset; + const { alertId, projectPath, projectIssuesPath, projectId, page = DEFAULT_PAGE } = domEl.dataset; const router = createRouter(); const resolvers = { @@ -48,18 +49,28 @@ export default (selector) => { }, }); + const provide = { + projectPath, + alertId, + projectIssuesPath, + projectId, + }; + + if (page === DEFAULT_PAGE) { + const { TRACK_ALERTS_DETAILS_VIEWS_OPTIONS, TRACK_ALERT_STATUS_UPDATE_OPTIONS } = PAGE_CONFIG[ + page + ]; + provide.trackAlertsDetailsViewsOptions = TRACK_ALERTS_DETAILS_VIEWS_OPTIONS; + provide.trackAlertStatusUpdateOptions = TRACK_ALERT_STATUS_UPDATE_OPTIONS; + } + // eslint-disable-next-line no-new new Vue({ el: selector, components: { AlertDetails, }, - provide: { - projectPath, - alertId, - projectIssuesPath, - projectId, - }, + provide, apolloProvider, router, render(createElement) { diff --git a/app/assets/javascripts/alert_management/router.js b/app/assets/javascripts/vue_shared/alert_details/router.js index 5687fe4e0f5..5687fe4e0f5 100644 --- a/app/assets/javascripts/alert_management/router.js +++ b/app/assets/javascripts/vue_shared/alert_details/router.js diff --git a/app/controllers/groups/dependency_proxy_for_containers_controller.rb b/app/controllers/groups/dependency_proxy_for_containers_controller.rb index 0f640397320..ff3c24a91a1 100644 --- a/app/controllers/groups/dependency_proxy_for_containers_controller.rb +++ b/app/controllers/groups/dependency_proxy_for_containers_controller.rb @@ -16,7 +16,12 @@ class Groups::DependencyProxyForContainersController < Groups::ApplicationContro result = DependencyProxy::FindOrCreateManifestService.new(group, image, tag, token).execute if result[:status] == :success - send_upload(result[:manifest].file) + response.headers['Docker-Content-Digest'] = result[:manifest].digest + response.headers['Content-Length'] = result[:manifest].size + response.headers['Docker-Distribution-Api-Version'] = DependencyProxy::DISTRIBUTION_API_VERSION + response.headers['Etag'] = "\"#{result[:manifest].digest}\"" + + send_upload(result[:manifest].file, send_params: { type: result[:manifest].content_type }) else render status: result[:http_status], json: result[:message] end diff --git a/app/controllers/projects/ci/prometheus_metrics/histograms_controller.rb b/app/controllers/projects/ci/prometheus_metrics/histograms_controller.rb new file mode 100644 index 00000000000..003441d4b91 --- /dev/null +++ b/app/controllers/projects/ci/prometheus_metrics/histograms_controller.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Projects + module Ci + module PrometheusMetrics + class HistogramsController < Projects::ApplicationController + feature_category :pipeline_authoring + + respond_to :json, only: [:create] + + def create + result = ::Ci::PrometheusMetrics::ObserveHistogramsService.new(project, permitted_params).execute + + render json: result.payload, status: result.http_status + end + + private + + def permitted_params + params.permit(histograms: [:name, :value]) + end + end + end + end +end diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 88f59484cdd..14e4f3e7dd8 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -41,7 +41,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo push_frontend_feature_flag(:core_security_mr_widget_counts, @project) push_frontend_feature_flag(:remove_resolve_note, @project, default_enabled: true) push_frontend_feature_flag(:diffs_gradual_load, @project, default_enabled: true) - push_frontend_feature_flag(:codequality_mr_diff, @project) + push_frontend_feature_flag(:codequality_backend_comparison, @project, default_enabled: :yaml) push_frontend_feature_flag(:suggestions_custom_commit, @project) push_frontend_feature_flag(:local_file_reviews, default_enabled: :yaml) push_frontend_feature_flag(:paginated_notes, @project, default_enabled: :yaml) diff --git a/app/graphql/types/milestone_state_enum.rb b/app/graphql/types/milestone_state_enum.rb index 588fcb8883a..e3b60395c9b 100644 --- a/app/graphql/types/milestone_state_enum.rb +++ b/app/graphql/types/milestone_state_enum.rb @@ -5,7 +5,7 @@ module Types graphql_name 'MilestoneStateEnum' description 'Current state of milestone' - value 'active', 'Milestone is currently active' - value 'closed', 'Milestone is closed' + value 'active', description: 'Milestone is currently active' + value 'closed', description: 'Milestone is closed' end end diff --git a/app/models/dependency_proxy.rb b/app/models/dependency_proxy.rb index 9cbaf7e9884..0ed17921aaa 100644 --- a/app/models/dependency_proxy.rb +++ b/app/models/dependency_proxy.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true module DependencyProxy URL_SUFFIX = '/dependency_proxy/containers' + DISTRIBUTION_API_VERSION = 'registry/2.0' def self.table_name_prefix 'dependency_proxy_' diff --git a/app/models/dependency_proxy/manifest.rb b/app/models/dependency_proxy/manifest.rb index f3c7f34e0d7..d613d5708f0 100644 --- a/app/models/dependency_proxy/manifest.rb +++ b/app/models/dependency_proxy/manifest.rb @@ -12,5 +12,10 @@ class DependencyProxy::Manifest < ApplicationRecord mount_file_store_uploader DependencyProxy::FileUploader - scope :find_or_initialize_by_file_name, ->(file_name) { find_or_initialize_by(file_name: file_name) } + def self.find_or_initialize_by_file_name_or_digest(file_name:, digest:) + result = find_by(file_name: file_name) || find_by(digest: digest) + return result if result + + new(file_name: file_name, digest: digest) + end end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 17645a35af4..73418270a34 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -1503,7 +1503,7 @@ class MergeRequest < ApplicationRecord end def has_codequality_reports? - return false unless ::Gitlab::Ci::Features.display_quality_on_mr_diff?(project) + return false unless ::Gitlab::Ci::Features.display_codequality_backend_comparison?(project) actual_head_pipeline&.has_reports?(Ci::JobArtifact.codequality_reports) end diff --git a/app/models/user.rb b/app/models/user.rb index b4ec6064ff8..4a2ca64fbe9 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -960,8 +960,8 @@ class User < ApplicationRecord end # rubocop: disable CodeReuse/ServiceClass - def refresh_authorized_projects - Users::RefreshAuthorizedProjectsService.new(self).execute + def refresh_authorized_projects(source: nil) + Users::RefreshAuthorizedProjectsService.new(self, source: source).execute end # rubocop: enable CodeReuse/ServiceClass diff --git a/app/services/authorized_project_update/recalculate_for_user_range_service.rb b/app/services/authorized_project_update/recalculate_for_user_range_service.rb index 14b0f5d6117..f300c45f019 100644 --- a/app/services/authorized_project_update/recalculate_for_user_range_service.rb +++ b/app/services/authorized_project_update/recalculate_for_user_range_service.rb @@ -9,7 +9,7 @@ module AuthorizedProjectUpdate def execute User.where(id: start_user_id..end_user_id).select(:id).find_each do |user| # rubocop: disable CodeReuse/ActiveRecord - Users::RefreshAuthorizedProjectsService.new(user).execute + Users::RefreshAuthorizedProjectsService.new(user, source: self.class.name).execute end end diff --git a/app/services/ci/process_pipeline_service.rb b/app/services/ci/process_pipeline_service.rb index e511e26adfe..678b386fbbf 100644 --- a/app/services/ci/process_pipeline_service.rb +++ b/app/services/ci/process_pipeline_service.rb @@ -38,10 +38,15 @@ module Ci # mark builds that are retried if latest_statuses.any? - pipeline.latest_statuses - .where(name: latest_statuses.map(&:second)) - .where.not(id: latest_statuses.map(&:first)) - .update_all(retried: true) + updated_count = pipeline.latest_statuses + .where(name: latest_statuses.map(&:second)) + .where.not(id: latest_statuses.map(&:first)) + .update_all(retried: true) + + # This counter is temporary. It will be used to check whether if we still use this method or not + # after setting correct value of `GenericCommitStatus#retried`. + # More info: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50465#note_491657115 + metrics.legacy_update_jobs_counter.increment if updated_count > 0 end end # rubocop: enable CodeReuse/ActiveRecord diff --git a/app/services/ci/prometheus_metrics/observe_histograms_service.rb b/app/services/ci/prometheus_metrics/observe_histograms_service.rb new file mode 100644 index 00000000000..ee22ea75df9 --- /dev/null +++ b/app/services/ci/prometheus_metrics/observe_histograms_service.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +module Ci + module PrometheusMetrics + class ObserveHistogramsService + class << self + def available_histograms + @available_histograms ||= [ + histogram(:pipeline_graph_link_calculation_duration_seconds, 'Total time spent calculating links, in seconds', {}, [0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.8, 1, 2]), + histogram(:pipeline_graph_links_total, 'Number of links per graph', {}, [1, 5, 10, 25, 50, 100, 200]), + histogram(:pipeline_graph_links_per_job_ratio, 'Ratio of links to job per graph', {}, [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]) + ].to_h + end + + private + + def histogram(name, *attrs) + [name.to_s, proc { Gitlab::Metrics.histogram(name, *attrs) }] + end + end + + def initialize(project, params) + @project = project + @params = params + end + + def execute + return ServiceResponse.success(http_status: :accepted) unless enabled? + + params + .fetch(:histograms, []) + .each(&method(:observe)) + + ServiceResponse.success(http_status: :created) + end + + private + + attr_reader :project, :params + + def observe(data) + histogram = find_histogram(data[:name]) + histogram.observe({ project: project.full_path }, data[:value].to_f) + end + + def find_histogram(name) + self.class.available_histograms + .fetch(name) { raise ActiveRecord::RecordNotFound } + .call + end + + def enabled? + ::Feature.enabled?(:ci_accept_frontend_prometheus_metrics, project, default_enabled: :yaml) + end + end + end +end diff --git a/app/services/dependency_proxy/find_or_create_manifest_service.rb b/app/services/dependency_proxy/find_or_create_manifest_service.rb index 6b46f5e4c59..ee608d715aa 100644 --- a/app/services/dependency_proxy/find_or_create_manifest_service.rb +++ b/app/services/dependency_proxy/find_or_create_manifest_service.rb @@ -13,7 +13,7 @@ module DependencyProxy def execute @manifest = @group.dependency_proxy_manifests - .find_or_initialize_by_file_name(@file_name) + .find_or_initialize_by_file_name_or_digest(file_name: @file_name, digest: @tag) head_result = DependencyProxy::HeadManifestService.new(@image, @tag, @token).execute @@ -30,6 +30,7 @@ module DependencyProxy def pull_new_manifest DependencyProxy::PullManifestService.new(@image, @tag, @token).execute_with_manifest do |new_manifest| @manifest.update!( + content_type: new_manifest[:content_type], digest: new_manifest[:digest], file: new_manifest[:file], size: new_manifest[:file].size @@ -38,7 +39,9 @@ module DependencyProxy end def cached_manifest_matches?(head_result) - @manifest && @manifest.digest == head_result[:digest] + return false if head_result[:status] == :error + + @manifest && @manifest.digest == head_result[:digest] && @manifest.content_type == head_result[:content_type] end def respond diff --git a/app/services/dependency_proxy/head_manifest_service.rb b/app/services/dependency_proxy/head_manifest_service.rb index 87d9c417c98..ecc3eb77399 100644 --- a/app/services/dependency_proxy/head_manifest_service.rb +++ b/app/services/dependency_proxy/head_manifest_service.rb @@ -2,6 +2,8 @@ module DependencyProxy class HeadManifestService < DependencyProxy::BaseService + ACCEPT_HEADERS = ::ContainerRegistry::Client::ACCEPTED_TYPES.join(',') + def initialize(image, tag, token) @image = image @tag = tag @@ -9,10 +11,10 @@ module DependencyProxy end def execute - response = Gitlab::HTTP.head(manifest_url, headers: auth_headers) + response = Gitlab::HTTP.head(manifest_url, headers: auth_headers.merge(Accept: ACCEPT_HEADERS)) if response.success? - success(digest: response.headers['docker-content-digest']) + success(digest: response.headers['docker-content-digest'], content_type: response.headers['content-type']) else error(response.body, response.code) end diff --git a/app/services/dependency_proxy/pull_manifest_service.rb b/app/services/dependency_proxy/pull_manifest_service.rb index 5c804489fd1..737414c396e 100644 --- a/app/services/dependency_proxy/pull_manifest_service.rb +++ b/app/services/dependency_proxy/pull_manifest_service.rb @@ -11,7 +11,7 @@ module DependencyProxy def execute_with_manifest raise ArgumentError, 'Block must be provided' unless block_given? - response = Gitlab::HTTP.get(manifest_url, headers: auth_headers) + response = Gitlab::HTTP.get(manifest_url, headers: auth_headers.merge(Accept: ::ContainerRegistry::Client::ACCEPTED_TYPES.join(','))) if response.success? file = Tempfile.new @@ -20,7 +20,7 @@ module DependencyProxy file.write(response) file.flush - yield(success(file: file, digest: response.headers['docker-content-digest'])) + yield(success(file: file, digest: response.headers['docker-content-digest'], content_type: response.headers['content-type'])) ensure file.close file.unlink diff --git a/app/services/issue_rebalancing_service.rb b/app/services/issue_rebalancing_service.rb index 4138c6441c8..849afc4edb8 100644 --- a/app/services/issue_rebalancing_service.rb +++ b/app/services/issue_rebalancing_service.rb @@ -17,8 +17,21 @@ class IssueRebalancingService start = RelativePositioning::START_POSITION - (gaps / 2) * gap_size - Issue.transaction do - indexed_ids.each_slice(100) { |pairs| assign_positions(start, pairs) } + if Feature.enabled?(:issue_rebalancing_optimization) + Issue.transaction do + assign_positions(start, indexed_ids) + .sort_by(&:first) + .each_slice(100) do |pairs_with_position| + update_positions(pairs_with_position, 'rebalance issue positions in batches ordered by id') + end + end + else + Issue.transaction do + indexed_ids.each_slice(100) do |pairs| + pairs_with_position = assign_positions(start, pairs) + update_positions(pairs_with_position, 'rebalance issue positions') + end + end end end @@ -32,13 +45,22 @@ class IssueRebalancingService end # rubocop: enable CodeReuse/ActiveRecord - # rubocop: disable CodeReuse/ActiveRecord - def assign_positions(start, positions) - values = positions.map do |id, index| - "(#{id}, #{start + (index * gap_size)})" + def assign_positions(start, pairs) + pairs.map do |id, index| + [id, start + (index * gap_size)] + end + end + + def update_positions(pairs_with_position, query_name) + values = pairs_with_position.map do |id, index| + "(#{id}, #{index})" end.join(', ') - Issue.connection.exec_query(<<~SQL, "rebalance issue positions") + run_update_query(values, query_name) + end + + def run_update_query(values, query_name) + Issue.connection.exec_query(<<~SQL, query_name) WITH cte(cte_id, new_pos) AS ( SELECT * FROM (VALUES #{values}) as t (id, pos) @@ -49,7 +71,6 @@ class IssueRebalancingService WHERE cte_id = id SQL end - # rubocop: enable CodeReuse/ActiveRecord def issue_count @issue_count ||= base.count diff --git a/app/services/users/refresh_authorized_projects_service.rb b/app/services/users/refresh_authorized_projects_service.rb index d0939d5a542..24e3fb73370 100644 --- a/app/services/users/refresh_authorized_projects_service.rb +++ b/app/services/users/refresh_authorized_projects_service.rb @@ -14,13 +14,14 @@ module Users # service = Users::RefreshAuthorizedProjectsService.new(some_user) # service.execute class RefreshAuthorizedProjectsService - attr_reader :user + attr_reader :user, :source LEASE_TIMEOUT = 1.minute.to_i # user - The User for which to refresh the authorized projects. - def initialize(user, incorrect_auth_found_callback: nil, missing_auth_found_callback: nil) + def initialize(user, source: nil, incorrect_auth_found_callback: nil, missing_auth_found_callback: nil) @user = user + @source = source @incorrect_auth_found_callback = incorrect_auth_found_callback @missing_auth_found_callback = missing_auth_found_callback @@ -91,6 +92,8 @@ module Users # remove - The IDs of the authorization rows to remove. # add - Rows to insert in the form `[user id, project id, access level]` def update_authorizations(remove = [], add = []) + log_refresh_details(remove.length, add.length) + User.transaction do user.remove_project_authorizations(remove) unless remove.empty? ProjectAuthorization.insert_authorizations(add) unless add.empty? @@ -101,6 +104,13 @@ module Users user.reset end + def log_refresh_details(rows_deleted, rows_added) + Gitlab::AppJsonLogger.info(event: 'authorized_projects_refresh', + 'authorized_projects_refresh.source': source, + 'authorized_projects_refresh.rows_deleted': rows_deleted, + 'authorized_projects_refresh.rows_added': rows_added) + end + def fresh_access_levels_per_project fresh_authorizations.each_with_object({}) do |row, hash| hash[row.project_id] = row.access_level diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml index a14f75259ec..802df664241 100644 --- a/app/views/projects/commits/show.html.haml +++ b/app/views/projects/commits/show.html.haml @@ -24,9 +24,9 @@ .control = form_tag(project_commits_path(@project, @id), method: :get, class: 'commits-search-form js-signature-container', data: { 'signatures-path' => namespace_project_signatures_path }) do - = search_field_tag :search, params[:search], { placeholder: _('Search by message'), id: 'commits-search', class: 'form-control gl-form-input input-short gl-mt-3 gl-sm-mt-0 gl-min-w-full gl-inset-border-1-gray-200!', spellcheck: false } + = search_field_tag :search, params[:search], { placeholder: _('Search by message'), id: 'commits-search', class: 'form-control gl-form-input input-short gl-mt-3 gl-sm-mt-0 gl-min-w-full', spellcheck: false } .control.d-none.d-md-block - = link_to project_commits_path(@project, @ref, rss_url_options), title: _("Commits feed"), class: 'btn gl-button btn-svg' do + = link_to project_commits_path(@project, @ref, rss_url_options), title: _("Commits feed"), class: 'btn gl-button btn-default btn-icon' do = sprite_icon('rss', css_class: 'qa-rss-icon') = render_if_exists 'projects/commits/mirror_status' diff --git a/app/workers/authorized_projects_worker.rb b/app/workers/authorized_projects_worker.rb index f5132459131..6e07d6d0f71 100644 --- a/app/workers/authorized_projects_worker.rb +++ b/app/workers/authorized_projects_worker.rb @@ -25,7 +25,7 @@ class AuthorizedProjectsWorker def perform(user_id) user = User.find_by(id: user_id) - user&.refresh_authorized_projects + user&.refresh_authorized_projects(source: self.class.name) end # rubocop: enable CodeReuse/ActiveRecord end |