From 7c221ba5ce130ca50b892e6dd32783e1327718df Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 4 Feb 2021 18:09:22 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .../alert_management/components/alert_details.vue | 380 -------------------- .../components/alert_management_table.vue | 10 +- .../alert_management/components/alert_metrics.vue | 56 --- .../alert_management/components/alert_sidebar.vue | 81 ----- .../alert_management/components/alert_status.vue | 119 ------- .../components/alert_summary_row.vue | 18 - .../components/sidebar/sidebar_assignee.vue | 38 -- .../components/sidebar/sidebar_assignees.vue | 299 ---------------- .../components/sidebar/sidebar_header.vue | 41 --- .../components/sidebar/sidebar_status.vue | 120 ------- .../components/sidebar/sidebar_todo.vue | 149 -------- .../components/system_notes/system_note.vue | 48 --- .../javascripts/alert_management/constants.js | 31 +- app/assets/javascripts/alert_management/details.js | 69 ---- .../graphql/fragments/detail_item.fragment.graphql | 30 -- .../mutations/alert_set_assignees.mutation.graphql | 25 -- .../mutations/alert_todo_create.mutation.graphql | 10 - .../create_issue_from_alert.mutation.graphql | 8 - .../toggle_sidebar_status.mutation.graphql | 3 - .../graphql/queries/details.query.graphql | 11 - .../graphql/queries/sidebar_status.query.graphql | 3 - app/assets/javascripts/alert_management/list.js | 2 + app/assets/javascripts/alert_management/router.js | 13 - .../fragments/alert_note.fragment.graphql | 2 +- .../mutations/alert_status_update.mutation.graphql | 17 + .../mutations/update_alert_status.mutation.graphql | 17 - .../projects/alert_management/details/index.js | 2 +- .../components/graph/stage_column_component.vue | 15 +- .../grouped_codequality_reports_app.vue | 2 +- .../alert_details/components/alert_details.vue | 385 +++++++++++++++++++++ .../alert_details/components/alert_metrics.vue | 56 +++ .../alert_details/components/alert_sidebar.vue | 81 +++++ .../alert_details/components/alert_status.vue | 125 +++++++ .../alert_details/components/alert_summary_row.vue | 18 + .../components/sidebar/sidebar_assignee.vue | 38 ++ .../components/sidebar/sidebar_assignees.vue | 299 ++++++++++++++++ .../components/sidebar/sidebar_header.vue | 41 +++ .../components/sidebar/sidebar_status.vue | 120 +++++++ .../components/sidebar/sidebar_todo.vue | 149 ++++++++ .../components/system_notes/system_note.vue | 48 +++ .../vue_shared/alert_details/constants.js | 29 ++ .../fragments/alert_detail_item.fragment.graphql | 30 ++ .../mutations/alert_issue_create.mutation.graphql | 8 + .../mutations/alert_set_assignees.mutation.graphql | 25 ++ .../alert_sidebar_status.mutation.graphql | 3 + .../mutations/alert_todo_create.mutation.graphql | 10 + .../graphql/queries/alert_details.query.graphql | 11 + .../queries/alert_sidebar_status.query.graphql | 3 + .../javascripts/vue_shared/alert_details/index.js | 80 +++++ .../javascripts/vue_shared/alert_details/router.js | 13 + .../dependency_proxy_for_containers_controller.rb | 7 +- .../ci/prometheus_metrics/histograms_controller.rb | 25 ++ .../projects/merge_requests_controller.rb | 2 +- app/graphql/types/milestone_state_enum.rb | 4 +- app/models/dependency_proxy.rb | 1 + app/models/dependency_proxy/manifest.rb | 7 +- app/models/merge_request.rb | 2 +- app/models/user.rb | 4 +- .../recalculate_for_user_range_service.rb | 2 +- app/services/ci/process_pipeline_service.rb | 13 +- .../observe_histograms_service.rb | 57 +++ .../find_or_create_manifest_service.rb | 7 +- .../dependency_proxy/head_manifest_service.rb | 6 +- .../dependency_proxy/pull_manifest_service.rb | 4 +- app/services/issue_rebalancing_service.rb | 37 +- .../users/refresh_authorized_projects_service.rb | 14 +- app/views/projects/commits/show.html.haml | 4 +- app/workers/authorized_projects_worker.rb | 2 +- 68 files changed, 1774 insertions(+), 1615 deletions(-) delete mode 100644 app/assets/javascripts/alert_management/components/alert_details.vue delete mode 100644 app/assets/javascripts/alert_management/components/alert_metrics.vue delete mode 100644 app/assets/javascripts/alert_management/components/alert_sidebar.vue delete mode 100644 app/assets/javascripts/alert_management/components/alert_status.vue delete mode 100644 app/assets/javascripts/alert_management/components/alert_summary_row.vue delete mode 100644 app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue delete mode 100644 app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue delete mode 100644 app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue delete mode 100644 app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue delete mode 100644 app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue delete mode 100644 app/assets/javascripts/alert_management/components/system_notes/system_note.vue delete mode 100644 app/assets/javascripts/alert_management/details.js delete mode 100644 app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql delete mode 100644 app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.mutation.graphql delete mode 100644 app/assets/javascripts/alert_management/graphql/mutations/alert_todo_create.mutation.graphql delete mode 100644 app/assets/javascripts/alert_management/graphql/mutations/create_issue_from_alert.mutation.graphql delete mode 100644 app/assets/javascripts/alert_management/graphql/mutations/toggle_sidebar_status.mutation.graphql delete mode 100644 app/assets/javascripts/alert_management/graphql/queries/details.query.graphql delete mode 100644 app/assets/javascripts/alert_management/graphql/queries/sidebar_status.query.graphql delete mode 100644 app/assets/javascripts/alert_management/router.js create mode 100644 app/assets/javascripts/graphql_shared/mutations/alert_status_update.mutation.graphql delete mode 100644 app/assets/javascripts/graphql_shared/mutations/update_alert_status.mutation.graphql create mode 100644 app/assets/javascripts/vue_shared/alert_details/components/alert_details.vue create mode 100644 app/assets/javascripts/vue_shared/alert_details/components/alert_metrics.vue create mode 100644 app/assets/javascripts/vue_shared/alert_details/components/alert_sidebar.vue create mode 100644 app/assets/javascripts/vue_shared/alert_details/components/alert_status.vue create mode 100644 app/assets/javascripts/vue_shared/alert_details/components/alert_summary_row.vue create mode 100644 app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignee.vue create mode 100644 app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignees.vue create mode 100644 app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_header.vue create mode 100644 app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_status.vue create mode 100644 app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_todo.vue create mode 100644 app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue create mode 100644 app/assets/javascripts/vue_shared/alert_details/constants.js create mode 100644 app/assets/javascripts/vue_shared/alert_details/graphql/fragments/alert_detail_item.fragment.graphql create mode 100644 app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_issue_create.mutation.graphql create mode 100644 app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_set_assignees.mutation.graphql create mode 100644 app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_sidebar_status.mutation.graphql create mode 100644 app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_todo_create.mutation.graphql create mode 100644 app/assets/javascripts/vue_shared/alert_details/graphql/queries/alert_details.query.graphql create mode 100644 app/assets/javascripts/vue_shared/alert_details/graphql/queries/alert_sidebar_status.query.graphql create mode 100644 app/assets/javascripts/vue_shared/alert_details/index.js create mode 100644 app/assets/javascripts/vue_shared/alert_details/router.js create mode 100644 app/controllers/projects/ci/prometheus_metrics/histograms_controller.rb create mode 100644 app/services/ci/prometheus_metrics/observe_histograms_service.rb (limited to 'app') diff --git a/app/assets/javascripts/alert_management/components/alert_details.vue b/app/assets/javascripts/alert_management/components/alert_details.vue deleted file mode 100644 index 5da4cae2439..00000000000 --- a/app/assets/javascripts/alert_management/components/alert_details.vue +++ /dev/null @@ -1,380 +0,0 @@ - - - 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/components/alert_metrics.vue b/app/assets/javascripts/alert_management/components/alert_metrics.vue deleted file mode 100644 index dd4faa03c00..00000000000 --- a/app/assets/javascripts/alert_management/components/alert_metrics.vue +++ /dev/null @@ -1,56 +0,0 @@ - - - diff --git a/app/assets/javascripts/alert_management/components/alert_sidebar.vue b/app/assets/javascripts/alert_management/components/alert_sidebar.vue deleted file mode 100644 index aa98e34d424..00000000000 --- a/app/assets/javascripts/alert_management/components/alert_sidebar.vue +++ /dev/null @@ -1,81 +0,0 @@ - - - diff --git a/app/assets/javascripts/alert_management/components/alert_status.vue b/app/assets/javascripts/alert_management/components/alert_status.vue deleted file mode 100644 index 3d46ce07b53..00000000000 --- a/app/assets/javascripts/alert_management/components/alert_status.vue +++ /dev/null @@ -1,119 +0,0 @@ - - - diff --git a/app/assets/javascripts/alert_management/components/alert_summary_row.vue b/app/assets/javascripts/alert_management/components/alert_summary_row.vue deleted file mode 100644 index 13835b7e2fa..00000000000 --- a/app/assets/javascripts/alert_management/components/alert_summary_row.vue +++ /dev/null @@ -1,18 +0,0 @@ - - diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue deleted file mode 100644 index c39a72a45b9..00000000000 --- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue +++ /dev/null @@ -1,38 +0,0 @@ - - - diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue deleted file mode 100644 index 2a999b908f9..00000000000 --- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue +++ /dev/null @@ -1,299 +0,0 @@ - - - diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue deleted file mode 100644 index fd40b5d9f65..00000000000 --- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue deleted file mode 100644 index 0a2bad5510b..00000000000 --- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue +++ /dev/null @@ -1,120 +0,0 @@ - - - diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue deleted file mode 100644 index 34d34f3d232..00000000000 --- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue +++ /dev/null @@ -1,149 +0,0 @@ - - - diff --git a/app/assets/javascripts/alert_management/components/system_notes/system_note.vue b/app/assets/javascripts/alert_management/components/system_notes/system_note.vue deleted file mode 100644 index 3705e36a579..00000000000 --- a/app/assets/javascripts/alert_management/components/system_notes/system_note.vue +++ /dev/null @@ -1,48 +0,0 @@ - - - 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/details.js b/app/assets/javascripts/alert_management/details.js deleted file mode 100644 index 4217b702d0a..00000000000 --- a/app/assets/javascripts/alert_management/details.js +++ /dev/null @@ -1,69 +0,0 @@ -import { defaultDataIdFromObject } from 'apollo-cache-inmemory'; -import produce from 'immer'; -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 createRouter from './router'; - -Vue.use(VueApollo); - -export default (selector) => { - const domEl = document.querySelector(selector); - const { alertId, projectPath, projectIssuesPath, projectId } = domEl.dataset; - const router = createRouter(); - - const resolvers = { - Mutation: { - toggleSidebarStatus: (_, __, { cache }) => { - const sourceData = cache.readQuery({ query: sidebarStatusQuery }); - const data = produce(sourceData, (draftData) => { - // eslint-disable-next-line no-param-reassign - draftData.sidebarStatus = !draftData.sidebarStatus; - }); - cache.writeQuery({ query: sidebarStatusQuery, data }); - }, - }, - }; - - const apolloProvider = new VueApollo({ - defaultClient: createDefaultClient(resolvers, { - cacheConfig: { - dataIdFromObject: (object) => { - // eslint-disable-next-line no-underscore-dangle - if (object.__typename === 'AlertManagementAlert') { - return object.iid; - } - return defaultDataIdFromObject(object); - }, - }, - assumeImmutableResults: true, - }), - }); - - apolloProvider.clients.defaultClient.cache.writeData({ - data: { - sidebarStatus: false, - }, - }); - - // eslint-disable-next-line no-new - new Vue({ - el: selector, - components: { - AlertDetails, - }, - provide: { - projectPath, - alertId, - projectIssuesPath, - projectId, - }, - apolloProvider, - router, - render(createElement) { - return createElement('alert-details', {}); - }, - }); -}; diff --git a/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql b/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql deleted file mode 100644 index 9a9ae369519..00000000000 --- a/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql +++ /dev/null @@ -1,30 +0,0 @@ -#import "~/graphql_shared/fragments/alert.fragment.graphql" -#import "~/graphql_shared/fragments/alert_note.fragment.graphql" - -fragment AlertDetailItem on AlertManagementAlert { - ...AlertListItem - createdAt - monitoringTool - metricsDashboardUrl - service - description - updatedAt - endedAt - hosts - environment { - name - path - } - details - runbook - todos { - nodes { - id - } - } - notes { - nodes { - ...AlertNote - } - } -} diff --git a/app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.mutation.graphql b/app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.mutation.graphql deleted file mode 100644 index 63d952a4857..00000000000 --- a/app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.mutation.graphql +++ /dev/null @@ -1,25 +0,0 @@ -#import "~/graphql_shared/fragments/alert_note.fragment.graphql" - -mutation alertSetAssignees($projectPath: ID!, $assigneeUsernames: [String!]!, $iid: String!) { - alertSetAssignees( - input: { iid: $iid, assigneeUsernames: $assigneeUsernames, projectPath: $projectPath } - ) { - errors - alert { - iid - assignees { - nodes { - username - name - avatarUrl - webUrl - } - } - notes { - nodes { - ...AlertNote - } - } - } - } -} diff --git a/app/assets/javascripts/alert_management/graphql/mutations/alert_todo_create.mutation.graphql b/app/assets/javascripts/alert_management/graphql/mutations/alert_todo_create.mutation.graphql deleted file mode 100644 index ac9858c104f..00000000000 --- a/app/assets/javascripts/alert_management/graphql/mutations/alert_todo_create.mutation.graphql +++ /dev/null @@ -1,10 +0,0 @@ -#import "../fragments/detail_item.fragment.graphql" - -mutation alertTodoCreate($projectPath: ID!, $iid: String!) { - alertTodoCreate(input: { iid: $iid, projectPath: $projectPath }) { - errors - alert { - ...AlertDetailItem - } - } -} diff --git a/app/assets/javascripts/alert_management/graphql/mutations/create_issue_from_alert.mutation.graphql b/app/assets/javascripts/alert_management/graphql/mutations/create_issue_from_alert.mutation.graphql deleted file mode 100644 index bc4d91a51d1..00000000000 --- a/app/assets/javascripts/alert_management/graphql/mutations/create_issue_from_alert.mutation.graphql +++ /dev/null @@ -1,8 +0,0 @@ -mutation createAlertIssue($projectPath: ID!, $iid: String!) { - createAlertIssue(input: { iid: $iid, projectPath: $projectPath }) { - errors - issue { - iid - } - } -} diff --git a/app/assets/javascripts/alert_management/graphql/mutations/toggle_sidebar_status.mutation.graphql b/app/assets/javascripts/alert_management/graphql/mutations/toggle_sidebar_status.mutation.graphql deleted file mode 100644 index f666fcd6782..00000000000 --- a/app/assets/javascripts/alert_management/graphql/mutations/toggle_sidebar_status.mutation.graphql +++ /dev/null @@ -1,3 +0,0 @@ -mutation toggleSidebarStatus { - toggleSidebarStatus @client -} diff --git a/app/assets/javascripts/alert_management/graphql/queries/details.query.graphql b/app/assets/javascripts/alert_management/graphql/queries/details.query.graphql deleted file mode 100644 index 8881f49b689..00000000000 --- a/app/assets/javascripts/alert_management/graphql/queries/details.query.graphql +++ /dev/null @@ -1,11 +0,0 @@ -#import "../fragments/detail_item.fragment.graphql" - -query alertDetails($fullPath: ID!, $alertId: String) { - project(fullPath: $fullPath) { - alertManagementAlerts(iid: $alertId) { - nodes { - ...AlertDetailItem - } - } - } -} diff --git a/app/assets/javascripts/alert_management/graphql/queries/sidebar_status.query.graphql b/app/assets/javascripts/alert_management/graphql/queries/sidebar_status.query.graphql deleted file mode 100644 index 61c570c5cd0..00000000000 --- a/app/assets/javascripts/alert_management/graphql/queries/sidebar_status.query.graphql +++ /dev/null @@ -1,3 +0,0 @@ -query sidebarStatus { - sidebarStatus @client -} 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/alert_management/router.js b/app/assets/javascripts/alert_management/router.js deleted file mode 100644 index 5687fe4e0f5..00000000000 --- a/app/assets/javascripts/alert_management/router.js +++ /dev/null @@ -1,13 +0,0 @@ -import Vue from 'vue'; -import VueRouter from 'vue-router'; -import { joinPaths } from '~/lib/utils/url_utility'; - -Vue.use(VueRouter); - -export default function createRouter(base) { - return new VueRouter({ - mode: 'hash', - base: joinPaths(gon.relative_url_root || '', base), - routes: [{ path: '/:tabId', name: 'tab' }], - }); -} 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/alert_status_update.mutation.graphql b/app/assets/javascripts/graphql_shared/mutations/alert_status_update.mutation.graphql new file mode 100644 index 00000000000..ba1e607bc10 --- /dev/null +++ b/app/assets/javascripts/graphql_shared/mutations/alert_status_update.mutation.graphql @@ -0,0 +1,17 @@ +#import "../fragments/alert_note.fragment.graphql" + +mutation updateAlertStatus($projectPath: ID!, $status: AlertManagementStatus!, $iid: String!) { + updateAlertStatus(input: { iid: $iid, status: $status, projectPath: $projectPath }) { + errors + alert { + iid + status + endedAt + notes { + nodes { + ...AlertNote + } + } + } + } +} diff --git a/app/assets/javascripts/graphql_shared/mutations/update_alert_status.mutation.graphql b/app/assets/javascripts/graphql_shared/mutations/update_alert_status.mutation.graphql deleted file mode 100644 index 42dc388c9d1..00000000000 --- a/app/assets/javascripts/graphql_shared/mutations/update_alert_status.mutation.graphql +++ /dev/null @@ -1,17 +0,0 @@ -#import "~/graphql_shared/fragments/alert_note.fragment.graphql" - -mutation updateAlertStatus($projectPath: ID!, $status: AlertManagementStatus!, $iid: String!) { - updateAlertStatus(input: { iid: $iid, status: $status, projectPath: $projectPath }) { - errors - alert { - iid - status - endedAt - notes { - nodes { - ...AlertNote - } - } - } - } -} 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')" /> - +
+ +
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/vue_shared/alert_details/components/alert_details.vue b/app/assets/javascripts/vue_shared/alert_details/components/alert_details.vue new file mode 100644 index 00000000000..673c6f4a1eb --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/components/alert_details.vue @@ -0,0 +1,385 @@ + + + diff --git a/app/assets/javascripts/vue_shared/alert_details/components/alert_metrics.vue b/app/assets/javascripts/vue_shared/alert_details/components/alert_metrics.vue new file mode 100644 index 00000000000..dd4faa03c00 --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/components/alert_metrics.vue @@ -0,0 +1,56 @@ + + + diff --git a/app/assets/javascripts/vue_shared/alert_details/components/alert_sidebar.vue b/app/assets/javascripts/vue_shared/alert_details/components/alert_sidebar.vue new file mode 100644 index 00000000000..12c58b582c5 --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/components/alert_sidebar.vue @@ -0,0 +1,81 @@ + + + diff --git a/app/assets/javascripts/vue_shared/alert_details/components/alert_status.vue b/app/assets/javascripts/vue_shared/alert_details/components/alert_status.vue new file mode 100644 index 00000000000..5520f7ff045 --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/components/alert_status.vue @@ -0,0 +1,125 @@ + + + diff --git a/app/assets/javascripts/vue_shared/alert_details/components/alert_summary_row.vue b/app/assets/javascripts/vue_shared/alert_details/components/alert_summary_row.vue new file mode 100644 index 00000000000..13835b7e2fa --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/components/alert_summary_row.vue @@ -0,0 +1,18 @@ + + diff --git a/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignee.vue b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignee.vue new file mode 100644 index 00000000000..c39a72a45b9 --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignee.vue @@ -0,0 +1,38 @@ + + + diff --git a/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignees.vue b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignees.vue new file mode 100644 index 00000000000..2a999b908f9 --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignees.vue @@ -0,0 +1,299 @@ + + + diff --git a/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_header.vue b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_header.vue new file mode 100644 index 00000000000..fd40b5d9f65 --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_header.vue @@ -0,0 +1,41 @@ + + + diff --git a/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_status.vue b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_status.vue new file mode 100644 index 00000000000..0a2bad5510b --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_status.vue @@ -0,0 +1,120 @@ + + + diff --git a/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_todo.vue b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_todo.vue new file mode 100644 index 00000000000..216b429fcbe --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_todo.vue @@ -0,0 +1,149 @@ + + + diff --git a/app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue b/app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue new file mode 100644 index 00000000000..3705e36a579 --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue @@ -0,0 +1,48 @@ + + + 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/vue_shared/alert_details/graphql/fragments/alert_detail_item.fragment.graphql b/app/assets/javascripts/vue_shared/alert_details/graphql/fragments/alert_detail_item.fragment.graphql new file mode 100644 index 00000000000..9a9ae369519 --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/graphql/fragments/alert_detail_item.fragment.graphql @@ -0,0 +1,30 @@ +#import "~/graphql_shared/fragments/alert.fragment.graphql" +#import "~/graphql_shared/fragments/alert_note.fragment.graphql" + +fragment AlertDetailItem on AlertManagementAlert { + ...AlertListItem + createdAt + monitoringTool + metricsDashboardUrl + service + description + updatedAt + endedAt + hosts + environment { + name + path + } + details + runbook + todos { + nodes { + id + } + } + notes { + nodes { + ...AlertNote + } + } +} diff --git a/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_issue_create.mutation.graphql b/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_issue_create.mutation.graphql new file mode 100644 index 00000000000..bc4d91a51d1 --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_issue_create.mutation.graphql @@ -0,0 +1,8 @@ +mutation createAlertIssue($projectPath: ID!, $iid: String!) { + createAlertIssue(input: { iid: $iid, projectPath: $projectPath }) { + errors + issue { + iid + } + } +} diff --git a/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_set_assignees.mutation.graphql b/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_set_assignees.mutation.graphql new file mode 100644 index 00000000000..63d952a4857 --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_set_assignees.mutation.graphql @@ -0,0 +1,25 @@ +#import "~/graphql_shared/fragments/alert_note.fragment.graphql" + +mutation alertSetAssignees($projectPath: ID!, $assigneeUsernames: [String!]!, $iid: String!) { + alertSetAssignees( + input: { iid: $iid, assigneeUsernames: $assigneeUsernames, projectPath: $projectPath } + ) { + errors + alert { + iid + assignees { + nodes { + username + name + avatarUrl + webUrl + } + } + notes { + nodes { + ...AlertNote + } + } + } + } +} diff --git a/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_sidebar_status.mutation.graphql b/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_sidebar_status.mutation.graphql new file mode 100644 index 00000000000..f666fcd6782 --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_sidebar_status.mutation.graphql @@ -0,0 +1,3 @@ +mutation toggleSidebarStatus { + toggleSidebarStatus @client +} diff --git a/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_todo_create.mutation.graphql b/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_todo_create.mutation.graphql new file mode 100644 index 00000000000..dc961b5eb90 --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/graphql/mutations/alert_todo_create.mutation.graphql @@ -0,0 +1,10 @@ +#import "../fragments/alert_detail_item.fragment.graphql" + +mutation alertTodoCreate($projectPath: ID!, $iid: String!) { + alertTodoCreate(input: { iid: $iid, projectPath: $projectPath }) { + errors + alert { + ...AlertDetailItem + } + } +} diff --git a/app/assets/javascripts/vue_shared/alert_details/graphql/queries/alert_details.query.graphql b/app/assets/javascripts/vue_shared/alert_details/graphql/queries/alert_details.query.graphql new file mode 100644 index 00000000000..5ee2cf7ca44 --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/graphql/queries/alert_details.query.graphql @@ -0,0 +1,11 @@ +#import "../fragments/alert_detail_item.fragment.graphql" + +query alertDetails($fullPath: ID!, $alertId: String) { + project(fullPath: $fullPath) { + alertManagementAlerts(iid: $alertId) { + nodes { + ...AlertDetailItem + } + } + } +} diff --git a/app/assets/javascripts/vue_shared/alert_details/graphql/queries/alert_sidebar_status.query.graphql b/app/assets/javascripts/vue_shared/alert_details/graphql/queries/alert_sidebar_status.query.graphql new file mode 100644 index 00000000000..61c570c5cd0 --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/graphql/queries/alert_sidebar_status.query.graphql @@ -0,0 +1,3 @@ +query sidebarStatus { + sidebarStatus @client +} diff --git a/app/assets/javascripts/vue_shared/alert_details/index.js b/app/assets/javascripts/vue_shared/alert_details/index.js new file mode 100644 index 00000000000..643d6b3a3fe --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/index.js @@ -0,0 +1,80 @@ +import { defaultDataIdFromObject } from 'apollo-cache-inmemory'; +import produce from 'immer'; +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/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, page = DEFAULT_PAGE } = domEl.dataset; + const router = createRouter(); + + const resolvers = { + Mutation: { + toggleSidebarStatus: (_, __, { cache }) => { + const sourceData = cache.readQuery({ query: sidebarStatusQuery }); + const data = produce(sourceData, (draftData) => { + // eslint-disable-next-line no-param-reassign + draftData.sidebarStatus = !draftData.sidebarStatus; + }); + cache.writeQuery({ query: sidebarStatusQuery, data }); + }, + }, + }; + + const apolloProvider = new VueApollo({ + defaultClient: createDefaultClient(resolvers, { + cacheConfig: { + dataIdFromObject: (object) => { + // eslint-disable-next-line no-underscore-dangle + if (object.__typename === 'AlertManagementAlert') { + return object.iid; + } + return defaultDataIdFromObject(object); + }, + }, + assumeImmutableResults: true, + }), + }); + + apolloProvider.clients.defaultClient.cache.writeData({ + data: { + sidebarStatus: false, + }, + }); + + 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, + apolloProvider, + router, + render(createElement) { + return createElement('alert-details', {}); + }, + }); +}; diff --git a/app/assets/javascripts/vue_shared/alert_details/router.js b/app/assets/javascripts/vue_shared/alert_details/router.js new file mode 100644 index 00000000000..5687fe4e0f5 --- /dev/null +++ b/app/assets/javascripts/vue_shared/alert_details/router.js @@ -0,0 +1,13 @@ +import Vue from 'vue'; +import VueRouter from 'vue-router'; +import { joinPaths } from '~/lib/utils/url_utility'; + +Vue.use(VueRouter); + +export default function createRouter(base) { + return new VueRouter({ + mode: 'hash', + base: joinPaths(gon.relative_url_root || '', base), + routes: [{ path: '/:tabId', name: 'tab' }], + }); +} 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 -- cgit v1.2.1