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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-11-22 15:07:45 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-11-22 15:07:45 +0300
commit25bf8a36335fa281dc8fe56f355f3829ace703a5 (patch)
tree33731aef63f86469a57185a8dfb46071007ed61c
parent02a0289d4077552778c0eeb0cc0172dfd7b6b331 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.checksum4
-rw-r--r--Gemfile.lock6
-rw-r--r--app/assets/javascripts/boards/components/board_content_sidebar.vue6
-rw-r--r--app/assets/javascripts/issuable/bulk_update_sidebar/constants.js23
-rw-r--r--app/assets/javascripts/issuable/bulk_update_sidebar/index.js75
-rw-r--r--app/assets/javascripts/issuable/index.js15
-rw-r--r--app/assets/javascripts/issuable/issuable_bulk_update_actions.js (renamed from app/assets/javascripts/issuable/bulk_update_sidebar/issuable_bulk_update_actions.js)0
-rw-r--r--app/assets/javascripts/issuable/issuable_bulk_update_sidebar.js (renamed from app/assets/javascripts/issuable/bulk_update_sidebar/issuable_bulk_update_sidebar.js)10
-rw-r--r--app/assets/javascripts/issues/list/components/issues_list_app.vue5
-rw-r--r--app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue69
-rw-r--r--app/assets/javascripts/issues/show/components/incidents/timeline_events_tab.vue7
-rw-r--r--app/assets/javascripts/labels/labels_select.js2
-rw-r--r--app/assets/javascripts/pages/groups/merge_requests/index.js8
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/index/index.js9
-rw-r--r--app/assets/javascripts/sidebar/components/copy_email/copy_email_to_clipboard.vue (renamed from app/assets/javascripts/sidebar/components/copy_email_to_clipboard.vue)0
-rw-r--r--app/assets/javascripts/sidebar/components/move/move_issues_button.vue (renamed from app/assets/javascripts/issuable/bulk_update_sidebar/components/move_issues_button.vue)2
-rw-r--r--app/assets/javascripts/sidebar/components/status/status_dropdown.vue (renamed from app/assets/javascripts/issuable/bulk_update_sidebar/components/status_dropdown.vue)2
-rw-r--r--app/assets/javascripts/sidebar/components/subscriptions/subscriptions_dropdown.vue (renamed from app/assets/javascripts/issuable/bulk_update_sidebar/components/subscriptions_dropdown.vue)2
-rw-r--r--app/assets/javascripts/sidebar/constants.js22
-rw-r--r--app/assets/javascripts/sidebar/mount_sidebar.js83
-rw-r--r--app/assets/javascripts/sidebar/queries/move_issue.mutation.graphql (renamed from app/assets/javascripts/issuable/bulk_update_sidebar/components/graphql/mutations/move_issue.mutation.graphql)0
-rw-r--r--app/assets/javascripts/vue_shared/components/metric_images/metric_images_tab.vue7
-rw-r--r--app/assets/stylesheets/framework/variables.scss24
-rw-r--r--app/assets/stylesheets/pages/notes.scss8
-rw-r--r--app/assets/stylesheets/startup/startup-dark.scss68
-rw-r--r--app/assets/stylesheets/startup/startup-general.scss6
-rw-r--r--app/assets/stylesheets/startup/startup-signin.scss4
-rw-r--r--app/assets/stylesheets/themes/_dark.scss29
-rw-r--r--app/services/projects/update_pages_service.rb7
-rw-r--r--config/metrics/settings/20210216180841_background_upload.yml3
-rw-r--r--config/metrics/settings/20210216180851_background_upload.yml3
-rw-r--r--config/metrics/settings/20210216180900_background_upload.yml3
-rw-r--r--config/metrics/settings/20210216180909_background_upload.yml3
-rw-r--r--config/metrics/settings/20210216180918_background_upload.yml3
-rw-r--r--db/post_migrate/20221121152048_remove_unused_feedback_migration_index.rb24
-rw-r--r--db/post_migrate/20221121152515_add_supporting_index_for_vulnerabilities_feedback_migration2.rb24
-rw-r--r--db/schema_migrations/202211211520481
-rw-r--r--db/schema_migrations/202211211525151
-rw-r--r--db/structure.sql2
-rw-r--r--doc/user/project/integrations/webhooks.md15
-rw-r--r--lib/api/commit_statuses.rb11
-rw-r--r--lib/gitlab/audit/auditor.rb25
-rw-r--r--lib/gitlab/ci/build/context/build.rb2
-rw-r--r--lib/gitlab/usage_data.rb2
-rwxr-xr-xscripts/undercoverage9
-rw-r--r--spec/frontend/issues/list/components/issues_list_app_spec.js2
-rw-r--r--spec/frontend/issues/show/components/incidents/incident_tabs_spec.js83
-rw-r--r--spec/frontend/sidebar/components/assignees/assignee_title_spec.js (renamed from spec/frontend/sidebar/assignee_title_spec.js)0
-rw-r--r--spec/frontend/sidebar/components/assignees/assignees_realtime_spec.js (renamed from spec/frontend/sidebar/assignees_realtime_spec.js)2
-rw-r--r--spec/frontend/sidebar/components/assignees/assignees_spec.js (renamed from spec/frontend/sidebar/assignees_spec.js)2
-rw-r--r--spec/frontend/sidebar/components/assignees/issuable_assignees_spec.js (renamed from spec/frontend/sidebar/issuable_assignees_spec.js)0
-rw-r--r--spec/frontend/sidebar/components/assignees/sidebar_assignees_spec.js (renamed from spec/frontend/sidebar/sidebar_assignees_spec.js)2
-rw-r--r--spec/frontend/sidebar/components/copy_email/copy_email_to_clipboard_spec.js (renamed from spec/frontend/sidebar/components/copy_email_to_clipboard_spec.js)2
-rw-r--r--spec/frontend/sidebar/components/crm_contacts/crm_contacts_spec.js (renamed from spec/frontend/sidebar/components/crm_contacts_spec.js)2
-rw-r--r--spec/frontend/sidebar/components/lock/__snapshots__/edit_form_spec.js.snap (renamed from spec/frontend/sidebar/lock/__snapshots__/edit_form_spec.js.snap)0
-rw-r--r--spec/frontend/sidebar/components/lock/constants.js (renamed from spec/frontend/sidebar/lock/constants.js)0
-rw-r--r--spec/frontend/sidebar/components/lock/edit_form_buttons_spec.js (renamed from spec/frontend/sidebar/lock/edit_form_buttons_spec.js)0
-rw-r--r--spec/frontend/sidebar/components/lock/edit_form_spec.js (renamed from spec/frontend/sidebar/lock/edit_form_spec.js)0
-rw-r--r--spec/frontend/sidebar/components/lock/issuable_lock_form_spec.js (renamed from spec/frontend/sidebar/lock/issuable_lock_form_spec.js)0
-rw-r--r--spec/frontend/sidebar/components/move/move_issues_button_spec.js (renamed from spec/frontend/issuable/bulk_update_sidebar/components/move_issues_button_spec.js)4
-rw-r--r--spec/frontend/sidebar/components/participants/participants_spec.js (renamed from spec/frontend/sidebar/participants_spec.js)0
-rw-r--r--spec/frontend/sidebar/components/reviewers/reviewer_title_spec.js (renamed from spec/frontend/sidebar/reviewer_title_spec.js)0
-rw-r--r--spec/frontend/sidebar/components/reviewers/reviewers_spec.js (renamed from spec/frontend/sidebar/reviewers_spec.js)0
-rw-r--r--spec/frontend/sidebar/components/status/status_dropdown_spec.js (renamed from spec/frontend/issuable/bulk_update_sidebar/components/status_dropdown_spec.js)4
-rw-r--r--spec/frontend/sidebar/components/subscriptions/subscriptions_dropdown_spec.js (renamed from spec/frontend/issuable/bulk_update_sidebar/components/subscriptions_dropdown_spec.js)4
-rw-r--r--spec/frontend/sidebar/components/subscriptions/subscriptions_spec.js (renamed from spec/frontend/sidebar/subscriptions_spec.js)0
-rw-r--r--spec/frontend/sidebar/components/todo_toggle/__snapshots__/todo_spec.js.snap (renamed from spec/frontend/sidebar/__snapshots__/todo_spec.js.snap)0
-rw-r--r--spec/frontend/sidebar/components/todo_toggle/todo_spec.js (renamed from spec/frontend/sidebar/todo_spec.js)0
-rw-r--r--spec/frontend/sidebar/lib/sidebar_move_issue_spec.js (renamed from spec/frontend/sidebar/sidebar_move_issue_spec.js)2
-rw-r--r--spec/frontend/sidebar/stores/sidebar_store_spec.js (renamed from spec/frontend/sidebar/sidebar_store_spec.js)2
-rw-r--r--spec/lib/gitlab/audit/auditor_spec.rb28
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb2
-rw-r--r--spec/requests/api/commit_statuses_spec.rb60
-rw-r--r--spec/services/ci/pipelines/add_job_service_spec.rb4
-rw-r--r--spec/services/projects/update_pages_service_spec.rb7
76 files changed, 545 insertions, 303 deletions
diff --git a/Gemfile b/Gemfile
index 0a56b296a54..5681ef34c00 100644
--- a/Gemfile
+++ b/Gemfile
@@ -166,7 +166,7 @@ gem 'seed-fu', '~> 2.3.7'
gem 'elasticsearch-model', '~> 7.2'
gem 'elasticsearch-rails', '~> 7.2', require: 'elasticsearch/rails/instrumentation'
gem 'elasticsearch-api', '7.13.3'
-gem 'aws-sdk-core', '~> 3.167.0'
+gem 'aws-sdk-core', '~> 3.168.1'
gem 'aws-sdk-cloudformation', '~> 1'
gem 'aws-sdk-s3', '~> 1.117.1'
gem 'faraday_middleware-aws-sigv4', '~>0.3.0'
diff --git a/Gemfile.checksum b/Gemfile.checksum
index 38044e328d2..81478ea92d9 100644
--- a/Gemfile.checksum
+++ b/Gemfile.checksum
@@ -33,9 +33,9 @@
{"name":"awesome_print","version":"1.9.2","platform":"ruby","checksum":"e99b32b704acff16d768b3468680793ced40bfdc4537eb07e06a4be11133786e"},
{"name":"awrence","version":"1.1.1","platform":"ruby","checksum":"9be584c97408ed92d5e1ca11740853646fe270de675f2f8dd44e8233226dfc97"},
{"name":"aws-eventstream","version":"1.2.0","platform":"ruby","checksum":"ffa53482c92880b001ff2fb06919b9bb82fd847cbb0fa244985d2ebb6dd0d1df"},
-{"name":"aws-partitions","version":"1.658.0","platform":"ruby","checksum":"bba2e21fc87c4e68c7ba5c09e3cd2b81d59ca86111ab236eaf9c5a8ae207b3fc"},
+{"name":"aws-partitions","version":"1.664.0","platform":"ruby","checksum":"cf7e9d07fb7d3517e4e349cf83d724fb7751caecc9b7a1abfd4e665be69ec9c0"},
{"name":"aws-sdk-cloudformation","version":"1.41.0","platform":"ruby","checksum":"31e47539719734413671edf9b1a31f8673fbf9688549f50c41affabbcb1c6b26"},
-{"name":"aws-sdk-core","version":"3.167.0","platform":"ruby","checksum":"d371856ad86f8bff08928059ee09b7cb9bca8ebf36bf5081f12424e4f491b624"},
+{"name":"aws-sdk-core","version":"3.168.1","platform":"ruby","checksum":"2b83c2cc0dde47293a9ff4f4ad1c4d49913c718d0daba8d1b357b5315fdad6ee"},
{"name":"aws-sdk-kms","version":"1.59.0","platform":"ruby","checksum":"6c002ebf8e404625c8338ca12ae69b1329399f9dc1b0ebca474e00ff06700153"},
{"name":"aws-sdk-s3","version":"1.117.1","platform":"ruby","checksum":"76f6dac5baeb2b78616eb34c6af650c1b7a15c1078b169d1b27e8421904c509d"},
{"name":"aws-sigv4","version":"1.5.1","platform":"ruby","checksum":"d68c87fff4ee843b4b92b23c7f31f957f254ec6eb064181f7119124aab8b8bb4"},
diff --git a/Gemfile.lock b/Gemfile.lock
index f232b7bf025..5b870696af2 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -185,11 +185,11 @@ GEM
awesome_print (1.9.2)
awrence (1.1.1)
aws-eventstream (1.2.0)
- aws-partitions (1.658.0)
+ aws-partitions (1.664.0)
aws-sdk-cloudformation (1.41.0)
aws-sdk-core (~> 3, >= 3.99.0)
aws-sigv4 (~> 1.1)
- aws-sdk-core (3.167.0)
+ aws-sdk-core (3.168.1)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
@@ -1594,7 +1594,7 @@ DEPENDENCIES
autoprefixer-rails (= 10.2.5.1)
awesome_print
aws-sdk-cloudformation (~> 1)
- aws-sdk-core (~> 3.167.0)
+ aws-sdk-core (~> 3.168.1)
aws-sdk-s3 (~> 1.117.1)
babosa (~> 1.0.4)
base32 (~> 0.3.0)
diff --git a/app/assets/javascripts/boards/components/board_content_sidebar.vue b/app/assets/javascripts/boards/components/board_content_sidebar.vue
index 65b6bc6b98e..a2ac1f3fe2c 100644
--- a/app/assets/javascripts/boards/components/board_content_sidebar.vue
+++ b/app/assets/javascripts/boards/components/board_content_sidebar.vue
@@ -34,10 +34,10 @@ export default {
MountingPortal,
SidebarHealthStatusWidget: () =>
import('ee_component/sidebar/components/health_status/sidebar_health_status_widget.vue'),
+ SidebarIterationWidget: () =>
+ import('ee_component/sidebar/components/iteration/sidebar_iteration_widget.vue'),
SidebarWeightWidget: () =>
import('ee_component/sidebar/components/weight/sidebar_weight_widget.vue'),
- IterationSidebarDropdownWidget: () =>
- import('ee_component/sidebar/components/iteration_sidebar_dropdown_widget.vue'),
},
mixins: [glFeatureFlagMixin()],
inject: {
@@ -193,7 +193,7 @@ export default {
:issuable-type="issuableType"
data-testid="sidebar-milestones"
/>
- <iteration-sidebar-dropdown-widget
+ <sidebar-iteration-widget
v-if="iterationFeatureAvailable && !isIncidentSidebar"
:iid="activeBoardItem.iid"
:workspace-path="projectPathForActiveIssue"
diff --git a/app/assets/javascripts/issuable/bulk_update_sidebar/constants.js b/app/assets/javascripts/issuable/bulk_update_sidebar/constants.js
deleted file mode 100644
index 68133ceb3c7..00000000000
--- a/app/assets/javascripts/issuable/bulk_update_sidebar/constants.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import { __ } from '~/locale';
-
-export const statusDropdownOptions = [
- {
- text: __('Open'),
- value: 'reopen',
- },
- {
- text: __('Closed'),
- value: 'close',
- },
-];
-
-export const subscriptionsDropdownOptions = [
- {
- text: __('Subscribe'),
- value: 'subscribe',
- },
- {
- text: __('Unsubscribe'),
- value: 'unsubscribe',
- },
-];
diff --git a/app/assets/javascripts/issuable/bulk_update_sidebar/index.js b/app/assets/javascripts/issuable/bulk_update_sidebar/index.js
deleted file mode 100644
index b7cb805ee37..00000000000
--- a/app/assets/javascripts/issuable/bulk_update_sidebar/index.js
+++ /dev/null
@@ -1,75 +0,0 @@
-import Vue from 'vue';
-import VueApollo from 'vue-apollo';
-import { gqlClient } from '../../issues/list/graphql';
-import StatusDropdown from './components/status_dropdown.vue';
-import SubscriptionsDropdown from './components/subscriptions_dropdown.vue';
-import MoveIssuesButton from './components/move_issues_button.vue';
-import issuableBulkUpdateActions from './issuable_bulk_update_actions';
-import IssuableBulkUpdateSidebar from './issuable_bulk_update_sidebar';
-
-export function initBulkUpdateSidebar(prefixId) {
- const el = document.querySelector('.issues-bulk-update');
-
- if (!el) {
- return;
- }
-
- issuableBulkUpdateActions.init({ prefixId });
- new IssuableBulkUpdateSidebar(); // eslint-disable-line no-new
-}
-
-export function initStatusDropdown() {
- const el = document.querySelector('.js-status-dropdown');
-
- if (!el) {
- return null;
- }
-
- return new Vue({
- el,
- name: 'StatusDropdownRoot',
- render: (createElement) => createElement(StatusDropdown),
- });
-}
-
-export function initSubscriptionsDropdown() {
- const el = document.querySelector('.js-subscriptions-dropdown');
-
- if (!el) {
- return null;
- }
-
- return new Vue({
- el,
- name: 'SubscriptionsDropdownRoot',
- render: (createElement) => createElement(SubscriptionsDropdown),
- });
-}
-
-export function initMoveIssuesButton() {
- const el = document.querySelector('.js-move-issues');
-
- if (!el) {
- return null;
- }
-
- const { dataset } = el;
-
- Vue.use(VueApollo);
- const apolloProvider = new VueApollo({
- defaultClient: gqlClient,
- });
-
- return new Vue({
- el,
- name: 'MoveIssuesRoot',
- apolloProvider,
- render: (createElement) =>
- createElement(MoveIssuesButton, {
- props: {
- projectFullPath: dataset.projectFullPath,
- projectsFetchPath: dataset.projectsFetchPath,
- },
- }),
- });
-}
diff --git a/app/assets/javascripts/issuable/index.js b/app/assets/javascripts/issuable/index.js
index 10dbefce503..ed336deb2ed 100644
--- a/app/assets/javascripts/issuable/index.js
+++ b/app/assets/javascripts/issuable/index.js
@@ -1,12 +1,25 @@
import { GlToast } from '@gitlab/ui';
import Vue from 'vue';
-import IssuableContext from '~/issuable/issuable_context';
import { parseBoolean } from '~/lib/utils/common_utils';
import Sidebar from '~/right_sidebar';
import { getSidebarOptions } from '~/sidebar/mount_sidebar';
import CsvImportExportButtons from './components/csv_import_export_buttons.vue';
import IssuableByEmail from './components/issuable_by_email.vue';
import IssuableHeaderWarnings from './components/issuable_header_warnings.vue';
+import issuableBulkUpdateActions from './issuable_bulk_update_actions';
+import IssuableBulkUpdateSidebar from './issuable_bulk_update_sidebar';
+import IssuableContext from './issuable_context';
+
+export function initBulkUpdateSidebar(prefixId) {
+ const el = document.querySelector('.issues-bulk-update');
+
+ if (!el) {
+ return;
+ }
+
+ issuableBulkUpdateActions.init({ prefixId });
+ new IssuableBulkUpdateSidebar(); // eslint-disable-line no-new
+}
export function initCsvImportExportButtons() {
const el = document.querySelector('.js-csv-import-export-buttons');
diff --git a/app/assets/javascripts/issuable/bulk_update_sidebar/issuable_bulk_update_actions.js b/app/assets/javascripts/issuable/issuable_bulk_update_actions.js
index 14824820c0d..14824820c0d 100644
--- a/app/assets/javascripts/issuable/bulk_update_sidebar/issuable_bulk_update_actions.js
+++ b/app/assets/javascripts/issuable/issuable_bulk_update_actions.js
diff --git a/app/assets/javascripts/issuable/bulk_update_sidebar/issuable_bulk_update_sidebar.js b/app/assets/javascripts/issuable/issuable_bulk_update_sidebar.js
index b46a95c7dfa..095da60a583 100644
--- a/app/assets/javascripts/issuable/bulk_update_sidebar/issuable_bulk_update_sidebar.js
+++ b/app/assets/javascripts/issuable/issuable_bulk_update_sidebar.js
@@ -3,7 +3,12 @@
import $ from 'jquery';
import issuableEventHub from '~/issues/list/eventhub';
import LabelsSelect from '~/labels/labels_select';
-import { mountMilestoneDropdown } from '~/sidebar/mount_sidebar';
+import {
+ mountMilestoneDropdown,
+ mountMoveIssuesButton,
+ mountStatusDropdown,
+ mountSubscriptionsDropdown,
+} from '~/sidebar/mount_sidebar';
import IssuableBulkUpdateActions from './issuable_bulk_update_actions';
const HIDDEN_CLASS = 'hidden';
@@ -56,6 +61,9 @@ export default class IssuableBulkUpdateSidebar {
initDropdowns() {
new LabelsSelect();
mountMilestoneDropdown();
+ mountMoveIssuesButton();
+ mountStatusDropdown();
+ mountSubscriptionsDropdown();
// Checking IS_EE and using ee_else_ce is odd, but we do it here to satisfy
// the import/no-unresolved lint rule when FOSS_ONLY=1, even though at
diff --git a/app/assets/javascripts/issues/list/components/issues_list_app.vue b/app/assets/javascripts/issues/list/components/issues_list_app.vue
index eb1c17ba7e5..cfb1de2e680 100644
--- a/app/assets/javascripts/issues/list/components/issues_list_app.vue
+++ b/app/assets/javascripts/issues/list/components/issues_list_app.vue
@@ -572,11 +572,8 @@ export default {
},
async handleBulkUpdateClick() {
if (!this.hasInitBulkEdit) {
- const bulkUpdateSidebar = await import('~/issuable/bulk_update_sidebar');
+ const bulkUpdateSidebar = await import('~/issuable');
bulkUpdateSidebar.initBulkUpdateSidebar('issuable_');
- bulkUpdateSidebar.initStatusDropdown();
- bulkUpdateSidebar.initSubscriptionsDropdown();
- bulkUpdateSidebar.initMoveIssuesButton();
const usersSelect = await import('~/users_select');
const UsersSelect = usersSelect.default;
diff --git a/app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue b/app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue
index 5725d0f8d6a..a3efb0bbbea 100644
--- a/app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue
+++ b/app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue
@@ -5,12 +5,25 @@ import { trackIncidentDetailsViewsOptions } from '~/incidents/constants';
import { s__ } from '~/locale';
import Tracking from '~/tracking';
import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue';
-import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import DescriptionComponent from '../description.vue';
import getAlert from './graphql/queries/get_alert.graphql';
import HighlightBar from './highlight_bar.vue';
import TimelineTab from './timeline_events_tab.vue';
+export const incidentTabsI18n = Object.freeze({
+ summaryTitle: s__('Incident|Summary'),
+ metricsTitle: s__('Incident|Metrics'),
+ alertsTitle: s__('Incident|Alert details'),
+ timelineTitle: s__('Incident|Timeline'),
+});
+
+export const TAB_NAMES = Object.freeze({
+ SUMMARY: '',
+ ALERTS: 'alerts',
+ METRICS: 'metrics',
+ TIMELINE: 'timeline',
+});
+
export default {
components: {
AlertDetailsTable,
@@ -22,8 +35,8 @@ export default {
IncidentMetricTab: () =>
import('ee_component/issues/show/components/incidents/incident_metric_tab.vue'),
},
- mixins: [glFeatureFlagsMixin()],
- inject: ['fullPath', 'iid'],
+ inject: ['fullPath', 'iid', 'uploadMetricsFeatureAvailable'],
+ i18n: incidentTabsI18n,
apollo: {
alert: {
query: getAlert,
@@ -46,12 +59,44 @@ export default {
data() {
return {
alert: null,
+ activeTabIndex: 0,
};
},
computed: {
loading() {
return this.$apollo.queries.alert.loading;
},
+ tabMapping() {
+ const availableTabs = [TAB_NAMES.SUMMARY];
+
+ if (this.uploadMetricsFeatureAvailable) {
+ availableTabs.push(TAB_NAMES.METRICS);
+ }
+ if (this.alert) {
+ availableTabs.push(TAB_NAMES.ALERTS);
+ }
+
+ availableTabs.push(TAB_NAMES.TIMELINE);
+
+ const tabNamesToIndex = {};
+ const tabIndexToName = {};
+
+ availableTabs.forEach((item, index) => {
+ tabNamesToIndex[item] = index;
+ tabIndexToName[index] = item;
+ });
+
+ return { tabNamesToIndex, tabIndexToName };
+ },
+ currentTabIndex: {
+ get() {
+ return this.activeTabIndex;
+ },
+ set(index) {
+ this.handleTabChange(index);
+ this.activeTabIndex = index;
+ },
+ },
},
mounted() {
this.trackPageViews();
@@ -91,25 +136,33 @@ export default {
<template>
<div>
<gl-tabs
+ v-model="currentTabIndex"
content-class="gl-reset-line-height"
class="gl-mt-n3"
data-testid="incident-tabs"
- @input="handleTabChange"
>
- <gl-tab :title="s__('Incident|Summary')">
+ <gl-tab :title="$options.i18n.summaryTitle" data-testid="summary-tab">
<highlight-bar :alert="alert" />
<description-component v-bind="$attrs" v-on="$listeners" />
</gl-tab>
- <incident-metric-tab />
+ <gl-tab
+ v-if="uploadMetricsFeatureAvailable"
+ :title="$options.i18n.metricsTitle"
+ data-testid="metrics-tab"
+ >
+ <incident-metric-tab />
+ </gl-tab>
<gl-tab
v-if="alert"
class="alert-management-details"
- :title="s__('Incident|Alert details')"
+ :title="$options.i18n.alertsTitle"
data-testid="alert-details-tab"
>
<alert-details-table :alert="alert" :loading="loading" />
</gl-tab>
- <timeline-tab />
+ <gl-tab :title="$options.i18n.timelineTitle" data-testid="timeline-tab">
+ <timeline-tab />
+ </gl-tab>
</gl-tabs>
</div>
</template>
diff --git a/app/assets/javascripts/issues/show/components/incidents/timeline_events_tab.vue b/app/assets/javascripts/issues/show/components/incidents/timeline_events_tab.vue
index 5f70d9acac9..c8237766505 100644
--- a/app/assets/javascripts/issues/show/components/incidents/timeline_events_tab.vue
+++ b/app/assets/javascripts/issues/show/components/incidents/timeline_events_tab.vue
@@ -1,5 +1,5 @@
<script>
-import { GlButton, GlEmptyState, GlLoadingIcon, GlTab } from '@gitlab/ui';
+import { GlButton, GlEmptyState, GlLoadingIcon } from '@gitlab/ui';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { TYPE_ISSUE } from '~/graphql_shared/constants';
import { fetchPolicies } from '~/lib/graphql';
@@ -15,7 +15,6 @@ export default {
GlButton,
GlEmptyState,
GlLoadingIcon,
- GlTab,
CreateTimelineEvent,
IncidentTimelineEventsList,
},
@@ -77,7 +76,7 @@ export default {
</script>
<template>
- <gl-tab :title="$options.i18n.title">
+ <div>
<gl-loading-icon v-if="timelineEventLoading" size="lg" color="dark" class="gl-mt-5" />
<gl-empty-state
v-else-if="showEmptyState"
@@ -106,5 +105,5 @@ export default {
>
{{ $options.i18n.addEventButton }}
</gl-button>
- </gl-tab>
+ </div>
</template>
diff --git a/app/assets/javascripts/labels/labels_select.js b/app/assets/javascripts/labels/labels_select.js
index 65dda804a20..515b0a79a03 100644
--- a/app/assets/javascripts/labels/labels_select.js
+++ b/app/assets/javascripts/labels/labels_select.js
@@ -4,7 +4,7 @@
import $ from 'jquery';
import { difference, isEqual, escape, sortBy, template, union } from 'lodash';
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
-import IssuableBulkUpdateActions from '~/issuable/bulk_update_sidebar/issuable_bulk_update_actions';
+import IssuableBulkUpdateActions from '~/issuable/issuable_bulk_update_actions';
import { isScopedLabel } from '~/lib/utils/common_utils';
import { createAlert } from '~/flash';
import axios from '~/lib/utils/axios_utils';
diff --git a/app/assets/javascripts/pages/groups/merge_requests/index.js b/app/assets/javascripts/pages/groups/merge_requests/index.js
index 377ba0f13a9..bf0147ca885 100644
--- a/app/assets/javascripts/pages/groups/merge_requests/index.js
+++ b/app/assets/javascripts/pages/groups/merge_requests/index.js
@@ -1,11 +1,7 @@
import addExtraTokensForMergeRequests from 'ee_else_ce/filtered_search/add_extra_tokens_for_merge_requests';
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
-import {
- initBulkUpdateSidebar,
- initStatusDropdown,
- initSubscriptionsDropdown,
-} from '~/issuable/bulk_update_sidebar';
import { FILTERED_SEARCH } from '~/filtered_search/constants';
+import { initBulkUpdateSidebar } from '~/issuable';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import projectSelect from '~/project_select';
@@ -13,8 +9,6 @@ const ISSUABLE_BULK_UPDATE_PREFIX = 'merge_request_';
addExtraTokensForMergeRequests(IssuableFilteredSearchTokenKeys);
initBulkUpdateSidebar(ISSUABLE_BULK_UPDATE_PREFIX);
-initStatusDropdown();
-initSubscriptionsDropdown();
initFilteredSearch({
page: FILTERED_SEARCH.MERGE_REQUESTS,
diff --git a/app/assets/javascripts/pages/projects/merge_requests/index/index.js b/app/assets/javascripts/pages/projects/merge_requests/index/index.js
index 2399aafc9b5..b3a09cc0be3 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/index/index.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/index/index.js
@@ -1,20 +1,13 @@
import addExtraTokensForMergeRequests from 'ee_else_ce/filtered_search/add_extra_tokens_for_merge_requests';
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
-import { initCsvImportExportButtons, initIssuableByEmail } from '~/issuable';
-import {
- initBulkUpdateSidebar,
- initStatusDropdown,
- initSubscriptionsDropdown,
-} from '~/issuable/bulk_update_sidebar';
import { FILTERED_SEARCH } from '~/filtered_search/constants';
+import { initBulkUpdateSidebar, initCsvImportExportButtons, initIssuableByEmail } from '~/issuable';
import { ISSUABLE_INDEX } from '~/issuable/constants';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import UsersSelect from '~/users_select';
initBulkUpdateSidebar(ISSUABLE_INDEX.MERGE_REQUEST);
-initStatusDropdown();
-initSubscriptionsDropdown();
addExtraTokensForMergeRequests(IssuableFilteredSearchTokenKeys);
IssuableFilteredSearchTokenKeys.removeTokensForKeys('iteration');
diff --git a/app/assets/javascripts/sidebar/components/copy_email_to_clipboard.vue b/app/assets/javascripts/sidebar/components/copy_email/copy_email_to_clipboard.vue
index fd652583f76..fd652583f76 100644
--- a/app/assets/javascripts/sidebar/components/copy_email_to_clipboard.vue
+++ b/app/assets/javascripts/sidebar/components/copy_email/copy_email_to_clipboard.vue
diff --git a/app/assets/javascripts/issuable/bulk_update_sidebar/components/move_issues_button.vue b/app/assets/javascripts/sidebar/components/move/move_issues_button.vue
index 6e287ac3bb7..a3a5072fc2d 100644
--- a/app/assets/javascripts/issuable/bulk_update_sidebar/components/move_issues_button.vue
+++ b/app/assets/javascripts/sidebar/components/move/move_issues_button.vue
@@ -13,7 +13,7 @@ import {
import issuableEventHub from '~/issues/list/eventhub';
import getIssuesQuery from 'ee_else_ce/issues/list/queries/get_issues.query.graphql';
import getIssuesCountQuery from 'ee_else_ce/issues/list/queries/get_issues_counts.query.graphql';
-import moveIssueMutation from './graphql/mutations/move_issue.mutation.graphql';
+import moveIssueMutation from '../../queries/move_issue.mutation.graphql';
export default {
name: 'MoveIssuesButton',
diff --git a/app/assets/javascripts/issuable/bulk_update_sidebar/components/status_dropdown.vue b/app/assets/javascripts/sidebar/components/status/status_dropdown.vue
index ba94932289e..7763ec00091 100644
--- a/app/assets/javascripts/issuable/bulk_update_sidebar/components/status_dropdown.vue
+++ b/app/assets/javascripts/sidebar/components/status/status_dropdown.vue
@@ -1,7 +1,7 @@
<script>
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { __ } from '~/locale';
-import { statusDropdownOptions } from '../constants';
+import { statusDropdownOptions } from '../../constants';
export default {
components: {
diff --git a/app/assets/javascripts/issuable/bulk_update_sidebar/components/subscriptions_dropdown.vue b/app/assets/javascripts/sidebar/components/subscriptions/subscriptions_dropdown.vue
index 8774b065c22..4c3ba76d12d 100644
--- a/app/assets/javascripts/issuable/bulk_update_sidebar/components/subscriptions_dropdown.vue
+++ b/app/assets/javascripts/sidebar/components/subscriptions/subscriptions_dropdown.vue
@@ -1,7 +1,7 @@
<script>
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { __ } from '~/locale';
-import { subscriptionsDropdownOptions } from '../constants';
+import { subscriptionsDropdownOptions } from '../../constants';
export default {
subscriptionsDropdownOptions,
diff --git a/app/assets/javascripts/sidebar/constants.js b/app/assets/javascripts/sidebar/constants.js
index 67b9b540e91..499b03cd931 100644
--- a/app/assets/javascripts/sidebar/constants.js
+++ b/app/assets/javascripts/sidebar/constants.js
@@ -350,3 +350,25 @@ export const escalationStatusQuery = getEscalationStatusQuery;
export const escalationStatusMutation = updateEscalationStatusMutation;
export const HOW_TO_TRACK_TIME = __('How to track time');
+
+export const statusDropdownOptions = [
+ {
+ text: __('Open'),
+ value: 'reopen',
+ },
+ {
+ text: __('Closed'),
+ value: 'close',
+ },
+];
+
+export const subscriptionsDropdownOptions = [
+ {
+ text: __('Subscribe'),
+ value: 'subscribe',
+ },
+ {
+ text: __('Unsubscribe'),
+ value: 'unsubscribe',
+ },
+];
diff --git a/app/assets/javascripts/sidebar/mount_sidebar.js b/app/assets/javascripts/sidebar/mount_sidebar.js
index b37486283ca..3fc98f86316 100644
--- a/app/assets/javascripts/sidebar/mount_sidebar.js
+++ b/app/assets/javascripts/sidebar/mount_sidebar.js
@@ -6,6 +6,7 @@ import { convertToGraphQLId } from '~/graphql_shared/utils';
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
import { IssuableType } from '~/issues/constants';
+import { gqlClient } from '~/issues/list/graphql';
import {
isInIssuePage,
isInDesignPage,
@@ -14,33 +15,36 @@ import {
parseBoolean,
} from '~/lib/utils/common_utils';
import { __ } from '~/locale';
-import CollapsedAssigneeList from '~/sidebar/components/assignees/collapsed_assignee_list.vue';
-import SidebarAssigneesWidget from '~/sidebar/components/assignees/sidebar_assignees_widget.vue';
-import SidebarConfidentialityWidget from '~/sidebar/components/confidential/sidebar_confidentiality_widget.vue';
-import SidebarDueDateWidget from '~/sidebar/components/date/sidebar_date_widget.vue';
-import MilestoneDropdown from '~/sidebar/components/milestone/milestone_dropdown.vue';
-import SidebarParticipantsWidget from '~/sidebar/components/participants/sidebar_participants_widget.vue';
-import SidebarReferenceWidget from '~/sidebar/components/reference/sidebar_reference_widget.vue';
-import SidebarDropdownWidget from '~/sidebar/components/sidebar_dropdown_widget.vue';
-import SidebarTodoWidget from '~/sidebar/components/todo_toggle/sidebar_todo_widget.vue';
import { apolloProvider } from '~/graphql_shared/issuable_client';
-import trackShowInviteMemberLink from '~/sidebar/track_invite_members';
import { DropdownVariant } from '~/vue_shared/components/sidebar/labels_select_vue/constants';
import LabelsSelectWidget from '~/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue';
import { LabelType } from '~/vue_shared/components/sidebar/labels_select_widget/constants';
-import Translate from '../vue_shared/translate';
+import Translate from '~/vue_shared/translate';
+import CollapsedAssigneeList from './components/assignees/collapsed_assignee_list.vue';
import SidebarAssignees from './components/assignees/sidebar_assignees.vue';
-import CopyEmailToClipboard from './components/copy_email_to_clipboard.vue';
+import SidebarAssigneesWidget from './components/assignees/sidebar_assignees_widget.vue';
+import SidebarConfidentialityWidget from './components/confidential/sidebar_confidentiality_widget.vue';
+import CopyEmailToClipboard from './components/copy_email/copy_email_to_clipboard.vue';
+import SidebarDueDateWidget from './components/date/sidebar_date_widget.vue';
import SidebarEscalationStatus from './components/incidents/sidebar_escalation_status.vue';
import IssuableLockForm from './components/lock/issuable_lock_form.vue';
+import MilestoneDropdown from './components/milestone/milestone_dropdown.vue';
+import MoveIssuesButton from './components/move/move_issues_button.vue';
+import SidebarParticipantsWidget from './components/participants/sidebar_participants_widget.vue';
+import SidebarReferenceWidget from './components/reference/sidebar_reference_widget.vue';
import SidebarReviewers from './components/reviewers/sidebar_reviewers.vue';
import SidebarReviewersInputs from './components/reviewers/sidebar_reviewers_inputs.vue';
import SidebarSeverity from './components/severity/sidebar_severity.vue';
+import SidebarDropdownWidget from './components/sidebar_dropdown_widget.vue';
+import StatusDropdown from './components/status/status_dropdown.vue';
import SidebarSubscriptionsWidget from './components/subscriptions/sidebar_subscriptions_widget.vue';
+import SubscriptionsDropdown from './components/subscriptions/subscriptions_dropdown.vue';
import SidebarTimeTracking from './components/time_tracking/sidebar_time_tracking.vue';
+import SidebarTodoWidget from './components/todo_toggle/sidebar_todo_widget.vue';
import { IssuableAttributeType } from './constants';
-import SidebarMoveIssue from './lib/sidebar_move_issue';
import CrmContacts from './components/crm_contacts/crm_contacts.vue';
+import SidebarMoveIssue from './lib/sidebar_move_issue';
+import trackShowInviteMemberLink from './track_invite_members';
Vue.use(Translate);
Vue.use(VueApollo);
@@ -635,6 +639,59 @@ function mountCopyEmailToClipboard() {
});
}
+export function mountMoveIssuesButton() {
+ const el = document.querySelector('.js-move-issues');
+
+ if (!el) {
+ return null;
+ }
+
+ Vue.use(VueApollo);
+
+ return new Vue({
+ el,
+ name: 'MoveIssuesRoot',
+ apolloProvider: new VueApollo({
+ defaultClient: gqlClient,
+ }),
+ render: (createElement) =>
+ createElement(MoveIssuesButton, {
+ props: {
+ projectFullPath: el.dataset.projectFullPath,
+ projectsFetchPath: el.dataset.projectsFetchPath,
+ },
+ }),
+ });
+}
+
+export function mountStatusDropdown() {
+ const el = document.querySelector('.js-status-dropdown');
+
+ if (!el) {
+ return null;
+ }
+
+ return new Vue({
+ el,
+ name: 'StatusDropdownRoot',
+ render: (createElement) => createElement(StatusDropdown),
+ });
+}
+
+export function mountSubscriptionsDropdown() {
+ const el = document.querySelector('.js-subscriptions-dropdown');
+
+ if (!el) {
+ return null;
+ }
+
+ return new Vue({
+ el,
+ name: 'SubscriptionsDropdownRoot',
+ render: (createElement) => createElement(SubscriptionsDropdown),
+ });
+}
+
const isAssigneesWidgetShown =
(isInIssuePage() || isInDesignPage() || isInMRPage()) && gon.features.issueAssigneesWidget;
diff --git a/app/assets/javascripts/issuable/bulk_update_sidebar/components/graphql/mutations/move_issue.mutation.graphql b/app/assets/javascripts/sidebar/queries/move_issue.mutation.graphql
index d350072425b..d350072425b 100644
--- a/app/assets/javascripts/issuable/bulk_update_sidebar/components/graphql/mutations/move_issue.mutation.graphql
+++ b/app/assets/javascripts/sidebar/queries/move_issue.mutation.graphql
diff --git a/app/assets/javascripts/vue_shared/components/metric_images/metric_images_tab.vue b/app/assets/javascripts/vue_shared/components/metric_images/metric_images_tab.vue
index e23721da223..2cadc87eca3 100644
--- a/app/assets/javascripts/vue_shared/components/metric_images/metric_images_tab.vue
+++ b/app/assets/javascripts/vue_shared/components/metric_images/metric_images_tab.vue
@@ -1,5 +1,5 @@
<script>
-import { GlFormGroup, GlFormInput, GlLoadingIcon, GlModal, GlTab } from '@gitlab/ui';
+import { GlFormGroup, GlFormInput, GlLoadingIcon, GlModal } from '@gitlab/ui';
import { mapState, mapActions } from 'vuex';
import { __, s__ } from '~/locale';
import UploadDropzone from '~/vue_shared/components/upload_dropzone/upload_dropzone.vue';
@@ -11,7 +11,6 @@ export default {
GlFormInput,
GlLoadingIcon,
GlModal,
- GlTab,
MetricImagesTable,
UploadDropzone,
},
@@ -82,7 +81,7 @@ export default {
</script>
<template>
- <gl-tab :title="s__('Incident|Metrics')" data-testid="metrics-tab">
+ <div>
<div v-if="isLoadingMetricImages">
<gl-loading-icon class="gl-p-5" size="sm" />
</div>
@@ -117,5 +116,5 @@ export default {
:drop-description-message="$options.i18n.dropDescription"
@change="openMetricDialog"
/>
- </gl-tab>
+ </div>
</template>
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index 99284ea0a64..cf20ea90fe9 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -83,18 +83,9 @@ $darken-dark-factor: 10% !default;
$darken-border-factor: 5% !default;
$darken-border-dashed-factor: 25% !default;
-$white: #fff !default;
-$white-normal: #f0f0f0 !default;
-$white-dark: #eaeaea !default;
-$white-transparent: rgba($white, 0.8) !default;
-
$purple: #6d49cb !default;
$purple-light: #ede8fb !default;
-$black: #000 !default;
-$black-transparent: rgba(0, 0, 0, 0.3) !default;
-$almost-black: #242424 !default;
-
$green-50: #ecf4ee !default;
$green-100: #c3e6cd !default;
$green-200: #91d4a8 !default;
@@ -183,6 +174,15 @@ $t-gray-a-08: rgba($gray-950, 0.08) !default;
$t-gray-a-16: rgba($gray-950, 0.16) !default;
$t-gray-a-24: rgba($gray-950, 0.24) !default;
+$white: #fff !default;
+$white-normal: $gray-50 !default;
+$white-dark: darken($gray-50, 2) !default;
+$white-transparent: rgba($white, 0.8) !default;
+
+$black: #000 !default;
+$black-transparent: $t-gray-a-24 !default;
+$almost-black: $gray-950 !default;
+
$greens: (
'50': $green-50,
'100': $green-100,
@@ -380,7 +380,7 @@ $well-expand-item: #e8f2f7 !default;
$well-inner-border: #eef0f2 !default;
$well-light-border: #f1f1f1;
$well-light-text-color: #5b6169;
-$nav-active-bg: rgba($black, 0.08);
+$nav-active-bg: $t-gray-a-08;
/*
* Text
@@ -732,8 +732,8 @@ $commit-stat-summary-height: 36px;
/*
* Common
*/
-$common-gray-light: #bbb;
-$common-gray-dark: #444;
+$common-gray-light: $gray-200;
+$common-gray-dark: $gray-800;
/*
* Files
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index fa3c87490f1..4507cc2d1c6 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -4,7 +4,7 @@ $system-note-svg-size: 1rem;
@mixin vertical-line($left) {
&::before {
content: '';
- border-left: 2px solid var(--gray-10, $gray-10);
+ border-left: 2px solid var(--gray-50, $gray-50);
position: absolute;
top: $gl-padding-6;
bottom: 0;
@@ -416,17 +416,17 @@ $system-note-svg-size: 1rem;
.timeline-icon {
display: flex;
align-items: center;
- background-color: $gray-10;
+ background-color: $gray-50;
width: $system-note-icon-size;
height: $system-note-icon-size;
- border: 1px solid $gray-10;
+ border: 1px solid $gray-50;
border-radius: $system-note-icon-size;
margin: -6px 0 0;
svg {
width: $system-note-svg-size;
height: $system-note-svg-size;
- fill: $gray-400;
+ fill: $gray-600;
display: block;
margin: 0 auto;
}
diff --git a/app/assets/stylesheets/startup/startup-dark.scss b/app/assets/stylesheets/startup/startup-dark.scss
index 11131cc1a4b..90bb028ef10 100644
--- a/app/assets/stylesheets/startup/startup-dark.scss
+++ b/app/assets/stylesheets/startup/startup-dark.scss
@@ -19,7 +19,7 @@ body.gl-dark {
--black: #fff;
}
:root {
- --white: #333;
+ --white: #333238;
}
*,
*::before,
@@ -117,7 +117,7 @@ button::-moz-focus-inner,
kbd {
padding: 0.2rem 0.4rem;
font-size: 90%;
- color: #333;
+ color: #333238;
background-color: #ececef;
border-radius: 0.2rem;
}
@@ -142,7 +142,7 @@ kbd kbd {
font-weight: 400;
line-height: 1.5;
color: #ececef;
- background-color: #333;
+ background-color: #333238;
background-clip: padding-box;
border: 1px solid #737278;
border-radius: 0.25rem;
@@ -158,7 +158,7 @@ kbd kbd {
opacity: 1;
}
.form-control:disabled {
- background-color: #333238;
+ background-color: #24232a;
opacity: 1;
}
.form-inline {
@@ -215,7 +215,7 @@ kbd kbd {
color: #ececef;
text-align: left;
list-style: none;
- background-color: #333;
+ background-color: #333238;
background-clip: padding-box;
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 0.25rem;
@@ -410,7 +410,7 @@ a.gl-badge.badge-info:active {
background-color: #0b5cad;
}
a.gl-badge.badge-info:active {
- box-shadow: 0 0 0 1px #333, 0 0 0 3px #1f75cb;
+ box-shadow: 0 0 0 1px #333238, 0 0 0 3px #1f75cb;
outline: none;
}
.gl-badge.badge-success {
@@ -423,7 +423,7 @@ a.gl-badge.badge-success:active {
background-color: #24663b;
}
a.gl-badge.badge-success:active {
- box-shadow: 0 0 0 1px #333, 0 0 0 3px #1f75cb;
+ box-shadow: 0 0 0 1px #333238, 0 0 0 3px #1f75cb;
outline: none;
}
.gl-badge.badge-warning {
@@ -436,7 +436,7 @@ a.gl-badge.badge-warning:active {
background-color: #8f4700;
}
a.gl-badge.badge-warning:active {
- box-shadow: 0 0 0 1px #333, 0 0 0 3px #1f75cb;
+ box-shadow: 0 0 0 1px #333238, 0 0 0 3px #1f75cb;
outline: none;
}
.gl-button .gl-badge {
@@ -444,7 +444,7 @@ a.gl-badge.badge-warning:active {
}
.gl-form-input,
.gl-form-input.form-control {
- background-color: #333;
+ background-color: #333238;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
"Noto Sans", Ubuntu, Cantarell, "Helvetica Neue", sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
@@ -527,11 +527,11 @@ a.gl-badge.badge-warning:active {
border-radius: 0.25rem;
}
.gl-button.gl-button.btn-default {
- background-color: #333;
+ background-color: #333238;
}
.gl-button.gl-button.btn-default:active,
.gl-button.gl-button.btn-default.active {
- box-shadow: inset 0 0 0 1px #a4a3a8, 0 0 0 1px #333, 0 0 0 3px #1f75cb;
+ box-shadow: inset 0 0 0 1px #a4a3a8, 0 0 0 1px #333238, 0 0 0 3px #1f75cb;
outline: none;
background-color: #434248;
}
@@ -613,7 +613,7 @@ html {
font-size: 0.875rem;
font-weight: 400;
padding: 6px 10px;
- background-color: #333;
+ background-color: #333238;
border-color: #434248;
color: #ececef;
color: #ececef;
@@ -625,7 +625,7 @@ html {
}
.btn:active,
.btn.active {
- background-color: #444;
+ background-color: #434248;
border-color: #4f4f4f;
color: #ececef;
}
@@ -649,7 +649,7 @@ html {
position: relative;
}
.dropdown-menu-toggle:active {
- box-shadow: 0 0 0 1px #333, 0 0 0 3px #1f75cb;
+ box-shadow: 0 0 0 1px #333238, 0 0 0 3px #1f75cb;
outline: none;
}
.search-input-container .dropdown-menu {
@@ -657,7 +657,7 @@ html {
}
.dropdown-menu-toggle {
padding: 6px 8px 6px 10px;
- background-color: #333;
+ background-color: #333238;
color: #ececef;
font-size: 14px;
text-align: left;
@@ -689,7 +689,7 @@ html {
font-size: 0.875rem;
font-weight: 400;
padding: 8px 0;
- background-color: #333;
+ background-color: #333238;
border: 1px solid #434248;
border-radius: 0.25rem;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
@@ -722,15 +722,15 @@ html {
}
.dropdown-menu li > a:active,
.dropdown-menu li button:active {
- background-color: #4f4f4f;
+ background-color: #4e4c53;
color: #ececef;
outline: 0;
text-decoration: none;
}
.dropdown-menu li > a:active,
.dropdown-menu li button:active {
- box-shadow: inset 0 0 0 2px #1f75cb, inset 0 0 0 3px #333,
- inset 0 0 0 1px #333;
+ box-shadow: inset 0 0 0 2px #1f75cb, inset 0 0 0 3px #333238,
+ inset 0 0 0 1px #333238;
outline: none;
}
.dropdown-menu .divider {
@@ -765,7 +765,7 @@ html {
input {
border-radius: 0.25rem;
color: #ececef;
- background-color: #333;
+ background-color: #333238;
}
.form-control {
border-radius: 4px;
@@ -1010,7 +1010,7 @@ kbd {
float: left;
margin-right: 5px;
border-radius: 50%;
- border: 1px solid #333;
+ border: 1px solid #333238;
}
.notification-dot {
background-color: #9e5400;
@@ -1049,7 +1049,7 @@ kbd {
}
.context-header .avatar-container {
flex: 0 0 32px;
- background-color: #333;
+ background-color: #333238;
}
.context-header .sidebar-context-title {
overflow: hidden;
@@ -1142,7 +1142,7 @@ kbd {
font-weight: 600;
}
.nav-sidebar li.active:not(.fly-out-top-item) > a:not(.has-sub-items) {
- background-color: rgba(255, 255, 255, 0.08);
+ background-color: rgba(251, 250, 253, 0.08);
}
.nav-sidebar ul {
padding-left: 0;
@@ -1189,7 +1189,7 @@ kbd {
margin-bottom: -0.25rem;
margin-top: 0;
position: relative;
- color: #333;
+ color: #333238;
background: var(--black, #fff);
}
.nav-sidebar
@@ -1417,7 +1417,7 @@ kbd {
.close-nav-button {
height: 48px;
padding: 0 16px;
- background-color: #333238;
+ background-color: #24232a;
border: 0;
color: #89888d;
display: flex;
@@ -1564,7 +1564,7 @@ svg.s16 {
margin-left: 5px;
line-height: 25px;
width: 98%;
- color: #333;
+ color: #333238;
background: none;
}
.search .search-input-container {
@@ -1627,7 +1627,7 @@ svg.s16 {
width: 40px;
height: 40px;
padding: 0;
- background: #222;
+ background: #212027;
overflow: hidden;
box-shadow: inset 0 0 0 1px rgba(251, 250, 253, 0.1);
}
@@ -1792,10 +1792,10 @@ body.gl-dark {
--dark-icon-color-orange-2: #b37a5d;
--gl-text-color: #ececef;
--border-color: #4f4f4f;
- --white: #333;
+ --white: #333238;
--black: #fff;
--gray-light: #333238;
- --svg-status-bg: #333;
+ --svg-status-bg: #333238;
}
.nav-sidebar,
.toggle-sidebar-button,
@@ -1830,7 +1830,7 @@ body.gl-dark .navbar-gitlab .navbar-sub-nav > li.active > button,
body.gl-dark .navbar-gitlab .navbar-nav > li.active > a,
body.gl-dark .navbar-gitlab .navbar-nav > li.active > button {
color: #ececef;
- background-color: #333;
+ background-color: #333238;
}
body.gl-dark .navbar-gitlab .navbar-sub-nav {
color: #ececef;
@@ -1862,10 +1862,10 @@ body.gl-dark
}
body.gl-dark .navbar-gitlab .nav > li.active > a {
color: #ececef;
- background-color: #333;
+ background-color: #333238;
}
body.gl-dark .navbar-gitlab .nav > li.active > a .notification-dot {
- border-color: #333;
+ border-color: #333238;
}
body.gl-dark
.navbar-gitlab
@@ -2036,10 +2036,10 @@ body.gl-dark {
--dark-icon-color-orange-2: #b37a5d;
--gl-text-color: #ececef;
--border-color: #4f4f4f;
- --white: #333;
+ --white: #333238;
--black: #fff;
--gray-light: #333238;
- --svg-status-bg: #333;
+ --svg-status-bg: #333238;
}
.tab-width-8 {
tab-size: 8;
diff --git a/app/assets/stylesheets/startup/startup-general.scss b/app/assets/stylesheets/startup/startup-general.scss
index 7fb373bb6f4..8ac4df55d0b 100644
--- a/app/assets/stylesheets/startup/startup-general.scss
+++ b/app/assets/stylesheets/startup/startup-general.scss
@@ -606,8 +606,8 @@ html {
}
.btn:active,
.btn.active {
- background-color: #eaeaea;
- border-color: #e3e3e3;
+ background-color: #e6e6ea;
+ border-color: #dedee3;
color: #333238;
}
.btn svg {
@@ -1123,7 +1123,7 @@ kbd {
font-weight: 600;
}
.nav-sidebar li.active:not(.fly-out-top-item) > a:not(.has-sub-items) {
- background-color: rgba(0, 0, 0, 0.08);
+ background-color: rgba(31, 30, 36, 0.08);
}
.nav-sidebar ul {
padding-left: 0;
diff --git a/app/assets/stylesheets/startup/startup-signin.scss b/app/assets/stylesheets/startup/startup-signin.scss
index 7ae158b3930..3979488b6cc 100644
--- a/app/assets/stylesheets/startup/startup-signin.scss
+++ b/app/assets/stylesheets/startup/startup-signin.scss
@@ -647,8 +647,8 @@ body.navless {
}
.btn:active,
.btn.active {
- background-color: #eaeaea;
- border-color: #e3e3e3;
+ background-color: #e6e6ea;
+ border-color: #dedee3;
color: #333238;
}
.btn svg {
diff --git a/app/assets/stylesheets/themes/_dark.scss b/app/assets/stylesheets/themes/_dark.scss
index a3474d2ed50..a3738568f9d 100644
--- a/app/assets/stylesheets/themes/_dark.scss
+++ b/app/assets/stylesheets/themes/_dark.scss
@@ -11,6 +11,20 @@ $gray-800: #dcdcde;
$gray-900: #ececef;
$gray-950: #fbfafd;
+$gray-lightest: lighten($gray-10, 1);
+$gray-light: lighten($gray-10, 2);
+$gray-lighter: darken($gray-50, 4);
+$gray-normal: $gray-50;
+$gray-dark: darken($gray-100, 2);
+$gray-darker: darken($gray-200, 2);
+$gray-darkest: $gray-700;
+
+$black: #fff;
+$black-normal: $gray-900;
+$white: $gray-50;
+$white-normal: $gray-50;
+$white-dark: $gray-100;
+
$green-50: #0a4020;
$green-100: #0d532a;
$green-200: #24663b;
@@ -83,21 +97,6 @@ $purple-800: #cbbbf2;
$purple-900: #e1d8f9;
$purple-950: #f4f0ff;
-$gray-lightest: #222;
-$gray-light: $gray-50;
-$gray-lighter: #303030;
-$gray-normal: #333;
-$gray-dark: $gray-100;
-$gray-darker: #4f4f4f;
-$gray-darkest: #c4c4c4;
-
-$black: #fff;
-$black-normal: $gray-900;
-$white: #333;
-$white-light: #2b2b2b;
-$white-normal: #333;
-$white-dark: #444;
-
$theme-indigo-50: #1a1a40;
$border-color: #4f4f4f;
diff --git a/app/services/projects/update_pages_service.rb b/app/services/projects/update_pages_service.rb
index 6a963e7fcd1..0fadd75669e 100644
--- a/app/services/projects/update_pages_service.rb
+++ b/app/services/projects/update_pages_service.rb
@@ -63,16 +63,19 @@ module Projects
end
def build_commit_status
+ stage = create_stage
+
GenericCommitStatus.new(
user: build.user,
ci_stage: stage,
name: 'pages:deploy',
- stage: 'deploy'
+ stage: 'deploy',
+ stage_idx: stage.position
)
end
# rubocop: disable Performance/ActiveRecordSubtransactionMethods
- def stage
+ def create_stage
build.pipeline.stages.safe_find_or_create_by(name: 'deploy', pipeline_id: build.pipeline.id) do |stage|
stage.position = GenericCommitStatus::EXTERNAL_STAGE_IDX
stage.project = build.project
diff --git a/config/metrics/settings/20210216180841_background_upload.yml b/config/metrics/settings/20210216180841_background_upload.yml
index e9d9d475b06..22f7e5e078d 100644
--- a/config/metrics/settings/20210216180841_background_upload.yml
+++ b/config/metrics/settings/20210216180841_background_upload.yml
@@ -7,7 +7,8 @@ product_stage: enablement
product_group: memory
product_category: memory
value_type: boolean
-status: active
+status: broken
+repair_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/382900
time_frame: none
data_source: system
distribution:
diff --git a/config/metrics/settings/20210216180851_background_upload.yml b/config/metrics/settings/20210216180851_background_upload.yml
index b7a0d328b8b..21536e35303 100644
--- a/config/metrics/settings/20210216180851_background_upload.yml
+++ b/config/metrics/settings/20210216180851_background_upload.yml
@@ -8,7 +8,8 @@ product_stage: enablement
product_group: memory
product_category: memory
value_type: boolean
-status: active
+status: broken
+repair_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/382900
time_frame: none
data_source: system
distribution:
diff --git a/config/metrics/settings/20210216180900_background_upload.yml b/config/metrics/settings/20210216180900_background_upload.yml
index ed6931dd443..df93b11c656 100644
--- a/config/metrics/settings/20210216180900_background_upload.yml
+++ b/config/metrics/settings/20210216180900_background_upload.yml
@@ -7,7 +7,8 @@ product_stage: enablement
product_group: memory
product_category: memory
value_type: boolean
-status: active
+status: broken
+repair_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/382900
time_frame: none
data_source: system
distribution:
diff --git a/config/metrics/settings/20210216180909_background_upload.yml b/config/metrics/settings/20210216180909_background_upload.yml
index c18a22d1634..32871d5d30e 100644
--- a/config/metrics/settings/20210216180909_background_upload.yml
+++ b/config/metrics/settings/20210216180909_background_upload.yml
@@ -7,7 +7,8 @@ product_stage: enablement
product_group: memory
product_category: memory
value_type: boolean
-status: active
+status: broken
+repair_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/382900
time_frame: none
data_source: system
distribution:
diff --git a/config/metrics/settings/20210216180918_background_upload.yml b/config/metrics/settings/20210216180918_background_upload.yml
index 940273ff972..186e7c8b2b9 100644
--- a/config/metrics/settings/20210216180918_background_upload.yml
+++ b/config/metrics/settings/20210216180918_background_upload.yml
@@ -7,7 +7,8 @@ product_stage: enablement
product_group: memory
product_category: memory
value_type: boolean
-status: active
+status: broken
+repair_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/382900
time_frame: none
data_source: system
distribution:
diff --git a/db/post_migrate/20221121152048_remove_unused_feedback_migration_index.rb b/db/post_migrate/20221121152048_remove_unused_feedback_migration_index.rb
new file mode 100644
index 00000000000..b5dbafccd3a
--- /dev/null
+++ b/db/post_migrate/20221121152048_remove_unused_feedback_migration_index.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class RemoveUnusedFeedbackMigrationIndex < Gitlab::Database::Migration[2.0]
+ INDEX_NAME = "tmp_idx_for_vulnerability_feedback_migration"
+ WHERE_CLAUSE = "migrated_to_state_transition = false AND feedback_type = 0"
+
+ disable_ddl_transaction!
+
+ def up
+ remove_concurrent_index_by_name(
+ :vulnerability_feedback,
+ INDEX_NAME
+ )
+ end
+
+ def down
+ add_concurrent_index(
+ :vulnerability_feedback,
+ %i[migrated_to_state_transition feedback_type],
+ where: WHERE_CLAUSE,
+ name: INDEX_NAME
+ )
+ end
+end
diff --git a/db/post_migrate/20221121152515_add_supporting_index_for_vulnerabilities_feedback_migration2.rb b/db/post_migrate/20221121152515_add_supporting_index_for_vulnerabilities_feedback_migration2.rb
new file mode 100644
index 00000000000..8c55f2da957
--- /dev/null
+++ b/db/post_migrate/20221121152515_add_supporting_index_for_vulnerabilities_feedback_migration2.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class AddSupportingIndexForVulnerabilitiesFeedbackMigration2 < Gitlab::Database::Migration[2.0]
+ INDEX_NAME = "tmp_idx_for_vulnerability_feedback_migration"
+ WHERE_CLAUSE = "migrated_to_state_transition = false AND feedback_type = 0"
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index(
+ :vulnerability_feedback,
+ :id,
+ where: WHERE_CLAUSE,
+ name: INDEX_NAME
+ )
+ end
+
+ def down
+ remove_concurrent_index_by_name(
+ :vulnerability_feedback,
+ INDEX_NAME
+ )
+ end
+end
diff --git a/db/schema_migrations/20221121152048 b/db/schema_migrations/20221121152048
new file mode 100644
index 00000000000..8d19b1ff54e
--- /dev/null
+++ b/db/schema_migrations/20221121152048
@@ -0,0 +1 @@
+daf3e3b4d3b7b6487542f5cc418b0308bc22da13c0ac6f189ab3fb9352e23898 \ No newline at end of file
diff --git a/db/schema_migrations/20221121152515 b/db/schema_migrations/20221121152515
new file mode 100644
index 00000000000..cb105448807
--- /dev/null
+++ b/db/schema_migrations/20221121152515
@@ -0,0 +1 @@
+23e3d67029b004c63e4c0843ca58556e259c5795075a772043418181335e3349 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 5c208a21ea2..f93c5f65684 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -31408,7 +31408,7 @@ CREATE UNIQUE INDEX taggings_idx ON taggings USING btree (tag_id, taggable_id, t
CREATE UNIQUE INDEX term_agreements_unique_index ON term_agreements USING btree (user_id, term_id);
-CREATE INDEX tmp_idx_for_vulnerability_feedback_migration ON vulnerability_feedback USING btree (migrated_to_state_transition, feedback_type) WHERE ((migrated_to_state_transition = false) AND (feedback_type = 0));
+CREATE INDEX tmp_idx_for_vulnerability_feedback_migration ON vulnerability_feedback USING btree (id) WHERE ((migrated_to_state_transition = false) AND (feedback_type = 0));
CREATE INDEX tmp_idx_vulnerabilities_on_id_where_report_type_7_99 ON vulnerabilities USING btree (id) WHERE (report_type = ANY (ARRAY[7, 99]));
diff --git a/doc/user/project/integrations/webhooks.md b/doc/user/project/integrations/webhooks.md
index 399e9f32ae1..be8b4cfed01 100644
--- a/doc/user/project/integrations/webhooks.md
+++ b/doc/user/project/integrations/webhooks.md
@@ -132,16 +132,15 @@ The feature is not ready for production use.
If a webhook fails repeatedly, it may be disabled automatically.
Webhooks that return response codes in the `5xx` range are understood to be failing
-intermittently, and are temporarily disabled. This lasts initially
-for 10 minutes. If the hook continues to fail, the back-off period is
-extended on each retry, up to a maximum disabled period of 24 hours.
+intermittently and are temporarily disabled. These webhooks are initially disabled
+for 1 minute, which is extended on each retry up to a maximum of 24 hours.
-Webhooks that return failure codes in the `4xx` range are understood to be
-misconfigured, and these are disabled until you manually re-enable
-them. These webhooks are not automatically retried.
+Webhooks that return response codes in the `4xx` range are understood to be
+misconfigured and are permanently disabled until you manually re-enable
+them yourself.
-See [troubleshooting](#troubleshoot-webhooks) for information on
-how to see if a webhook is disabled, and how to re-enable it.
+See [Troubleshooting](#troubleshoot-webhooks) for more information on
+disabled webhooks and how to re-enable them.
## Test a webhook
diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb
index 954b572c9b1..e785d10f7e7 100644
--- a/lib/api/commit_statuses.rb
+++ b/lib/api/commit_statuses.rb
@@ -110,13 +110,22 @@ module API
authorize! :update_pipeline, pipeline
+ # rubocop: disable Performance/ActiveRecordSubtransactionMethods
+ stage = pipeline.stages.safe_find_or_create_by!(name: 'external') do |stage|
+ stage.position = GenericCommitStatus::EXTERNAL_STAGE_IDX
+ stage.project = pipeline.project
+ end
+ # rubocop: enable Performance/ActiveRecordSubtransactionMethods
+
status = GenericCommitStatus.running_or_pending.find_or_initialize_by(
project: user_project,
pipeline: pipeline,
name: name,
ref: ref,
user: current_user,
- protected: user_project.protected_for?(ref)
+ protected: user_project.protected_for?(ref),
+ ci_stage: stage,
+ stage_idx: stage.position
)
updatable_optional_attributes = %w[target_url description coverage]
diff --git a/lib/gitlab/audit/auditor.rb b/lib/gitlab/audit/auditor.rb
index 4a6e4e2e06e..178c6e0be7d 100644
--- a/lib/gitlab/audit/auditor.rb
+++ b/lib/gitlab/audit/auditor.rb
@@ -84,14 +84,23 @@ module Gitlab
end
def record(events)
- log_events(events) unless @stream_only
- send_to_stream(events)
+ @stream_only ? send_to_stream(events) : log_events_and_stream(events)
end
- def log_events(events)
+ def log_events_and_stream(events)
log_authentication_event
- log_to_database(events)
+ saved_events = log_to_database(events)
+
+ # we only want to override events with saved_events when it successfully saves into database.
+ # we are doing so to ensure events in memory reflects events saved in database and have id column.
+ events = saved_events if saved_events.present?
+
+ log_to_file_and_stream(events)
+ end
+
+ def log_to_file_and_stream(events)
log_to_file(events)
+ send_to_stream(events)
end
def audit_enabled?
@@ -145,7 +154,13 @@ module Gitlab
end
def log_to_database(events)
- AuditEvent.bulk_insert!(events)
+ if events.one?
+ events.first.save!
+ events
+ else
+ event_ids = AuditEvent.bulk_insert!(events, returns: :ids)
+ AuditEvent.id_in(event_ids)
+ end
rescue ActiveRecord::RecordInvalid => e
::Gitlab::ErrorTracking.track_exception(e, audit_operation: @name)
end
diff --git a/lib/gitlab/ci/build/context/build.rb b/lib/gitlab/ci/build/context/build.rb
index a1a8e9288c7..a2b330f19b1 100644
--- a/lib/gitlab/ci/build/context/build.rb
+++ b/lib/gitlab/ci/build/context/build.rb
@@ -50,3 +50,5 @@ module Gitlab
end
end
end
+
+Gitlab::Ci::Build::Context::Build.prepend_mod_with('Gitlab::Ci::Build::Context::Build')
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index 82db102e858..238fd9a92cd 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -299,7 +299,7 @@ module Gitlab
object_store: {
enabled: alt_usage_data { config['enabled'] },
direct_upload: alt_usage_data { config['direct_upload'] },
- background_upload: alt_usage_data { config['background_upload'] },
+ background_upload: alt_usage_data { false }, # This setting no longer exists
provider: alt_usage_data { config['connection']['provider'] }
}
}
diff --git a/scripts/undercoverage b/scripts/undercoverage
index 86153671d6a..348f421c0d5 100755
--- a/scripts/undercoverage
+++ b/scripts/undercoverage
@@ -21,6 +21,13 @@ end
compare_base = ARGV[0]
compare_base ||= IO.popen(%w(git merge-base origin/master HEAD)) { |p| p.read.chomp }
+coverage_file_path = 'coverage/lcov/gitlab.lcov'
+
+result = if File.exist?(coverage_file_path)
+ Undercover::CLI.run(%W(-c #{compare_base}))
+ else
+ warn "#{coverage_file_path} doesn't exist"
+ 0
+ end
-result = Undercover::CLI.run(%W(-c #{compare_base}))
exit result
diff --git a/spec/frontend/issues/list/components/issues_list_app_spec.js b/spec/frontend/issues/list/components/issues_list_app_spec.js
index d0c93c896b3..eb72968cb18 100644
--- a/spec/frontend/issues/list/components/issues_list_app_spec.js
+++ b/spec/frontend/issues/list/components/issues_list_app_spec.js
@@ -61,7 +61,7 @@ import {
TOKEN_TYPE_TYPE,
} from '~/vue_shared/components/filtered_search_bar/constants';
-import('~/issuable/bulk_update_sidebar');
+import('~/issuable');
import('~/users_select');
jest.mock('@sentry/browser');
diff --git a/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js b/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js
index 458c1c3f858..33a3a6eddfc 100644
--- a/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js
+++ b/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js
@@ -1,10 +1,11 @@
-import { GlTab } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
import merge from 'lodash/merge';
+import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { trackIncidentDetailsViewsOptions } from '~/incidents/constants';
import DescriptionComponent from '~/issues/show/components/description.vue';
import HighlightBar from '~/issues/show/components/incidents/highlight_bar.vue';
-import IncidentTabs from '~/issues/show/components/incidents/incident_tabs.vue';
+import IncidentTabs, {
+ incidentTabsI18n,
+} from '~/issues/show/components/incidents/incident_tabs.vue';
import INVALID_URL from '~/lib/utils/invalid_url';
import Tracking from '~/tracking';
import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue';
@@ -16,11 +17,24 @@ const mockAlert = {
iid: '1',
};
+const defaultMocks = {
+ $apollo: {
+ queries: {
+ alert: {
+ loading: true,
+ },
+ timelineEvents: {
+ loading: false,
+ },
+ },
+ },
+};
+
describe('Incident Tabs component', () => {
let wrapper;
- const mountComponent = (data = {}, options = {}) => {
- wrapper = shallowMount(
+ const mountComponent = ({ data = {}, options = {}, mount = shallowMountExtended } = {}) => {
+ wrapper = mount(
IncidentTabs,
merge(
{
@@ -29,7 +43,7 @@ describe('Incident Tabs component', () => {
},
stubs: {
DescriptionComponent: true,
- MetricsTab: true,
+ IncidentMetricTab: true,
},
provide: {
fullPath: '',
@@ -37,41 +51,37 @@ describe('Incident Tabs component', () => {
projectId: '',
issuableId: '',
uploadMetricsFeatureAvailable: true,
+ slaFeatureAvailable: true,
+ canUpdate: true,
+ canUpdateTimelineEvent: true,
},
data() {
return { alert: mockAlert, ...data };
},
- mocks: {
- $apollo: {
- queries: {
- alert: {
- loading: true,
- },
- timelineEvents: {
- loading: false,
- },
- },
- },
- },
+ mocks: defaultMocks,
},
options,
),
);
};
- const findTabs = () => wrapper.findAllComponents(GlTab);
- const findSummaryTab = () => findTabs().at(0);
- const findAlertDetailsTab = () => wrapper.find('[data-testid="alert-details-tab"]');
+ const findSummaryTab = () => wrapper.findByTestId('summary-tab');
+ const findTimelineTab = () => wrapper.findByTestId('timeline-tab');
+ const findAlertDetailsTab = () => wrapper.findByTestId('alert-details-tab');
const findAlertDetailsComponent = () => wrapper.findComponent(AlertDetailsTable);
const findDescriptionComponent = () => wrapper.findComponent(DescriptionComponent);
const findHighlightBarComponent = () => wrapper.findComponent(HighlightBar);
+ const findTabButtonByFilter = (filter) => wrapper.findAllByRole('tab').filter(filter);
+ const findTimelineTabButton = () =>
+ findTabButtonByFilter((inner) => inner.text() === incidentTabsI18n.timelineTitle).at(0);
+ const findActiveTabs = () => findTabButtonByFilter((inner) => inner.classes('active'));
- describe('empty state', () => {
+ describe('with no alerts', () => {
beforeEach(() => {
- mountComponent({ alert: null });
+ mountComponent({ data: { alert: null } });
});
- it('does not show the alert details tab', () => {
+ it('does not show the alert details tab option', () => {
expect(findAlertDetailsComponent().exists()).toBe(false);
});
});
@@ -83,7 +93,12 @@ describe('Incident Tabs component', () => {
it('renders the summary tab', () => {
expect(findSummaryTab().exists()).toBe(true);
- expect(findSummaryTab().attributes('title')).toBe('Summary');
+ expect(findSummaryTab().attributes('title')).toBe(incidentTabsI18n.summaryTitle);
+ });
+
+ it('renders the timeline tab', () => {
+ expect(findTimelineTab().exists()).toBe(true);
+ expect(findTimelineTab().attributes('title')).toBe(incidentTabsI18n.timelineTitle);
});
it('renders the alert details tab', () => {
@@ -125,4 +140,22 @@ describe('Incident Tabs component', () => {
expect(Tracking.event).toHaveBeenCalledWith(category, action);
});
});
+
+ describe('tab changing', () => {
+ beforeEach(() => {
+ mountComponent({ mount: mountExtended });
+ });
+
+ it('shows only the summary tab by default', async () => {
+ expect(findActiveTabs()).toHaveLength(1);
+ expect(findActiveTabs().at(0).text()).toBe(incidentTabsI18n.summaryTitle);
+ });
+
+ it("shows the timeline tab after it's clicked", async () => {
+ await findTimelineTabButton().trigger('click');
+
+ expect(findActiveTabs()).toHaveLength(1);
+ expect(findActiveTabs().at(0).text()).toBe(incidentTabsI18n.timelineTitle);
+ });
+ });
});
diff --git a/spec/frontend/sidebar/assignee_title_spec.js b/spec/frontend/sidebar/components/assignees/assignee_title_spec.js
index 14a6bdbf907..14a6bdbf907 100644
--- a/spec/frontend/sidebar/assignee_title_spec.js
+++ b/spec/frontend/sidebar/components/assignees/assignee_title_spec.js
diff --git a/spec/frontend/sidebar/assignees_realtime_spec.js b/spec/frontend/sidebar/components/assignees/assignees_realtime_spec.js
index ae8f07bf901..5b6f4d3b557 100644
--- a/spec/frontend/sidebar/assignees_realtime_spec.js
+++ b/spec/frontend/sidebar/components/assignees/assignees_realtime_spec.js
@@ -11,7 +11,7 @@ import Mock, {
issuableQueryResponse,
subscriptionNullResponse,
subscriptionResponse,
-} from './mock_data';
+} from '../../mock_data';
Vue.use(VueApollo);
diff --git a/spec/frontend/sidebar/assignees_spec.js b/spec/frontend/sidebar/components/assignees/assignees_spec.js
index 7cf7fd33022..6971ae2f9ed 100644
--- a/spec/frontend/sidebar/assignees_spec.js
+++ b/spec/frontend/sidebar/components/assignees/assignees_spec.js
@@ -5,7 +5,7 @@ import { trimText } from 'helpers/text_helper';
import UsersMockHelper from 'helpers/user_mock_data_helper';
import Assignee from '~/sidebar/components/assignees/assignees.vue';
import AssigneeAvatarLink from '~/sidebar/components/assignees/assignee_avatar_link.vue';
-import UsersMock from './mock_data';
+import UsersMock from '../../mock_data';
describe('Assignee component', () => {
const getDefaultProps = () => ({
diff --git a/spec/frontend/sidebar/issuable_assignees_spec.js b/spec/frontend/sidebar/components/assignees/issuable_assignees_spec.js
index 1161fefcc64..1161fefcc64 100644
--- a/spec/frontend/sidebar/issuable_assignees_spec.js
+++ b/spec/frontend/sidebar/components/assignees/issuable_assignees_spec.js
diff --git a/spec/frontend/sidebar/sidebar_assignees_spec.js b/spec/frontend/sidebar/components/assignees/sidebar_assignees_spec.js
index 2cb2425532b..58b174059fa 100644
--- a/spec/frontend/sidebar/sidebar_assignees_spec.js
+++ b/spec/frontend/sidebar/components/assignees/sidebar_assignees_spec.js
@@ -8,7 +8,7 @@ import SidebarAssignees from '~/sidebar/components/assignees/sidebar_assignees.v
import SidebarService from '~/sidebar/services/sidebar_service';
import SidebarMediator from '~/sidebar/sidebar_mediator';
import SidebarStore from '~/sidebar/stores/sidebar_store';
-import Mock from './mock_data';
+import Mock from '../../mock_data';
describe('sidebar assignees', () => {
let wrapper;
diff --git a/spec/frontend/sidebar/components/copy_email_to_clipboard_spec.js b/spec/frontend/sidebar/components/copy_email/copy_email_to_clipboard_spec.js
index 69a8d645973..9f94a1b3f3a 100644
--- a/spec/frontend/sidebar/components/copy_email_to_clipboard_spec.js
+++ b/spec/frontend/sidebar/components/copy_email/copy_email_to_clipboard_spec.js
@@ -1,5 +1,5 @@
import { shallowMount } from '@vue/test-utils';
-import CopyEmailToClipboard from '~/sidebar/components/copy_email_to_clipboard.vue';
+import CopyEmailToClipboard from '~/sidebar/components/copy_email/copy_email_to_clipboard.vue';
import CopyableField from '~/vue_shared/components/sidebar/copyable_field.vue';
describe('CopyEmailToClipboard component', () => {
diff --git a/spec/frontend/sidebar/components/crm_contacts_spec.js b/spec/frontend/sidebar/components/crm_contacts/crm_contacts_spec.js
index 6d76fa1f9df..2281b38cc53 100644
--- a/spec/frontend/sidebar/components/crm_contacts_spec.js
+++ b/spec/frontend/sidebar/components/crm_contacts/crm_contacts_spec.js
@@ -11,7 +11,7 @@ import {
getIssueCrmContactsQueryResponse,
issueCrmContactsUpdateResponse,
issueCrmContactsUpdateNullResponse,
-} from './mock_data';
+} from '../mock_data';
jest.mock('~/flash');
diff --git a/spec/frontend/sidebar/lock/__snapshots__/edit_form_spec.js.snap b/spec/frontend/sidebar/components/lock/__snapshots__/edit_form_spec.js.snap
index 18d4df297df..18d4df297df 100644
--- a/spec/frontend/sidebar/lock/__snapshots__/edit_form_spec.js.snap
+++ b/spec/frontend/sidebar/components/lock/__snapshots__/edit_form_spec.js.snap
diff --git a/spec/frontend/sidebar/lock/constants.js b/spec/frontend/sidebar/components/lock/constants.js
index b9f08e9286d..b9f08e9286d 100644
--- a/spec/frontend/sidebar/lock/constants.js
+++ b/spec/frontend/sidebar/components/lock/constants.js
diff --git a/spec/frontend/sidebar/lock/edit_form_buttons_spec.js b/spec/frontend/sidebar/components/lock/edit_form_buttons_spec.js
index 2abb0c24d7d..2abb0c24d7d 100644
--- a/spec/frontend/sidebar/lock/edit_form_buttons_spec.js
+++ b/spec/frontend/sidebar/components/lock/edit_form_buttons_spec.js
diff --git a/spec/frontend/sidebar/lock/edit_form_spec.js b/spec/frontend/sidebar/components/lock/edit_form_spec.js
index 4ae9025ee39..4ae9025ee39 100644
--- a/spec/frontend/sidebar/lock/edit_form_spec.js
+++ b/spec/frontend/sidebar/components/lock/edit_form_spec.js
diff --git a/spec/frontend/sidebar/lock/issuable_lock_form_spec.js b/spec/frontend/sidebar/components/lock/issuable_lock_form_spec.js
index 8f825847cfc..8f825847cfc 100644
--- a/spec/frontend/sidebar/lock/issuable_lock_form_spec.js
+++ b/spec/frontend/sidebar/components/lock/issuable_lock_form_spec.js
diff --git a/spec/frontend/issuable/bulk_update_sidebar/components/move_issues_button_spec.js b/spec/frontend/sidebar/components/move/move_issues_button_spec.js
index c432d722637..4eed5785977 100644
--- a/spec/frontend/issuable/bulk_update_sidebar/components/move_issues_button_spec.js
+++ b/spec/frontend/sidebar/components/move/move_issues_button_spec.js
@@ -9,9 +9,9 @@ import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import createFlash from '~/flash';
import { logError } from '~/lib/logger';
import IssuableMoveDropdown from '~/vue_shared/components/sidebar/issuable_move_dropdown.vue';
-import MoveIssuesButton from '~/issuable/bulk_update_sidebar/components/move_issues_button.vue';
import issuableEventHub from '~/issues/list/eventhub';
-import moveIssueMutation from '~/issuable/bulk_update_sidebar/components/graphql/mutations/move_issue.mutation.graphql';
+import MoveIssuesButton from '~/sidebar/components/move/move_issues_button.vue';
+import moveIssueMutation from '~/sidebar/queries/move_issue.mutation.graphql';
import getIssuesQuery from 'ee_else_ce/issues/list/queries/get_issues.query.graphql';
import getIssuesCountsQuery from 'ee_else_ce/issues/list/queries/get_issues_counts.query.graphql';
import { getIssuesCountsQueryResponse, getIssuesQueryResponse } from 'jest/issues/list/mock_data';
diff --git a/spec/frontend/sidebar/participants_spec.js b/spec/frontend/sidebar/components/participants/participants_spec.js
index f7a626a189c..f7a626a189c 100644
--- a/spec/frontend/sidebar/participants_spec.js
+++ b/spec/frontend/sidebar/components/participants/participants_spec.js
diff --git a/spec/frontend/sidebar/reviewer_title_spec.js b/spec/frontend/sidebar/components/reviewers/reviewer_title_spec.js
index 68ecd62e4c6..68ecd62e4c6 100644
--- a/spec/frontend/sidebar/reviewer_title_spec.js
+++ b/spec/frontend/sidebar/components/reviewers/reviewer_title_spec.js
diff --git a/spec/frontend/sidebar/reviewers_spec.js b/spec/frontend/sidebar/components/reviewers/reviewers_spec.js
index 229f7ffbe04..229f7ffbe04 100644
--- a/spec/frontend/sidebar/reviewers_spec.js
+++ b/spec/frontend/sidebar/components/reviewers/reviewers_spec.js
diff --git a/spec/frontend/issuable/bulk_update_sidebar/components/status_dropdown_spec.js b/spec/frontend/sidebar/components/status/status_dropdown_spec.js
index 2f281cb88f9..5a75299c3a4 100644
--- a/spec/frontend/issuable/bulk_update_sidebar/components/status_dropdown_spec.js
+++ b/spec/frontend/sidebar/components/status/status_dropdown_spec.js
@@ -1,7 +1,7 @@
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import StatusDropdown from '~/issuable/bulk_update_sidebar/components/status_dropdown.vue';
-import { statusDropdownOptions } from '~/issuable/bulk_update_sidebar/constants';
+import StatusDropdown from '~/sidebar/components/status/status_dropdown.vue';
+import { statusDropdownOptions } from '~/sidebar/constants';
describe('SubscriptionsDropdown component', () => {
let wrapper;
diff --git a/spec/frontend/issuable/bulk_update_sidebar/components/subscriptions_dropdown_spec.js b/spec/frontend/sidebar/components/subscriptions/subscriptions_dropdown_spec.js
index 56ef7a1ed39..3fb8214606c 100644
--- a/spec/frontend/issuable/bulk_update_sidebar/components/subscriptions_dropdown_spec.js
+++ b/spec/frontend/sidebar/components/subscriptions/subscriptions_dropdown_spec.js
@@ -1,8 +1,8 @@
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
-import SubscriptionsDropdown from '~/issuable/bulk_update_sidebar/components/subscriptions_dropdown.vue';
-import { subscriptionsDropdownOptions } from '~/issuable/bulk_update_sidebar/constants';
+import SubscriptionsDropdown from '~/sidebar/components/subscriptions/subscriptions_dropdown.vue';
+import { subscriptionsDropdownOptions } from '~/sidebar/constants';
describe('SubscriptionsDropdown component', () => {
let wrapper;
diff --git a/spec/frontend/sidebar/subscriptions_spec.js b/spec/frontend/sidebar/components/subscriptions/subscriptions_spec.js
index 1a1aa370eef..1a1aa370eef 100644
--- a/spec/frontend/sidebar/subscriptions_spec.js
+++ b/spec/frontend/sidebar/components/subscriptions/subscriptions_spec.js
diff --git a/spec/frontend/sidebar/__snapshots__/todo_spec.js.snap b/spec/frontend/sidebar/components/todo_toggle/__snapshots__/todo_spec.js.snap
index 846f45345e7..846f45345e7 100644
--- a/spec/frontend/sidebar/__snapshots__/todo_spec.js.snap
+++ b/spec/frontend/sidebar/components/todo_toggle/__snapshots__/todo_spec.js.snap
diff --git a/spec/frontend/sidebar/todo_spec.js b/spec/frontend/sidebar/components/todo_toggle/todo_spec.js
index 8e6597bf80f..8e6597bf80f 100644
--- a/spec/frontend/sidebar/todo_spec.js
+++ b/spec/frontend/sidebar/components/todo_toggle/todo_spec.js
diff --git a/spec/frontend/sidebar/sidebar_move_issue_spec.js b/spec/frontend/sidebar/lib/sidebar_move_issue_spec.js
index 195cc6ddeeb..6e365df329b 100644
--- a/spec/frontend/sidebar/sidebar_move_issue_spec.js
+++ b/spec/frontend/sidebar/lib/sidebar_move_issue_spec.js
@@ -8,7 +8,7 @@ import SidebarService from '~/sidebar/services/sidebar_service';
import SidebarMediator from '~/sidebar/sidebar_mediator';
import SidebarStore from '~/sidebar/stores/sidebar_store';
import { GitLabDropdown } from '~/deprecated_jquery_dropdown/gl_dropdown';
-import Mock from './mock_data';
+import Mock from '../mock_data';
jest.mock('~/flash');
diff --git a/spec/frontend/sidebar/sidebar_store_spec.js b/spec/frontend/sidebar/stores/sidebar_store_spec.js
index 3930dabfcfa..3f4b80409c2 100644
--- a/spec/frontend/sidebar/sidebar_store_spec.js
+++ b/spec/frontend/sidebar/stores/sidebar_store_spec.js
@@ -1,6 +1,6 @@
import UsersMockHelper from 'helpers/user_mock_data_helper';
import SidebarStore from '~/sidebar/stores/sidebar_store';
-import Mock from './mock_data';
+import Mock from '../mock_data';
const ASSIGNEE = {
id: 2,
diff --git a/spec/lib/gitlab/audit/auditor_spec.rb b/spec/lib/gitlab/audit/auditor_spec.rb
index f743515e616..4b16333d913 100644
--- a/spec/lib/gitlab/audit/auditor_spec.rb
+++ b/spec/lib/gitlab/audit/auditor_spec.rb
@@ -68,6 +68,7 @@ RSpec.describe Gitlab::Audit::Auditor do
expect(logger).to have_received(:info).with(
hash_including(
+ 'id' => AuditEvent.last.id,
'author_id' => author.id,
'author_name' => author.name,
'entity_id' => group.id,
@@ -112,6 +113,7 @@ RSpec.describe Gitlab::Audit::Auditor do
expect(logger).to have_received(:info).with(
hash_including(
+ 'id' => AuditEvent.last.id,
'author_id' => author.id,
'author_name' => author.name,
'entity_id' => group.id,
@@ -244,7 +246,9 @@ RSpec.describe Gitlab::Audit::Auditor do
let(:audit!) { auditor.audit(context) }
before do
- allow(AuditEvent).to receive(:bulk_insert!).and_raise(ActiveRecord::RecordInvalid)
+ expect_next_instance_of(AuditEvent) do |instance|
+ allow(instance).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
+ end
allow(Gitlab::ErrorTracking).to receive(:track_exception)
end
@@ -261,5 +265,27 @@ RSpec.describe Gitlab::Audit::Auditor do
expect { auditor.audit(context) }.not_to raise_exception
end
end
+
+ context 'when audit event is not saved in database due to some database infra issue' do
+ let(:audit!) { auditor.audit(context) }
+
+ before do
+ allow_any_instance_of(auditor) do |auditor_instance|
+ allow(auditor_instance).to receive(:log_to_database).and_return(nil)
+ end
+ end
+
+ it 'calls log_to_file_and_stream with in memory events' do
+ audit!
+
+ expect_any_instance_of(auditor) do |auditor_instance|
+ expect(auditor_instance).to receive(:log_to_file_and_stream).with(include(kind_of(AuditEvent)))
+ end
+ end
+
+ it 'does not throw exception' do
+ expect { auditor.audit(context) }.not_to raise_exception
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 1418adb535f..79cd9ffc950 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -598,7 +598,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
external_diffs: { enabled: false },
lfs: { enabled: true, object_store: { enabled: false, direct_upload: true, background_upload: false, provider: "AWS" } },
uploads: { enabled: nil, object_store: { enabled: false, direct_upload: true, background_upload: false, provider: "AWS" } },
- packages: { enabled: true, object_store: { enabled: false, direct_upload: false, background_upload: true, provider: "AWS" } } }
+ packages: { enabled: true, object_store: { enabled: false, direct_upload: false, background_upload: false, provider: "AWS" } } }
)
end
diff --git a/spec/requests/api/commit_statuses_spec.rb b/spec/requests/api/commit_statuses_spec.rb
index dc5d9620dc4..8cfac4b736f 100644
--- a/spec/requests/api/commit_statuses_spec.rb
+++ b/spec/requests/api/commit_statuses_spec.rb
@@ -167,7 +167,7 @@ RSpec.describe API::CommitStatuses do
let!(:pipeline) { create(:ci_pipeline, project: project, sha: sha, ref: 'ref') }
let(:params) { { state: 'pending' } }
- shared_examples_for 'creates a commit status for the existing pipeline' do
+ shared_examples_for 'creates a commit status for the existing pipeline with an external stage' do
it do
expect do
post api(post_url, developer), params: params
@@ -176,19 +176,73 @@ RSpec.describe API::CommitStatuses do
job = pipeline.statuses.find_by_name(json_response['name'])
expect(response).to have_gitlab_http_status(:created)
+ expect(job.ci_stage.name).to eq('external')
+ expect(job.ci_stage.position).to eq(GenericCommitStatus::EXTERNAL_STAGE_IDX)
+ expect(job.ci_stage.pipeline).to eq(pipeline)
expect(job.status).to eq('pending')
expect(job.stage_idx).to eq(GenericCommitStatus::EXTERNAL_STAGE_IDX)
end
end
- it_behaves_like 'creates a commit status for the existing pipeline'
+ shared_examples_for 'updates the commit status with an external stage' do
+ before do
+ post api(post_url, developer), params: { state: 'pending' }
+ end
+
+ it 'updates the commit status with the external stage' do
+ post api(post_url, developer), params: { state: 'running' }
+ job = pipeline.statuses.find_by_name(json_response['name'])
+
+ expect(job.ci_stage.name).to eq('external')
+ expect(job.ci_stage.position).to eq(GenericCommitStatus::EXTERNAL_STAGE_IDX)
+ expect(job.ci_stage.pipeline).to eq(pipeline)
+ expect(job.status).to eq('running')
+ expect(job.stage_idx).to eq(GenericCommitStatus::EXTERNAL_STAGE_IDX)
+ end
+ end
context 'with pipeline for merge request' do
let!(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline, source_project: project) }
let!(:pipeline) { merge_request.all_pipelines.last }
let(:sha) { pipeline.sha }
- it_behaves_like 'creates a commit status for the existing pipeline'
+ it_behaves_like 'creates a commit status for the existing pipeline with an external stage'
+ end
+
+ context 'when an external stage does not exist' do
+ context 'when the commit status does not exist' do
+ it_behaves_like 'creates a commit status for the existing pipeline with an external stage'
+ end
+
+ context 'when the commit status exists' do
+ it_behaves_like 'updates the commit status with an external stage'
+ end
+ end
+
+ context 'when an external stage already exists' do
+ let(:stage) { create(:ci_stage, name: 'external', pipeline: pipeline, position: 1_000_000) }
+
+ context 'when the commit status exists' do
+ it_behaves_like 'updates the commit status with an external stage'
+ end
+
+ context 'when the commit status does not exist' do
+ it_behaves_like 'creates a commit status for the existing pipeline with an external stage'
+ end
+ end
+ end
+
+ context 'when the pipeline does not exist' do
+ it 'creates a commit status and a stage' do
+ expect do
+ post api(post_url, developer), params: { state: 'pending' }
+ end.to change { Ci::Pipeline.count }.by(1)
+ job = Ci::Pipeline.last.statuses.find_by_name(json_response['name'])
+
+ expect(job.ci_stage.name).to eq('external')
+ expect(job.ci_stage.position).to eq(GenericCommitStatus::EXTERNAL_STAGE_IDX)
+ expect(job.status).to eq('pending')
+ expect(job.stage_idx).to eq(GenericCommitStatus::EXTERNAL_STAGE_IDX)
end
end
end
diff --git a/spec/services/ci/pipelines/add_job_service_spec.rb b/spec/services/ci/pipelines/add_job_service_spec.rb
index e735b2752d9..c62aa9506bd 100644
--- a/spec/services/ci/pipelines/add_job_service_spec.rb
+++ b/spec/services/ci/pipelines/add_job_service_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Ci::Pipelines::AddJobService do
include ExclusiveLeaseHelpers
- let_it_be(:pipeline) { create(:ci_pipeline) }
+ let_it_be_with_reload(:pipeline) { create(:ci_pipeline) }
let(:job) { build(:ci_build) }
@@ -35,7 +35,7 @@ RSpec.describe Ci::Pipelines::AddJobService do
end
it 'assigns partition_id to job and metadata' do
- pipeline.partition_id = 123
+ pipeline.partition_id = ci_testing_partition_id
expect { execute }
.to change(job, :partition_id).to(pipeline.partition_id)
diff --git a/spec/services/projects/update_pages_service_spec.rb b/spec/services/projects/update_pages_service_spec.rb
index a69db3b9970..d908a169898 100644
--- a/spec/services/projects/update_pages_service_spec.rb
+++ b/spec/services/projects/update_pages_service_spec.rb
@@ -320,10 +320,11 @@ RSpec.describe Projects::UpdatePagesService do
end
context 'when retrying the job' do
+ let(:stage) { create(:ci_stage, position: 1_000_000, name: 'deploy', pipeline: pipeline) }
let!(:older_deploy_job) do
create(:generic_commit_status, :failed, pipeline: pipeline,
ref: build.ref,
- stage: 'deploy',
+ ci_stage: stage,
name: 'pages:deploy')
end
@@ -337,13 +338,15 @@ RSpec.describe Projects::UpdatePagesService do
expect(execute).to eq(:success)
expect(older_deploy_job.reload).to be_retried
+ expect(deploy_status.ci_stage).to eq(stage)
+ expect(deploy_status.stage_idx).to eq(stage.position)
end
end
private
def deploy_status
- GenericCommitStatus.find_by(name: 'pages:deploy')
+ GenericCommitStatus.where(name: 'pages:deploy').last
end
def execute