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>2023-12-12 18:13:14 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-12-12 18:13:14 +0300
commit86a3b1b3ae2115c6ab7b9d492e9c89ac70963d3a (patch)
treec78266705382f28d08786303ea57525ec1e2a2cf
parent7045d3816aa7bab6619e9d841f45d5cb8d454f23 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/ci/qa.gitlab-ci.yml9
-rw-r--r--.rubocop_todo/gitlab/namespaced_class.yml1
-rw-r--r--.rubocop_todo/rspec/context_wording.yml1
-rw-r--r--app/assets/javascripts/feature_highlight/constants.js1
-rw-r--r--app/assets/javascripts/feature_highlight/feature_highlight_helper.js19
-rw-r--r--app/assets/javascripts/feature_highlight/feature_highlight_popover.vue95
-rw-r--r--app/assets/javascripts/feature_highlight/index.js28
-rw-r--r--app/assets/javascripts/main.js2
-rw-r--r--app/assets/javascripts/notifications/constants.js1
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue9
-rw-r--r--app/assets/stylesheets/framework.scss1
-rw-r--r--app/assets/stylesheets/framework/awards.scss4
-rw-r--r--app/assets/stylesheets/framework/blocks.scss8
-rw-r--r--app/assets/stylesheets/framework/buttons.scss4
-rw-r--r--app/assets/stylesheets/framework/common.scss2
-rw-r--r--app/assets/stylesheets/framework/feature_highlight.scss53
-rw-r--r--app/assets/stylesheets/framework/sidebar.scss8
-rw-r--r--app/assets/stylesheets/framework/typography.scss6
-rw-r--r--app/assets/stylesheets/framework/variables.scss11
-rw-r--r--app/assets/stylesheets/mailers/highlighted_diff_email.scss2
-rw-r--r--app/assets/stylesheets/page_bundles/_ide_monaco_overrides.scss2
-rw-r--r--app/assets/stylesheets/page_bundles/_ide_theme_overrides.scss8
-rw-r--r--app/assets/stylesheets/page_bundles/ide.scss44
-rw-r--r--app/assets/stylesheets/page_bundles/milestone.scss2
-rw-r--r--app/assets/stylesheets/page_bundles/pipelines.scss2
-rw-r--r--app/assets/stylesheets/pages/commits.scss4
-rw-r--r--app/assets/stylesheets/pages/groups.scss4
-rw-r--r--app/assets/stylesheets/pages/issues.scss4
-rw-r--r--app/assets/stylesheets/pages/notes.scss2
-rw-r--r--app/assets/stylesheets/print.scss2
-rw-r--r--app/assets/stylesheets/snippets.scss2
-rw-r--r--app/assets/stylesheets/themes/_dark.scss3
-rw-r--r--app/assets/stylesheets/themes/dark_mode_overrides.scss1
-rw-r--r--app/mailers/emails/merge_requests.rb2
-rw-r--r--app/models/notification_recipient.rb2
-rw-r--r--app/models/notification_setting.rb3
-rw-r--r--app/models/todo.rb4
-rw-r--r--app/services/bulk_imports/file_download_service.rb1
-rw-r--r--app/services/bulk_imports/process_service.rb9
-rw-r--r--app/workers/bulk_imports/entity_worker.rb31
-rw-r--r--app/workers/bulk_imports/export_request_worker.rb24
-rw-r--r--app/workers/bulk_imports/finish_batched_pipeline_worker.rb11
-rw-r--r--app/workers/bulk_imports/pipeline_worker.rb20
-rw-r--r--app/workers/bulk_imports/stuck_import_worker.rb6
-rw-r--r--config/sidekiq_queues.yml2
-rw-r--r--db/docs/batched_background_migrations/backfill_dismissal_reason_in_vulnerability_reads.yml1
-rw-r--r--db/docs/batched_background_migrations/fix_allow_descendants_override_disabled_shared_runners.yml4
-rw-r--r--db/migrate/20231114152304_add_approver_to_notification_settings.rb10
-rw-r--r--db/post_migrate/20231207163648_re_finalize_backfill_dismissal_reason_in_vulnerability_reads.rb21
-rw-r--r--db/post_migrate/20231207221159_finalize_fix_allow_descendants_override_disabled_shared_runners.rb21
-rw-r--r--db/schema_migrations/202311141523041
-rw-r--r--db/schema_migrations/202312071636481
-rw-r--r--db/schema_migrations/202312072211591
-rw-r--r--db/structure.sql3
-rw-r--r--doc/administration/monitoring/prometheus/gitlab_metrics.md1
-rw-r--r--doc/administration/settings/slack_app.md2
-rw-r--r--doc/api/graphql/reference/index.md2
-rw-r--r--doc/ci/runners/configure_runners.md34
-rw-r--r--doc/user/project/integrations/gitlab_slack_app_troubleshooting.md48
-rw-r--r--doc/user/project/integrations/gitlab_slack_application.md43
-rw-r--r--gems/gitlab-secret_detection/lib/gitlab/secret_detection.rb1
-rw-r--r--gems/gitlab-secret_detection/lib/gitlab/secret_detection/finding.rb10
-rw-r--r--gems/gitlab-secret_detection/lib/gitlab/secret_detection/scan.rb65
-rw-r--r--gems/gitlab-secret_detection/lib/gitlab/secret_detection/status.rb2
-rw-r--r--gems/gitlab-secret_detection/spec/lib/gitlab/secret_detection/scan_spec.rb77
-rw-r--r--lib/bulk_imports/common/pipelines/entity_finisher.rb9
-rw-r--r--lib/bulk_imports/logger.rb49
-rw-r--r--lib/bulk_imports/pipeline/runner.rb8
-rw-r--r--locale/gitlab.pot36
-rw-r--r--qa/.confiner/master.yml15
-rw-r--r--qa/Gemfile2
-rw-r--r--qa/Gemfile.lock4
-rw-r--r--spec/frontend/feature_highlight/feature_highlight_helper_spec.js42
-rw-r--r--spec/frontend/feature_highlight/feature_highlight_popover_spec.js75
-rw-r--r--spec/frontend/vue_merge_request_widget/components/states/mr_widget_ready_to_merge_spec.js79
-rw-r--r--spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb9
-rw-r--r--spec/lib/bulk_imports/common/pipelines/lfs_objects_pipeline_spec.rb2
-rw-r--r--spec/lib/bulk_imports/logger_spec.rb49
-rw-r--r--spec/lib/bulk_imports/pipeline/runner_spec.rb16
-rw-r--r--spec/models/notification_recipient_spec.rb4
-rw-r--r--spec/models/notification_setting_spec.rb6
-rw-r--r--spec/services/bulk_imports/file_download_service_spec.rb1
-rw-r--r--spec/services/bulk_imports/process_service_spec.rb16
-rw-r--r--spec/workers/bulk_imports/entity_worker_spec.rb2
-rw-r--r--spec/workers/bulk_imports/export_request_worker_spec.rb13
-rw-r--r--spec/workers/bulk_imports/finish_batched_pipeline_worker_spec.rb6
-rw-r--r--spec/workers/bulk_imports/pipeline_worker_spec.rb72
-rw-r--r--spec/workers/bulk_imports/stuck_import_worker_spec.rb16
88 files changed, 576 insertions, 763 deletions
diff --git a/.gitlab/ci/qa.gitlab-ci.yml b/.gitlab/ci/qa.gitlab-ci.yml
index cbb68985bb4..d26df15412f 100644
--- a/.gitlab/ci/qa.gitlab-ci.yml
+++ b/.gitlab/ci/qa.gitlab-ci.yml
@@ -53,15 +53,6 @@ qa:internal-as-if-foss:
- .qa:rules:internal-as-if-foss
- .as-if-foss
-qa:master-auto-quarantine-dequarantine:
- extends:
- - .qa-job-base
- rules:
- - if: '$QA_TRIGGER_AUTO_QUARANTINE =~ /true|yes|1/i'
- script:
- - bundle exec confiner -r .confiner/master.yml
- allow_failure: true
-
cache-qa-gems:
extends:
- .qa-job-base
diff --git a/.rubocop_todo/gitlab/namespaced_class.yml b/.rubocop_todo/gitlab/namespaced_class.yml
index f1f86122067..4d3c8eb4a90 100644
--- a/.rubocop_todo/gitlab/namespaced_class.yml
+++ b/.rubocop_todo/gitlab/namespaced_class.yml
@@ -1059,6 +1059,7 @@ Gitlab/NamespacedClass:
- 'ee/lib/gitlab/proxy.rb'
- 'ee/lib/gitlab/return_to_location.rb'
- 'ee/lib/gitlab/update_mirror_service_json_logger.rb'
+ - 'ee/lib/gitlab/secret_detection_logger.rb'
- 'ee/spec/support/elastic_query_name_inspector.rb'
- 'ee/spec/support/test_license.rb'
- 'lib/carrier_wave_string_file.rb'
diff --git a/.rubocop_todo/rspec/context_wording.yml b/.rubocop_todo/rspec/context_wording.yml
index e2df251aa7e..51094378414 100644
--- a/.rubocop_todo/rspec/context_wording.yml
+++ b/.rubocop_todo/rspec/context_wording.yml
@@ -807,6 +807,7 @@ RSpec/ContextWording:
- 'ee/spec/support/shared_contexts/lib/gitlab/insights/reducers/reducers_shared_contexts.rb'
- 'ee/spec/support/shared_contexts/lib/gitlab/insights/serializers/serializers_shared_context.rb'
- 'ee/spec/support/shared_contexts/push_rules_checks_shared_context.rb'
+ - 'ee/spec/support/shared_contexts/secrets_check_shared_contexts.rb'
- 'ee/spec/support/shared_contexts/requests/api/members_shared_contexts.rb'
- 'ee/spec/support/shared_contexts/status_page/status_page_enabled_context.rb'
- 'ee/spec/support/shared_contexts/status_page/status_page_list_objects.rb'
diff --git a/app/assets/javascripts/feature_highlight/constants.js b/app/assets/javascripts/feature_highlight/constants.js
deleted file mode 100644
index 3e4cd11f7d5..00000000000
--- a/app/assets/javascripts/feature_highlight/constants.js
+++ /dev/null
@@ -1 +0,0 @@
-export const POPOVER_TARGET_ID = 'feature-highlight-trigger';
diff --git a/app/assets/javascripts/feature_highlight/feature_highlight_helper.js b/app/assets/javascripts/feature_highlight/feature_highlight_helper.js
deleted file mode 100644
index e2218c1ba2e..00000000000
--- a/app/assets/javascripts/feature_highlight/feature_highlight_helper.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import { createAlert } from '~/alert';
-import axios from '~/lib/utils/axios_utils';
-import { __ } from '~/locale';
-
-export const getSelector = (highlightId) => `.js-feature-highlight[data-highlight=${highlightId}]`;
-
-export function dismiss(endpoint, highlightId) {
- return axios
- .post(endpoint, {
- feature_name: highlightId,
- })
- .catch(() =>
- createAlert({
- message: __(
- 'An error occurred while dismissing the feature highlight. Refresh the page and try dismissing again.',
- ),
- }),
- );
-}
diff --git a/app/assets/javascripts/feature_highlight/feature_highlight_popover.vue b/app/assets/javascripts/feature_highlight/feature_highlight_popover.vue
deleted file mode 100644
index 24f7d567ea7..00000000000
--- a/app/assets/javascripts/feature_highlight/feature_highlight_popover.vue
+++ /dev/null
@@ -1,95 +0,0 @@
-<script>
-import clusterPopover from '@gitlab/svgs/dist/illustrations/cluster_popover.svg?raw';
-import { GlPopover, GlSprintf, GlLink, GlButton } from '@gitlab/ui';
-import SafeHtml from '~/vue_shared/directives/safe_html';
-import { __ } from '~/locale';
-import { POPOVER_TARGET_ID } from './constants';
-import { dismiss } from './feature_highlight_helper';
-
-export default {
- components: {
- GlPopover,
- GlSprintf,
- GlLink,
- GlButton,
- },
- directives: {
- SafeHtml,
- },
- props: {
- autoDevopsHelpPath: {
- type: String,
- required: true,
- },
- highlightId: {
- type: String,
- required: true,
- },
- dismissEndpoint: {
- type: String,
- required: true,
- },
- },
- data() {
- return {
- dismissed: false,
- triggerHidden: false,
- };
- },
- methods: {
- dismiss() {
- dismiss(this.dismissEndpoint, this.highlightId);
- this.$refs.popover.$emit('close');
- this.dismissed = true;
- },
- hideTrigger() {
- if (this.dismissed) {
- this.triggerHidden = true;
- }
- },
- },
- clusterPopover,
- targetId: POPOVER_TARGET_ID,
- i18n: {
- highlightMessage: __('Allows you to add and manage Kubernetes clusters.'),
- autoDevopsProTipMessage: __(
- 'Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!',
- ),
- dismissButtonLabel: __('Got it!'),
- },
-};
-</script>
-<template>
- <div class="gl-ml-3">
- <span v-if="!triggerHidden" :id="$options.targetId" class="feature-highlight"></span>
- <gl-popover
- ref="popover"
- :target="$options.targetId"
- :css-classes="['feature-highlight-popover']"
- container="body"
- placement="right"
- boundary="viewport"
- @hidden="hideTrigger"
- >
- <span
- v-safe-html="$options.clusterPopover"
- class="feature-highlight-illustration gl-display-flex gl-justify-content-center gl-py-4 gl-w-full"
- ></span>
- <div class="gl-px-4 gl-py-5">
- <p>
- {{ $options.i18n.highlightMessage }}
- </p>
- <p>
- <gl-sprintf :message="$options.i18n.autoDevopsProTipMessage">
- <template #link="{ content }">
- <gl-link class="gl-font-sm" :href="autoDevopsHelpPath">{{ content }}</gl-link>
- </template>
- </gl-sprintf>
- </p>
- <gl-button size="small" icon="thumb-up" variant="confirm" @click="dismiss">
- {{ $options.i18n.dismissButtonLabel }}
- </gl-button>
- </div>
- </gl-popover>
- </div>
-</template>
diff --git a/app/assets/javascripts/feature_highlight/index.js b/app/assets/javascripts/feature_highlight/index.js
deleted file mode 100644
index 3a8b211b3c5..00000000000
--- a/app/assets/javascripts/feature_highlight/index.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import Vue from 'vue';
-
-const init = async () => {
- const el = document.querySelector('.js-feature-highlight');
-
- if (!el) {
- return null;
- }
-
- const { autoDevopsHelpPath, highlight: highlightId, dismissEndpoint } = el.dataset;
- const { default: FeatureHighlight } = await import(
- /* webpackChunkName: 'feature_highlight' */ './feature_highlight_popover.vue'
- );
-
- return new Vue({
- el,
- render: (h) =>
- h(FeatureHighlight, {
- props: {
- autoDevopsHelpPath,
- highlightId,
- dismissEndpoint,
- },
- }),
- });
-};
-
-export default init;
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index b555eef5006..e4ff5e55f5c 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -21,7 +21,6 @@ import { localTimeAgo } from './lib/utils/datetime/timeago_utility';
import { getLocationHash, visitUrl, mergeUrlParams } from './lib/utils/url_utility';
// everything else
-import initFeatureHighlight from './feature_highlight';
import LazyLoader from './lazy_loader';
import initLogoAnimation from './logo';
import initBreadcrumbs from './breadcrumb';
@@ -88,7 +87,6 @@ function deferredInitialisation() {
initBroadcastNotifications();
initPersistentUserCallouts();
initDefaultTrackers();
- initFeatureHighlight();
initCopyCodeButton();
initGitlabVersionCheck();
diff --git a/app/assets/javascripts/notifications/constants.js b/app/assets/javascripts/notifications/constants.js
index f5891c9acb5..8d004188c39 100644
--- a/app/assets/javascripts/notifications/constants.js
+++ b/app/assets/javascripts/notifications/constants.js
@@ -55,5 +55,6 @@ export const i18n = {
reopen_merge_request: s__('NotificationEvent|Reopen merge request'),
merge_when_pipeline_succeeds: s__('NotificationEvent|Merge when pipeline succeeds'),
success_pipeline: s__('NotificationEvent|Successful pipeline'),
+ approver: s__('NotificationEvent|Added as approver'),
},
};
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
index 6de041d8f0d..1516b63f96d 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
@@ -120,6 +120,14 @@ export default {
) {
if (mergeRequestMergeStatusUpdated) {
this.state = mergeRequestMergeStatusUpdated;
+
+ if (!this.commitMessageIsTouched) {
+ this.commitMessage = mergeRequestMergeStatusUpdated.defaultMergeCommitMessage;
+ }
+
+ if (!this.squashCommitMessageIsTouched) {
+ this.squashCommitMessage = mergeRequestMergeStatusUpdated.defaultSquashCommitMessage;
+ }
}
},
},
@@ -605,6 +613,7 @@ export default {
:label="__('Merge commit message')"
input-id="merge-message-edit"
class="gl-m-0! gl-p-0!"
+ data-testid="merge-commit-message"
@input="setCommitMessage"
>
<template #header>
diff --git a/app/assets/stylesheets/framework.scss b/app/assets/stylesheets/framework.scss
index 9118c2a3a50..6f4f7a29334 100644
--- a/app/assets/stylesheets/framework.scss
+++ b/app/assets/stylesheets/framework.scss
@@ -57,7 +57,6 @@
@import 'framework/responsive_tables';
@import 'framework/stacked_progress_bar';
@import 'framework/sortable';
-@import 'framework/feature_highlight';
@import 'framework/read_more';
@import 'framework/system_messages';
@import 'framework/spinner';
diff --git a/app/assets/stylesheets/framework/awards.scss b/app/assets/stylesheets/framework/awards.scss
index 28c0c071dc0..fc694e0d37f 100644
--- a/app/assets/stylesheets/framework/awards.scss
+++ b/app/assets/stylesheets/framework/awards.scss
@@ -24,7 +24,7 @@
width: $award-emoji-width;
font-size: 14px;
background-color: $white;
- border: 1px solid $border-white-light;
+ border: 1px solid $border-color;
border-radius: $border-radius-base;
box-shadow: 0 6px 12px $award-emoji-menu-shadow;
pointer-events: none;
@@ -218,7 +218,7 @@
}
.award-control-icon {
- color: $border-gray-normal;
+ color: $gray-100;
svg {
height: $default-icon-size;
diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss
index cae2ea1716c..4249bb372dc 100644
--- a/app/assets/stylesheets/framework/blocks.scss
+++ b/app/assets/stylesheets/framework/blocks.scss
@@ -25,8 +25,8 @@
background-color: $gray-light;
padding: $gl-padding;
margin-bottom: 0;
- border-top: 1px solid $white-dark;
- border-bottom: 1px solid $white-dark;
+ border-top: 1px solid $border-color;
+ border-bottom: 1px solid $border-color;
color: $gl-text-color;
&.white {
@@ -76,14 +76,14 @@
.sub-header-block {
background-color: $white;
- border-bottom: 1px solid $white-dark;
+ border-bottom: 1px solid $border-color;
padding: 11px 0;
margin-bottom: 11px;
}
.content-block {
padding: $gl-padding 0;
- border-bottom: 1px solid $white-dark;
+ border-bottom: 1px solid $border-color;
> .controls {
float: right;
diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss
index 07539b59574..709c33a2ad8 100644
--- a/app/assets/stylesheets/framework/buttons.scss
+++ b/app/assets/stylesheets/framework/buttons.scss
@@ -118,7 +118,7 @@
}
@mixin btn-white {
- @include btn-color($white, $border-color, $gray-50, $border-white-normal, $white-dark, $border-white-normal, $gl-text-color);
+ @include btn-color($white, $gray-200, $gray-50, $gray-200, $gray-100, $gray-300, $gl-text-color);
}
@mixin btn-purple {
@@ -276,7 +276,7 @@
.active {
box-shadow: $gl-btn-active-background;
- border: 1px solid $border-white-normal !important;
+ border: 1px solid $gray-100 !important;
background-color: $btn-active-gray-light !important;
}
}
diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss
index 343e1ebc97d..874cfa2fe53 100644
--- a/app/assets/stylesheets/framework/common.scss
+++ b/app/assets/stylesheets/framework/common.scss
@@ -319,7 +319,7 @@ li.note {
.progress {
margin-top: 4px;
box-shadow: none;
- background-color: $border-gray-light;
+ background-color: $gray-100;
}
}
diff --git a/app/assets/stylesheets/framework/feature_highlight.scss b/app/assets/stylesheets/framework/feature_highlight.scss
deleted file mode 100644
index 0e76d651b70..00000000000
--- a/app/assets/stylesheets/framework/feature_highlight.scss
+++ /dev/null
@@ -1,53 +0,0 @@
-.feature-highlight {
- &::before {
- content: '';
- display: block;
- top: 6px;
- left: 6px;
- width: 8px;
- height: 8px;
- background-color: $blue-500;
- border-radius: 50%;
- box-shadow: 0 0 0 rgba($blue-500, 0.4);
- animation: pulse-highlight 2s infinite;
- }
-
- &:hover::before,
- &.disable-animation::before {
- animation: none;
- }
-
- &[disabled]::before {
- display: none;
- }
-}
-
-
-.feature-highlight-illustration {
- background-color: $theme-indigo-50;
- border-top-left-radius: 2px;
- border-top-right-radius: 2px;
- border-bottom: 1px solid darken($gray-normal, 8%);
-}
-
-.feature-highlight-popover {
- width: 240px;
-
- .popover-body {
- padding: 0;
- }
-}
-
-@include keyframes(pulse-highlight) {
- 0% {
- box-shadow: 0 0 0 0 rgba($blue-200, 0.4);
- }
-
- 70% {
- box-shadow: 0 0 0 10px transparent;
- }
-
- 100% {
- box-shadow: 0 0 0 0 transparent;
- }
-}
diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss
index 30f6d39f70b..9e453249a79 100644
--- a/app/assets/stylesheets/framework/sidebar.scss
+++ b/app/assets/stylesheets/framework/sidebar.scss
@@ -108,7 +108,7 @@
}
.right-sidebar {
- border-left: 1px solid $gray-50;
+ border-left: 1px solid $border-color;
&.right-sidebar-merge-requests {
@include media-breakpoint-up(lg) {
@@ -411,7 +411,7 @@
.issuable-sidebar-header {
@include clearfix;
padding: $gl-spacing-scale-4 0 $gl-spacing-scale-5;
- border-bottom: 1px solid $border-gray-normal;
+ border-bottom: 1px solid $border-color;
// This prevents the mess when resizing the sidebar
// of elements repositioning themselves..
width: $right-sidebar-inner-width;
@@ -587,7 +587,7 @@
}
.participants {
- border-bottom: 1px solid $border-gray-normal;
+ border-bottom: 1px solid $border-color;
}
.hide-collapsed {
@@ -598,7 +598,7 @@
width: 100%;
height: $sidebar-toggle-height;
margin-left: 0;
- border-bottom: 1px solid $border-white-normal;
+ border-bottom: 1px solid $border-color;
border-radius: 0;
}
diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss
index 25542a86e8c..eefdbda8f4f 100644
--- a/app/assets/stylesheets/framework/typography.scss
+++ b/app/assets/stylesheets/framework/typography.scss
@@ -89,7 +89,7 @@
font-weight: $gl-font-weight-bold;
margin: 24px 0 16px;
padding-bottom: 0.3em;
- border-bottom: 1px solid $white-dark;
+ border-bottom: 1px solid $gray-200;
color: $gl-text-color;
&:first-child {
@@ -102,7 +102,7 @@
font-weight: $gl-font-weight-bold;
margin: 24px 0 16px;
padding-bottom: 0.3em;
- border-bottom: 1px solid $white-dark;
+ border-bottom: 1px solid $gray-200;
color: $gl-text-color;
}
@@ -138,7 +138,7 @@
&:dir(rtl) {
border-left: 0;
- border-right: 3px solid $white-dark;
+ border-right: 3px solid $gray-100;
}
p {
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index 0df00532fe9..31948762972 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -87,8 +87,6 @@ $size-scale: (
// Color schema
$darken-normal-factor: 7% !default;
$darken-dark-factor: 10% !default;
-$darken-border-factor: 5% !default;
-$darken-border-dashed-factor: 25% !default;
$purple: #6d49cb !default;
$purple-light: #ede8fb !default;
@@ -116,15 +114,6 @@ $t-gray-a-08: rgba(31, 30, 36, 0.08) !default;
$t-gray-a-16: rgba(31, 30, 36, 0.16) !default;
$t-gray-a-24: rgba(31, 30, 36, 0.24) !default;
-$white-dark: darken($gray-50, 2) !default;
-
-$border-white-light: darken($white, $darken-border-factor) !default;
-$border-white-normal: darken($gray-50, $darken-border-factor) !default;
-
-$border-gray-light: darken($gray-light, $darken-border-factor);
-$border-gray-normal: darken($gray-normal, $darken-border-factor);
-$border-gray-normal-dashed: darken($gray-normal, $darken-border-dashed-factor);
-
/*
* UI elements
*/
diff --git a/app/assets/stylesheets/mailers/highlighted_diff_email.scss b/app/assets/stylesheets/mailers/highlighted_diff_email.scss
index db8c3d163c0..c42b7baec39 100644
--- a/app/assets/stylesheets/mailers/highlighted_diff_email.scss
+++ b/app/assets/stylesheets/mailers/highlighted_diff_email.scss
@@ -144,7 +144,7 @@ blockquote,
color: $gl-grayish-blue;
padding: 0 0 0 15px;
margin: 0;
- border-left: 3px solid $white-dark;
+ border-left: 3px solid $gray-100;
}
span.highlight_word {
diff --git a/app/assets/stylesheets/page_bundles/_ide_monaco_overrides.scss b/app/assets/stylesheets/page_bundles/_ide_monaco_overrides.scss
index 0fb1b3c9c92..013e9e020fc 100644
--- a/app/assets/stylesheets/page_bundles/_ide_monaco_overrides.scss
+++ b/app/assets/stylesheets/page_bundles/_ide_monaco_overrides.scss
@@ -75,7 +75,7 @@
.diffOverview {
background-color: $white;
- border-left: 1px solid $white-dark;
+ border-left: 1px solid $border-color;
cursor: ns-resize;
}
diff --git a/app/assets/stylesheets/page_bundles/_ide_theme_overrides.scss b/app/assets/stylesheets/page_bundles/_ide_theme_overrides.scss
index b6caa845cfa..5c8e9bce0e7 100644
--- a/app/assets/stylesheets/page_bundles/_ide_theme_overrides.scss
+++ b/app/assets/stylesheets/page_bundles/_ide_theme_overrides.scss
@@ -147,7 +147,7 @@
.nav-links,
.gl-tabs-nav,
.common-note-form .md-area.is-focused .nav-links {
- border-color: var(--ide-border-color-alt, $white-dark);
+ border-color: var(--ide-border-color-alt, $border-color);
}
pre {
@@ -291,14 +291,14 @@
&:hover,
&:focus {
- border-color: var(--ide-btn-default-hover-border, $border-white-normal) !important;
+ border-color: var(--ide-btn-default-hover-border, $border-color) !important;
background-color: var(--ide-btn-default-background, $gray-50) !important;
}
&:active,
.active {
- border-color: var(--ide-btn-default-hover-border, $border-white-normal) !important;
- background-color: var(--ide-btn-default-background, $white-dark) !important;
+ border-color: var(--ide-btn-default-hover-border, $border-color) !important;
+ background-color: var(--ide-btn-default-background, $border-color) !important;
}
}
diff --git a/app/assets/stylesheets/page_bundles/ide.scss b/app/assets/stylesheets/page_bundles/ide.scss
index f7b979c2dac..7e2bf4a03a3 100644
--- a/app/assets/stylesheets/page_bundles/ide.scss
+++ b/app/assets/stylesheets/page_bundles/ide.scss
@@ -74,15 +74,15 @@ $ide-commit-header-height: 48px;
display: flex;
flex-direction: column;
flex: 1;
- border-left: 1px solid var(--ide-border-color, $white-dark);
- border-right: 1px solid var(--ide-border-color, $white-dark);
+ border-left: 1px solid var(--ide-border-color, $border-color);
+ border-right: 1px solid var(--ide-border-color, $border-color);
overflow: hidden;
}
.multi-file-tabs {
display: flex;
background-color: var(--ide-background, $gray-light);
- box-shadow: inset 0 -1px var(--ide-border-color, $white-dark);
+ box-shadow: inset 0 -1px var(--ide-border-color, $border-color);
> ul {
display: flex;
@@ -94,8 +94,8 @@ $ide-commit-header-height: 48px;
align-items: center;
padding: $grid-size $gl-padding;
background-color: var(--ide-background-hover, $gray-normal);
- border-right: 1px solid var(--ide-border-color, $white-dark);
- border-bottom: 1px solid var(--ide-border-color, $white-dark);
+ border-right: 1px solid var(--ide-border-color, $border-color);
+ border-bottom: 1px solid var(--ide-border-color, $border-color);
&.active,
.gl-tab-nav-item-active {
@@ -136,12 +136,12 @@ $ide-commit-header-height: 48px;
font-weight: normal !important;
background-color: var(--ide-background-hover, $gray-normal);
- border-right: 1px solid var(--ide-border-color, $white-dark);
- border-bottom: 1px solid var(--ide-border-color, $white-dark);
+ border-right: 1px solid var(--ide-border-color, $border-color);
+ border-bottom: 1px solid var(--ide-border-color, $border-color);
&.gl-tab-nav-item-active {
background-color: var(--ide-highlight-background, $white);
- border-color: var(--ide-border-color, $white-dark);
+ border-color: var(--ide-border-color, $border-color);
border-bottom-color: transparent;
}
@@ -245,7 +245,7 @@ $ide-commit-header-height: 48px;
}
.ide-mode-tabs {
- border-bottom: 1px solid var(--ide-border-color, $white-dark);
+ border-bottom: 1px solid var(--ide-border-color, $border-color);
li a {
padding: $gl-padding-8 $gl-padding;
@@ -260,7 +260,7 @@ $ide-commit-header-height: 48px;
.ide-status-bar {
color: var(--ide-text-color, $gl-text-color);
- border-top: 1px solid var(--ide-border-color, $white-dark);
+ border-top: 1px solid var(--ide-border-color, $border-color);
padding: 2px $gl-padding-8 0;
background-color: var(--ide-footer-background, $white);
display: flex;
@@ -358,8 +358,8 @@ $ide-commit-header-height: 48px;
flex: 1;
flex-direction: column;
background-color: var(--ide-highlight-background, $white);
- border-left: 1px solid var(--ide-border-color, $white-dark);
- border-top: 1px solid var(--ide-border-color, $white-dark);
+ border-left: 1px solid var(--ide-border-color, $border-color);
+ border-top: 1px solid var(--ide-border-color, $border-color);
border-top-left-radius: $border-radius-small;
min-height: 0; // firefox fix
}
@@ -384,7 +384,7 @@ $ide-commit-header-height: 48px;
.multi-file-commit-panel-header {
height: $ide-commit-header-height;
- border-bottom: 1px solid var(--ide-border-color-alt, $white-dark);
+ border-bottom: 1px solid var(--ide-border-color-alt, $border-color);
padding: 12px 0;
}
@@ -465,7 +465,7 @@ $ide-commit-header-height: 48px;
.multi-file-commit-form {
position: relative;
background-color: var(--ide-highlight-background, $white);
- border-left: 1px solid var(--ide-border-color, $white-dark);
+ border-left: 1px solid var(--ide-border-color, $border-color);
transition: all 0.3s ease;
> form,
@@ -473,7 +473,7 @@ $ide-commit-header-height: 48px;
padding: $gl-padding 0;
margin-left: $gl-padding;
margin-right: $gl-padding;
- border-top: 1px solid var(--ide-border-color-alt, $white-dark);
+ border-top: 1px solid var(--ide-border-color-alt, $border-color);
}
.btn {
@@ -544,7 +544,7 @@ $ide-commit-header-height: 48px;
margin-right: $gl-padding;
&.is-first {
- border-bottom: 1px solid var(--ide-border-color-alt, $white-dark);
+ border-bottom: 1px solid var(--ide-border-color-alt, $border-color);
}
}
@@ -603,8 +603,8 @@ $ide-commit-header-height: 48px;
width: calc(100% + 1px);
padding-right: $gl-padding + 1px;
background-color: var(--ide-highlight-background, $white);
- border-top-color: var(--ide-border-color, $white-dark);
- border-bottom-color: var(--ide-border-color, $white-dark);
+ border-top-color: var(--ide-border-color, $border-color);
+ border-bottom-color: var(--ide-border-color, $border-color);
&::after {
content: '';
@@ -714,7 +714,7 @@ $ide-commit-header-height: 48px;
padding: 12px 0;
margin-left: $ide-tree-padding;
margin-right: $ide-tree-padding;
- border-bottom: 1px solid var(--ide-border-color-alt, $white-dark);
+ border-bottom: 1px solid var(--ide-border-color-alt, $border-color);
svg {
color: var(--ide-text-color-secondary, $gray-500);
@@ -906,7 +906,7 @@ $ide-commit-header-height: 48px;
.multi-file-commit-panel-inner {
padding: $grid-size 0;
background-color: var(--ide-highlight-background, $white);
- border-right: 1px solid var(--ide-border-color, $white-dark);
+ border-right: 1px solid var(--ide-border-color, $border-color);
}
.ide-right-sidebar-jobs-detail {
@@ -1092,7 +1092,7 @@ $ide-commit-header-height: 48px;
.ide-file-templates {
padding: $grid-size $gl-padding;
background-color: var(--ide-background, $gray-light);
- border-bottom: 1px solid var(--ide-border-color, $white-dark);
+ border-bottom: 1px solid var(--ide-border-color, $border-color);
.dropdown {
min-width: 180px;
@@ -1107,7 +1107,7 @@ $ide-commit-header-height: 48px;
height: 65px;
padding: 8px 16px;
background-color: var(--ide-background, $gray-10);
- box-shadow: inset 0 -1px var(--ide-border-color, $white-dark);
+ box-shadow: inset 0 -1px var(--ide-border-color, $border-color);
}
.ide-commit-list-changed-icon {
diff --git a/app/assets/stylesheets/page_bundles/milestone.scss b/app/assets/stylesheets/page_bundles/milestone.scss
index 8dc07715989..7a9c7487a7e 100644
--- a/app/assets/stylesheets/page_bundles/milestone.scss
+++ b/app/assets/stylesheets/page_bundles/milestone.scss
@@ -90,7 +90,7 @@
}
.reference {
- border-top: 1px solid $border-gray-normal;
+ border-top: 1px solid $border-color;
}
}
}
diff --git a/app/assets/stylesheets/page_bundles/pipelines.scss b/app/assets/stylesheets/page_bundles/pipelines.scss
index 2bd8984c2ea..d61e3f85995 100644
--- a/app/assets/stylesheets/page_bundles/pipelines.scss
+++ b/app/assets/stylesheets/page_bundles/pipelines.scss
@@ -43,7 +43,7 @@
.btn-group.open .btn-default {
background-color: $gray-50;
- border-color: $border-white-normal;
+ border-color: $gray-100;
}
.btn .text-center {
diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss
index 8511bc22725..f1055590539 100644
--- a/app/assets/stylesheets/pages/commits.scss
+++ b/app/assets/stylesheets/pages/commits.scss
@@ -7,7 +7,7 @@
background: none;
word-break: normal;
overflow-x: auto;
- border-left: 3px solid $white-dark;
+ border-left: 3px solid $gray-100;
color: $gl-text-color-secondary;
}
@@ -93,7 +93,7 @@
color: $gl-text-color-secondary;
padding: 1px $gl-padding-4;
cursor: pointer;
- border: 1px solid $border-white-normal;
+ border: 1px solid $gray-100;
border-radius: $border-radius-default;
margin-left: 5px;
font-size: 12px;
diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss
index a8f557270ba..d01286bd209 100644
--- a/app/assets/stylesheets/pages/groups.scss
+++ b/app/assets/stylesheets/pages/groups.scss
@@ -141,7 +141,7 @@ table.pipeline-project-metrics tr td {
top: 5px;
bottom: 0;
left: -16px;
- border-left: 2px solid $border-white-normal;
+ border-left: 2px solid $border-color;
}
.group-row {
@@ -152,7 +152,7 @@ table.pipeline-project-metrics tr td {
display: block;
width: 10px;
height: 0;
- border-top: 2px solid $border-white-normal;
+ border-top: 2px solid $border-color;
position: absolute;
top: 30px;
left: -16px;
diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss
index 052e3326318..9748983d1ae 100644
--- a/app/assets/stylesheets/pages/issues.scss
+++ b/app/assets/stylesheets/pages/issues.scss
@@ -29,7 +29,7 @@
.issue-token:hover &,
.issue-token-link:focus > & {
- background-color: $border-gray-normal;
+ background-color: $gray-100;
}
}
@@ -41,7 +41,7 @@
&:focus,
.issue-token:hover &,
.issue-token-link:focus + & {
- background-color: $border-gray-normal;
+ background-color: $gray-100;
outline: none;
}
}
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index eb2061081ae..8792c7f9a72 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -986,7 +986,7 @@ $system-note-icon-m-left: $avatar-m-left + $icon-size-diff / $avatar-m-ratio;
.disabled-comment {
background-color: $gray-light;
border-radius: $border-radius-base;
- border: 1px solid $border-gray-normal;
+ border: 1px solid $border-color;
color: $note-disabled-comment-color;
padding: $gl-padding-8 0;
diff --git a/app/assets/stylesheets/print.scss b/app/assets/stylesheets/print.scss
index 3015cfec34f..7464946cfc8 100644
--- a/app/assets/stylesheets/print.scss
+++ b/app/assets/stylesheets/print.scss
@@ -39,7 +39,7 @@
content: ' ';
height: 100%;
width: 4px;
- background-color: $white-dark;
+ background-color: $gray-100;
}
position: relative;
diff --git a/app/assets/stylesheets/snippets.scss b/app/assets/stylesheets/snippets.scss
index f5787799fce..91b381462be 100644
--- a/app/assets/stylesheets/snippets.scss
+++ b/app/assets/stylesheets/snippets.scss
@@ -159,7 +159,7 @@
&:hover {
background-color: $gray-50;
- border-color: $border-white-normal;
+ border-color: $gray-100;
text-decoration: none;
}
diff --git a/app/assets/stylesheets/themes/_dark.scss b/app/assets/stylesheets/themes/_dark.scss
index 5a9f3dd096e..cb0da7e782d 100644
--- a/app/assets/stylesheets/themes/_dark.scss
+++ b/app/assets/stylesheets/themes/_dark.scss
@@ -13,12 +13,9 @@ $gray-darkest: $gray-700;
$t-gray-a-08: rgba($gray-950, 0.08);
$black-normal: $gray-900;
-$white-dark: $gray-100;
$border-color: #4f4f4f;
-$border-white-normal: $border-color;
-
$gl-text-color-secondary: $gray-700;
$body-bg: $gray-10;
diff --git a/app/assets/stylesheets/themes/dark_mode_overrides.scss b/app/assets/stylesheets/themes/dark_mode_overrides.scss
index 708d173ed3e..3ab3e195b06 100644
--- a/app/assets/stylesheets/themes/dark_mode_overrides.scss
+++ b/app/assets/stylesheets/themes/dark_mode_overrides.scss
@@ -137,7 +137,6 @@
aside.right-sidebar:not(.right-sidebar-merge-requests) {
background-color: $gray-10;
- border-left-color: $gray-50;
}
:root.gl-dark {
diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb
index 5e82a3e8dcf..c702b107b7e 100644
--- a/app/mailers/emails/merge_requests.rb
+++ b/app/mailers/emails/merge_requests.rb
@@ -187,3 +187,5 @@ module Emails
end
end
end
+
+Emails::MergeRequests.prepend_mod_with('Emails::MergeRequests')
diff --git a/app/models/notification_recipient.rb b/app/models/notification_recipient.rb
index 20d5a5ae1a1..7ef2aa194b9 100644
--- a/app/models/notification_recipient.rb
+++ b/app/models/notification_recipient.rb
@@ -119,7 +119,7 @@ class NotificationRecipient
end
def excluded_watcher_action?
- return false unless @type == :watch
+ return false unless notification_level == :watch
return false unless @custom_action
NotificationSetting::EXCLUDED_WATCHER_EVENTS.include?(@custom_action)
diff --git a/app/models/notification_setting.rb b/app/models/notification_setting.rb
index eb4fa9ac474..6c165b10a6a 100644
--- a/app/models/notification_setting.rb
+++ b/app/models/notification_setting.rb
@@ -70,7 +70,8 @@ class NotificationSetting < ApplicationRecord
EXCLUDED_WATCHER_EVENTS = [
:push_to_merge_request,
:issue_due,
- :success_pipeline
+ :success_pipeline,
+ :approver
].freeze
def self.find_or_create_for(source)
diff --git a/app/models/todo.rb b/app/models/todo.rb
index a61aad69820..54c3866d703 100644
--- a/app/models/todo.rb
+++ b/app/models/todo.rb
@@ -23,6 +23,7 @@ class Todo < ApplicationRecord
MEMBER_ACCESS_REQUESTED = 10
REVIEW_SUBMITTED = 11 # This is an EE-only feature
OKR_CHECKIN_REQUESTED = 12 # This is an EE-only feature
+ ADDED_APPROVER = 13 # This is an EE-only feature
ACTION_NAMES = {
ASSIGNED => :assigned,
@@ -36,7 +37,8 @@ class Todo < ApplicationRecord
MERGE_TRAIN_REMOVED => :merge_train_removed,
MEMBER_ACCESS_REQUESTED => :member_access_requested,
REVIEW_SUBMITTED => :review_submitted,
- OKR_CHECKIN_REQUESTED => :okr_checkin_requested
+ OKR_CHECKIN_REQUESTED => :okr_checkin_requested,
+ ADDED_APPROVER => :added_approver
}.freeze
ACTIONS_MULTIPLE_ALLOWED = [Todo::MENTIONED, Todo::DIRECTLY_ADDRESSED, Todo::MEMBER_ACCESS_REQUESTED].freeze
diff --git a/app/services/bulk_imports/file_download_service.rb b/app/services/bulk_imports/file_download_service.rb
index 8f72c35a94c..8fa438a76ce 100644
--- a/app/services/bulk_imports/file_download_service.rb
+++ b/app/services/bulk_imports/file_download_service.rb
@@ -96,7 +96,6 @@ module BulkImports
message: message,
response_code: response_code,
response_headers: response_headers,
- importer: 'gitlab_migration',
last_chunk_context: last_chunk_context
)
diff --git a/app/services/bulk_imports/process_service.rb b/app/services/bulk_imports/process_service.rb
index 2d9a0d6a6c9..1484a6fddd3 100644
--- a/app/services/bulk_imports/process_service.rb
+++ b/app/services/bulk_imports/process_service.rb
@@ -106,16 +106,11 @@ module BulkImports
end
def log_skipped_pipeline(pipeline, entity, minimum_version, maximum_version)
- logger.info(
+ logger.with_entity(entity).info(
message: 'Pipeline skipped as source instance version not compatible with pipeline',
- bulk_import_entity_id: entity.id,
- bulk_import_id: entity.bulk_import_id,
- bulk_import_entity_type: entity.source_type,
- source_full_path: entity.source_full_path,
pipeline_class: pipeline[:pipeline],
minimum_source_version: minimum_version,
- maximum_source_version: maximum_version,
- source_version: entity.source_version.to_s
+ maximum_source_version: maximum_version
)
end
diff --git a/app/workers/bulk_imports/entity_worker.rb b/app/workers/bulk_imports/entity_worker.rb
index 6ff2d15d6e8..258ccea1f63 100644
--- a/app/workers/bulk_imports/entity_worker.rb
+++ b/app/workers/bulk_imports/entity_worker.rb
@@ -42,7 +42,9 @@ module BulkImports
Gitlab::ErrorTracking.track_exception(
exception,
- log_params(message: "Request to export #{entity.source_type} failed")
+ {
+ message: "Request to export #{entity.source_type} failed"
+ }.merge(logger.default_attributes)
)
entity.fail_op!
@@ -94,35 +96,12 @@ module BulkImports
log_info(message: lease_taken_message)
end
- def source_version
- entity.bulk_import.source_version_info.to_s
- end
-
def logger
- @logger ||= Logger.build
- end
-
- def log_exception(exception, payload)
- Gitlab::ExceptionLogFormatter.format!(exception, payload)
-
- logger.error(structured_payload(payload))
+ @logger ||= Logger.build.with_entity(entity)
end
def log_info(payload)
- logger.info(structured_payload(log_params(payload)))
- end
-
- def log_params(extra)
- defaults = {
- bulk_import_entity_id: entity.id,
- bulk_import_id: entity.bulk_import_id,
- bulk_import_entity_type: entity.source_type,
- source_full_path: entity.source_full_path,
- source_version: source_version,
- importer: Logger::IMPORTER_NAME
- }
-
- defaults.merge(extra)
+ logger.info(structured_payload(payload))
end
end
end
diff --git a/app/workers/bulk_imports/export_request_worker.rb b/app/workers/bulk_imports/export_request_worker.rb
index 54815c05c67..bfe561cca5c 100644
--- a/app/workers/bulk_imports/export_request_worker.rb
+++ b/app/workers/bulk_imports/export_request_worker.rb
@@ -75,16 +75,7 @@ module BulkImports
::GlobalID.parse(response.dig(*entity_query.data_path, 'id')).model_id
rescue StandardError => e
- log_exception(e,
- {
- message: 'Failed to fetch source entity id',
- bulk_import_entity_id: entity.id,
- bulk_import_id: entity.bulk_import_id,
- bulk_import_entity_type: entity.source_type,
- source_full_path: entity.source_full_path,
- source_version: entity.bulk_import.source_version_info.to_s
- }
- )
+ log_exception(e, message: 'Failed to fetch source entity id')
nil
end
@@ -98,7 +89,7 @@ module BulkImports
end
def logger
- @logger ||= Logger.build
+ @logger ||= Logger.build.with_entity(entity)
end
def log_exception(exception, payload)
@@ -108,16 +99,7 @@ module BulkImports
end
def log_and_fail(exception)
- log_exception(exception,
- {
- bulk_import_entity_id: entity.id,
- bulk_import_id: entity.bulk_import_id,
- bulk_import_entity_type: entity.source_type,
- source_full_path: entity.source_full_path,
- message: "Request to export #{entity.source_type} failed",
- source_version: entity.bulk_import.source_version_info.to_s
- }
- )
+ log_exception(exception, message: "Request to export #{entity.source_type} failed")
BulkImports::Failure.create(failure_attributes(exception))
diff --git a/app/workers/bulk_imports/finish_batched_pipeline_worker.rb b/app/workers/bulk_imports/finish_batched_pipeline_worker.rb
index 980cdb98f32..60676f4bd15 100644
--- a/app/workers/bulk_imports/finish_batched_pipeline_worker.rb
+++ b/app/workers/bulk_imports/finish_batched_pipeline_worker.rb
@@ -58,18 +58,11 @@ module BulkImports
end
def logger
- @logger ||= Logger.build
+ @logger ||= Logger.build.with_tracker(tracker)
end
def log_attributes(extra = {})
- structured_payload(
- {
- tracker_id: tracker.id,
- bulk_import_id: tracker.entity.id,
- bulk_import_entity_id: tracker.entity.bulk_import_id,
- pipeline_class: tracker.pipeline_name
- }.merge(extra)
- )
+ structured_payload(extra)
end
end
end
diff --git a/app/workers/bulk_imports/pipeline_worker.rb b/app/workers/bulk_imports/pipeline_worker.rb
index bd86970844b..184b321ca7a 100644
--- a/app/workers/bulk_imports/pipeline_worker.rb
+++ b/app/workers/bulk_imports/pipeline_worker.rb
@@ -96,10 +96,6 @@ module BulkImports
retry_tracker(e)
end
- def source_version
- entity.bulk_import.source_version_info.to_s
- end
-
def fail_pipeline(exception)
pipeline_tracker.update!(status_event: 'fail_op', jid: jid)
@@ -120,7 +116,7 @@ module BulkImports
end
def logger
- @logger ||= Logger.build
+ @logger ||= Logger.build.with_tracker(pipeline_tracker)
end
def re_enqueue(delay = FILE_EXTRACTION_PIPELINE_PERFORM_DELAY)
@@ -185,19 +181,7 @@ module BulkImports
end
def log_attributes(extra = {})
- structured_payload(
- {
- bulk_import_entity_id: entity.id,
- bulk_import_id: entity.bulk_import_id,
- bulk_import_entity_type: entity.source_type,
- source_full_path: entity.source_full_path,
- pipeline_tracker_id: pipeline_tracker.id,
- pipeline_class: pipeline_tracker.pipeline_name,
- pipeline_tracker_state: pipeline_tracker.human_status_name,
- source_version: source_version,
- importer: Logger::IMPORTER_NAME
- }.merge(extra)
- )
+ logger.default_attributes.merge(extra)
end
def log_exception(exception, payload)
diff --git a/app/workers/bulk_imports/stuck_import_worker.rb b/app/workers/bulk_imports/stuck_import_worker.rb
index 6c8569b0aa0..9f3fe21f1e1 100644
--- a/app/workers/bulk_imports/stuck_import_worker.rb
+++ b/app/workers/bulk_imports/stuck_import_worker.rb
@@ -20,10 +20,8 @@ module BulkImports
BulkImports::Entity.includes(:trackers).stale.find_each do |entity| # rubocop: disable CodeReuse/ActiveRecord
ApplicationRecord.transaction do
- logger.error(
- message: 'BulkImports::Entity stale',
- bulk_import_id: entity.bulk_import_id,
- bulk_import_entity_id: entity.id
+ logger.with_entity(entity).error(
+ message: 'BulkImports::Entity stale'
)
entity.cleanup_stale
diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml
index 5af17ae3ece..f81d904f4c5 100644
--- a/config/sidekiq_queues.yml
+++ b/config/sidekiq_queues.yml
@@ -461,6 +461,8 @@
- 1
- - merge_requests_mergeability_check_batch
- 1
+- - merge_requests_notify_approvers
+ - 1
- - merge_requests_process_approval_auto_merge
- 1
- - merge_requests_remove_user_approval_rules
diff --git a/db/docs/batched_background_migrations/backfill_dismissal_reason_in_vulnerability_reads.yml b/db/docs/batched_background_migrations/backfill_dismissal_reason_in_vulnerability_reads.yml
index 1f76acc4def..4e845f41c32 100644
--- a/db/docs/batched_background_migrations/backfill_dismissal_reason_in_vulnerability_reads.yml
+++ b/db/docs/batched_background_migrations/backfill_dismissal_reason_in_vulnerability_reads.yml
@@ -6,3 +6,4 @@ feature_category: vulnerability_management
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123518
queued_migration_version: 20230612232000
milestone: '16.1'
+finalized_by: '20231207163648'
diff --git a/db/docs/batched_background_migrations/fix_allow_descendants_override_disabled_shared_runners.yml b/db/docs/batched_background_migrations/fix_allow_descendants_override_disabled_shared_runners.yml
index fc69b1eb934..1fec979899b 100644
--- a/db/docs/batched_background_migrations/fix_allow_descendants_override_disabled_shared_runners.yml
+++ b/db/docs/batched_background_migrations/fix_allow_descendants_override_disabled_shared_runners.yml
@@ -1,6 +1,8 @@
---
migration_job_name: FixAllowDescendantsOverrideDisabledSharedRunners
-description: Clears invalid combination of shared runners settings (fixes subgroup creation)
+description: Clears invalid combination of shared runners settings (fixes subgroup
+ creation)
feature_category: runner_fleet
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/128112
milestone: '16.3'
+finalized_by: '20231207221159'
diff --git a/db/migrate/20231114152304_add_approver_to_notification_settings.rb b/db/migrate/20231114152304_add_approver_to_notification_settings.rb
new file mode 100644
index 00000000000..aaa9405532d
--- /dev/null
+++ b/db/migrate/20231114152304_add_approver_to_notification_settings.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class AddApproverToNotificationSettings < Gitlab::Database::Migration[2.2]
+ milestone '16.7'
+ enable_lock_retries!
+
+ def change
+ add_column :notification_settings, :approver, :boolean, default: false, null: false
+ end
+end
diff --git a/db/post_migrate/20231207163648_re_finalize_backfill_dismissal_reason_in_vulnerability_reads.rb b/db/post_migrate/20231207163648_re_finalize_backfill_dismissal_reason_in_vulnerability_reads.rb
new file mode 100644
index 00000000000..fcfa50c8f32
--- /dev/null
+++ b/db/post_migrate/20231207163648_re_finalize_backfill_dismissal_reason_in_vulnerability_reads.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class ReFinalizeBackfillDismissalReasonInVulnerabilityReads < Gitlab::Database::Migration[2.2]
+ milestone '16.7'
+
+ disable_ddl_transaction!
+
+ restrict_gitlab_migration gitlab_schema: :gitlab_main
+
+ def up
+ ensure_batched_background_migration_is_finished(
+ job_class_name: 'BackfillDismissalReasonInVulnerabilityReads',
+ table_name: :vulnerability_reads,
+ column_name: :id,
+ job_arguments: [],
+ finalize: true
+ )
+ end
+
+ def down; end
+end
diff --git a/db/post_migrate/20231207221159_finalize_fix_allow_descendants_override_disabled_shared_runners.rb b/db/post_migrate/20231207221159_finalize_fix_allow_descendants_override_disabled_shared_runners.rb
new file mode 100644
index 00000000000..86dead2c54e
--- /dev/null
+++ b/db/post_migrate/20231207221159_finalize_fix_allow_descendants_override_disabled_shared_runners.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class FinalizeFixAllowDescendantsOverrideDisabledSharedRunners < Gitlab::Database::Migration[2.2]
+ milestone '16.7'
+
+ disable_ddl_transaction!
+
+ restrict_gitlab_migration gitlab_schema: :gitlab_main
+
+ def up
+ ensure_batched_background_migration_is_finished(
+ job_class_name: 'FixAllowDescendantsOverrideDisabledSharedRunners',
+ table_name: :namespaces,
+ column_name: :id,
+ job_arguments: [],
+ finalize: true
+ )
+ end
+
+ def down; end
+end
diff --git a/db/schema_migrations/20231114152304 b/db/schema_migrations/20231114152304
new file mode 100644
index 00000000000..61092255023
--- /dev/null
+++ b/db/schema_migrations/20231114152304
@@ -0,0 +1 @@
+1d95078648a6fde73287b5a90c66143669cbde10836e3a1457ded5d3decb0266 \ No newline at end of file
diff --git a/db/schema_migrations/20231207163648 b/db/schema_migrations/20231207163648
new file mode 100644
index 00000000000..24a47db3349
--- /dev/null
+++ b/db/schema_migrations/20231207163648
@@ -0,0 +1 @@
+1d8d015245c8e8951f53b5e925cd1f47aa85aec001f738d7456aff4225ead951 \ No newline at end of file
diff --git a/db/schema_migrations/20231207221159 b/db/schema_migrations/20231207221159
new file mode 100644
index 00000000000..a0b072bdd4d
--- /dev/null
+++ b/db/schema_migrations/20231207221159
@@ -0,0 +1 @@
+2a81b952d0db20a477204dbecfeff94af3df0c1b1373eef4b5276f215f6257e9 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index ed7fb02520d..3e55c8ff615 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -19759,7 +19759,8 @@ CREATE TABLE notification_settings (
new_release boolean,
moved_project boolean DEFAULT true NOT NULL,
change_reviewer_merge_request boolean,
- merge_when_pipeline_succeeds boolean DEFAULT false NOT NULL
+ merge_when_pipeline_succeeds boolean DEFAULT false NOT NULL,
+ approver boolean DEFAULT false NOT NULL
);
CREATE SEQUENCE notification_settings_id_seq
diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md
index 3726924b82c..80121c7c235 100644
--- a/doc/administration/monitoring/prometheus/gitlab_metrics.md
+++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md
@@ -179,6 +179,7 @@ The following metrics are available:
| `gitlab_ci_queue_active_runners_total` | Histogram | 16.3 | The amount of active runners that can process queue in a project |
| `gitlab_connection_pool_size` | Gauge | 16.7 | Size of connection pool |
| `gitlab_connection_pool_available_count` | Gauge | 16.7 | Number of available connections in the pool |
+| `gitlab_security_policies_scan_result_process_duration_seconds` | Histogram | 16.7 | The amount of time to process scan result policies |
## Metrics controlled by a feature flag
diff --git a/doc/administration/settings/slack_app.md b/doc/administration/settings/slack_app.md
index b4a4df8faa3..5e54294b720 100644
--- a/doc/administration/settings/slack_app.md
+++ b/doc/administration/settings/slack_app.md
@@ -104,7 +104,7 @@ To enable the GitLab for Slack app functionality, your network must allow inboun
When administering the GitLab for Slack app for self-managed instances, you might encounter the following issues.
-For GitLab.com, see [GitLab for Slack app](../../user/project/integrations/gitlab_slack_application.md#troubleshooting).
+For GitLab.com, see [GitLab for Slack app](../../user/project/integrations/gitlab_slack_app_troubleshooting.md).
### Slash commands return an error in Slack
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 92972094891..3f0ec54801c 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -19378,6 +19378,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="groupcomplianceframeworksid"></a>`id` | [`ComplianceManagementFrameworkID`](#compliancemanagementframeworkid) | Global ID of a specific compliance framework to return. |
+| <a id="groupcomplianceframeworkssearch"></a>`search` | [`String`](#string) | Search framework with most similar names. |
##### `Group.contactStateCounts`
@@ -23019,6 +23020,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="namespacecomplianceframeworksid"></a>`id` | [`ComplianceManagementFrameworkID`](#compliancemanagementframeworkid) | Global ID of a specific compliance framework to return. |
+| <a id="namespacecomplianceframeworkssearch"></a>`search` | [`String`](#string) | Search framework with most similar names. |
##### `Namespace.projects`
diff --git a/doc/ci/runners/configure_runners.md b/doc/ci/runners/configure_runners.md
index ad39c3f1546..eefd953263e 100644
--- a/doc/ci/runners/configure_runners.md
+++ b/doc/ci/runners/configure_runners.md
@@ -174,6 +174,23 @@ After you reset the registration token, it is no longer valid and does not regis
any new runners to the project. You should also update the registration token in tools
you use to provision and register new values.
+## Authentication token security
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30942) in GitLab 15.3 [with a flag](../../administration/feature_flags.md) named `enforce_runner_token_expires_at`. Disabled by default.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/377902) in GitLab 15.5. Feature flag `enforce_runner_token_expires_at` removed.
+
+Each runner has an [runner authentication token](../../api/runners.md#registration-and-authentication-tokens)
+to connect with the GitLab instance.
+
+To help prevent the token from being compromised, you can have the
+token rotate automatically at specified intervals. When the tokens are rotated,
+they are updated for each runner, regardless of the runner's status (`online` or `offline`).
+
+No manual intervention should be required, and no running jobs should be affected.
+
+If you need to manually update the runner authentication token, you can run a
+command to [reset the token](https://docs.gitlab.com/runner/commands/#gitlab-runner-reset-token).
+
### Reset the runner authentication token
If a runner authentication token is revealed, an attacker could use the token to [clone a runner](https://docs.gitlab.com/runner/security/#cloning-a-runner).
@@ -1016,20 +1033,3 @@ setting.
`FASTZIP_EXTRACTOR_CONCURRENCY` controls how many files are decompressed at once. Files from a zip archive can natively
be read from concurrency, so no additional memory is allocated in addition to what the decompressor requires. This
defaults to the number of CPUs available.
-
-## Authentication token security
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30942) in GitLab 15.3 [with a flag](../../administration/feature_flags.md) named `enforce_runner_token_expires_at`. Disabled by default.
-> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/377902) in GitLab 15.5. Feature flag `enforce_runner_token_expires_at` removed.
-
-Each runner has an [runner authentication token](../../api/runners.md#registration-and-authentication-tokens)
-to connect with the GitLab instance.
-
-To help prevent the token from being compromised, you can have the
-token rotate automatically at specified intervals. When the tokens are rotated,
-they are updated for each runner, regardless of the runner's status (`online` or `offline`).
-
-No manual intervention should be required, and no running jobs should be affected.
-
-If you need to manually update the runner authentication token, you can run a
-command to [reset the token](https://docs.gitlab.com/runner/commands/#gitlab-runner-reset-token).
diff --git a/doc/user/project/integrations/gitlab_slack_app_troubleshooting.md b/doc/user/project/integrations/gitlab_slack_app_troubleshooting.md
new file mode 100644
index 00000000000..363e7c2c364
--- /dev/null
+++ b/doc/user/project/integrations/gitlab_slack_app_troubleshooting.md
@@ -0,0 +1,48 @@
+---
+stage: Manage
+group: Import and Integrate
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
+---
+
+# Troubleshooting GitLab for Slack app **(FREE ALL)**
+
+When configuring the GitLab for Slack app on GitLab.com, you might encounter the following issues.
+
+For self-managed GitLab, see [GitLab for Slack app administration](../../../administration/settings/slack_app.md#troubleshooting).
+
+## The app does not appear in the list of integrations
+
+The GitLab for Slack app might not appear in the list of integrations. To have the GitLab for Slack app on your self-managed instance, an administrator must [enable the integration](../../../administration/settings/slack_app.md). On GitLab.com, the GitLab for Slack app is available by default.
+
+The GitLab for Slack app is enabled at the project level only. Support for the app at the group and instance levels is proposed in [issue 391526](https://gitlab.com/gitlab-org/gitlab/-/issues/391526).
+
+## Project or alias not found
+
+Some Slack commands must have a project full path or alias and fail with the following error
+if the project cannot be found:
+
+```plaintext
+GitLab error: project or alias not found
+```
+
+To resolve this issue, ensure:
+
+- The project full path is correct.
+- If using a [project alias](gitlab_slack_application.md#create-a-project-alias-for-slash-commands), the alias is correct.
+- The GitLab for Slack app is [enabled for the project](gitlab_slack_application.md#from-project-integration-settings).
+
+## Slash commands return an error in Slack
+
+Slash commands might return `/gitlab failed with the error "dispatch_failed"` in Slack.
+To resolve this issue, ensure an administrator has properly configured the [GitLab for Slack app settings](../../../administration/settings/slack_app.md) on your self-managed instance.
+
+## Notifications are not received to a channel
+
+If you're not receiving notifications to a Slack channel, ensure:
+
+- The channel name you configured is correct.
+- If the channel is private, you've [added the GitLab for Slack app to the channel](gitlab_slack_application.md#receive-notifications-to-a-private-channel).
+
+## The App Home does not display properly
+
+If the [App Home](https://api.slack.com/start/overview#app_home) does not display properly, ensure your [app is up to date](gitlab_slack_application.md#update-the-gitlab-for-slack-app).
diff --git a/doc/user/project/integrations/gitlab_slack_application.md b/doc/user/project/integrations/gitlab_slack_application.md
index 7b2d3bfc203..0a42b363eb6 100644
--- a/doc/user/project/integrations/gitlab_slack_application.md
+++ b/doc/user/project/integrations/gitlab_slack_application.md
@@ -170,46 +170,3 @@ The following events are available for Slack notifications:
| **Deployment** | A deployment starts or finishes. |
| **Alert** | A new, unique alert is recorded. |
| [**Vulnerability**](../../application_security/vulnerabilities/index.md) | A new, unique vulnerability is recorded. |
-
-## Troubleshooting
-
-When configuring the GitLab for Slack app on GitLab.com, you might encounter the following issues.
-
-For self-managed GitLab, see [GitLab for Slack app administration](../../../administration/settings/slack_app.md#troubleshooting).
-
-### The app does not appear in the list of integrations
-
-The GitLab for Slack app might not appear in the list of integrations. To have the GitLab for Slack app on your self-managed instance, an administrator must [enable the integration](../../../administration/settings/slack_app.md). On GitLab.com, the GitLab for Slack app is available by default.
-
-The GitLab for Slack app is enabled at the project level only. Support for the app at the group and instance levels is proposed in [issue 391526](https://gitlab.com/gitlab-org/gitlab/-/issues/391526).
-
-### Project or alias not found
-
-Some Slack commands must have a project full path or alias and fail with the following error
-if the project cannot be found:
-
-```plaintext
-GitLab error: project or alias not found
-```
-
-As a workaround, ensure:
-
-- The project full path is correct.
-- If using a [project alias](#create-a-project-alias-for-slash-commands), the alias is correct.
-- The GitLab for Slack app is [enabled for the project](#from-project-integration-settings).
-
-### Slash commands return an error in Slack
-
-Slash commands might return `/gitlab failed with the error "dispatch_failed"` in Slack.
-To resolve this issue, ensure an administrator has properly configured the [GitLab for Slack app settings](../../../administration/settings/slack_app.md) on your self-managed instance.
-
-### Notifications are not received to a channel
-
-If you're not receiving notifications to a Slack channel, ensure:
-
-- The channel name you configured is correct.
-- If the channel is private, you've [added the GitLab for Slack app to the channel](#receive-notifications-to-a-private-channel).
-
-### The App Home does not display properly
-
-If the [App Home](https://api.slack.com/start/overview#app_home) does not display properly, ensure your [app is up to date](#update-the-gitlab-for-slack-app).
diff --git a/gems/gitlab-secret_detection/lib/gitlab/secret_detection.rb b/gems/gitlab-secret_detection/lib/gitlab/secret_detection.rb
index 95da376b7c1..eadcbc4de43 100644
--- a/gems/gitlab-secret_detection/lib/gitlab/secret_detection.rb
+++ b/gems/gitlab-secret_detection/lib/gitlab/secret_detection.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true
-require_relative 'secret_detection/version'
require_relative 'secret_detection/status'
require_relative 'secret_detection/finding'
require_relative 'secret_detection/response'
diff --git a/gems/gitlab-secret_detection/lib/gitlab/secret_detection/finding.rb b/gems/gitlab-secret_detection/lib/gitlab/secret_detection/finding.rb
index 9bded2dbf97..e8d83178b09 100644
--- a/gems/gitlab-secret_detection/lib/gitlab/secret_detection/finding.rb
+++ b/gems/gitlab-secret_detection/lib/gitlab/secret_detection/finding.rb
@@ -18,6 +18,16 @@ module Gitlab
self.class == other.class && other.state == state
end
+ def to_h
+ {
+ blob_id: blob_id,
+ status: status,
+ line_number: line_number,
+ type: type,
+ description: description
+ }
+ end
+
protected
def state
diff --git a/gems/gitlab-secret_detection/lib/gitlab/secret_detection/scan.rb b/gems/gitlab-secret_detection/lib/gitlab/secret_detection/scan.rb
index 83fc65a9b33..20d630d5dbb 100644
--- a/gems/gitlab-secret_detection/lib/gitlab/secret_detection/scan.rb
+++ b/gems/gitlab-secret_detection/lib/gitlab/secret_detection/scan.rb
@@ -34,9 +34,9 @@ module Gitlab
# in case the compilation fails.
def initialize(logger: Logger.new($stdout), ruleset_path: RULESET_FILE_PATH)
@logger = logger
- @rules = parse_ruleset ruleset_path
- @keywords = create_keywords @rules
- @matcher = build_pattern_matcher @rules
+ @rules = parse_ruleset(ruleset_path)
+ @keywords = create_keywords(rules)
+ @pattern_matcher = build_pattern_matcher(rules)
end
# Runs Secret Detection scan on the list of given blobs. Both the total scan duration and
@@ -52,49 +52,51 @@ module Gitlab
# status: One of the SecretDetection::Status values
# results: [SecretDetection::Finding]
# }
- #
- #
def secrets_scan(blobs, timeout: DEFAULT_SCAN_TIMEOUT_SECS, blob_timeout: DEFAULT_BLOB_TIMEOUT_SECS)
return SecretDetection::Response.new(SecretDetection::Status::INPUT_ERROR) unless validate_scan_input(blobs)
- Timeout.timeout timeout do
+ Timeout.timeout(timeout) do
matched_blobs = filter_by_keywords(blobs)
next SecretDetection::Response.new(SecretDetection::Status::NOT_FOUND) if matched_blobs.empty?
secrets = find_secrets_bulk(matched_blobs, blob_timeout)
- scan_status = overall_scan_status secrets
+ scan_status = overall_scan_status(secrets)
SecretDetection::Response.new(scan_status, secrets)
end
rescue Timeout::Error => e
- @logger.error "Secret Detection operation timed out: #{e}"
+ logger.error "Secret detection operation timed out: #{e}"
+
SecretDetection::Response.new(SecretDetection::Status::SCAN_TIMEOUT)
end
private
- attr_reader :logger, :rules, :keywords, :matcher
+ attr_reader :logger, :rules, :keywords, :pattern_matcher
# parses given ruleset file and returns the parsed rules
def parse_ruleset(ruleset_file_path)
rules_data = TomlRB.load_file(ruleset_file_path)
rules_data['rules']
rescue StandardError => e
- logger.error "Failed to parse Secret Detection ruleset from '#{ruleset_file_path}' path: #{e}"
+ logger.error "Failed to parse secret detection ruleset from '#{ruleset_file_path}' path: #{e}"
+
raise RulesetParseError
end
# builds RE2::Set pattern matcher for the given rules
def build_pattern_matcher(rules)
matcher = RE2::Set.new
+
rules.each do |rule|
- matcher.add(rule['regex'])
+ matcher.add(rule["regex"])
end
unless matcher.compile
- logger.error "Failed to compile Secret Detection rulesets in RE::Set"
+ logger.error "Failed to compile secret detection rulesets in RE::Set"
+
raise RulesetCompilationError
end
@@ -104,8 +106,9 @@ module Gitlab
# creates and returns the unique set of rule matching keywords
def create_keywords(rules)
secrets_keywords = []
+
rules.each do |rule|
- secrets_keywords << rule['keywords']
+ secrets_keywords << rule["keywords"]
end
secrets_keywords.flatten.compact.to_set
@@ -126,14 +129,16 @@ module Gitlab
# finds secrets in the given list of blobs
def find_secrets_bulk(blobs, blob_timeout)
found_secrets = []
+
blobs.each do |blob|
- found_secrets << Timeout.timeout(blob_timeout) do
- find_secrets(blob)
- end
+ found_secrets << Timeout.timeout(blob_timeout) { find_secrets(blob) }
rescue Timeout::Error => e
- logger.error "Secret Detection scan timed out on the blob(id:#{blob.id}): #{e}"
- found_secrets << SecretDetection::Finding.new(blob.id,
- SecretDetection::Status::BLOB_TIMEOUT)
+ logger.error "Secret detection scan timed out on the blob(id:#{blob.id}): #{e}"
+
+ found_secrets << SecretDetection::Finding.new(
+ blob.id,
+ SecretDetection::Status::BLOB_TIMEOUT
+ )
end
found_secrets.flatten.freeze
@@ -147,20 +152,28 @@ module Gitlab
# ignore the line scan if it is suffixed with '#gitleaks:allow'
next if line.end_with?(GITLEAKS_KEYWORD_IGNORE)
- patterns = matcher.match(line, :exception => false)
+ patterns = pattern_matcher.match(line, :exception => false)
next unless patterns.any?
- line_no = index + 1
+ line_number = index + 1
patterns.each do |pattern|
- type = rules[pattern]['id']
- description = rules[pattern]['description']
- secrets << SecretDetection::Finding.new(blob.id, SecretDetection::Status::FOUND, line_no, type,
- description)
+ type = rules[pattern]["id"]
+ description = rules[pattern]["description"]
+
+ secrets << SecretDetection::Finding.new(
+ blob.id,
+ SecretDetection::Status::FOUND,
+ line_number,
+ type,
+ description
+ )
end
end
+
secrets
rescue StandardError => e
- logger.error "Secret Detection scan failed on the blob(id:#{blob.id}): #{e}"
+ logger.error "Secret detection scan failed on the blob(id:#{blob.id}): #{e}"
+
SecretDetection::Finding.new(blob.id, SecretDetection::Status::SCAN_ERROR)
end
diff --git a/gems/gitlab-secret_detection/lib/gitlab/secret_detection/status.rb b/gems/gitlab-secret_detection/lib/gitlab/secret_detection/status.rb
index 45ac04a81b7..200294fc2e7 100644
--- a/gems/gitlab-secret_detection/lib/gitlab/secret_detection/status.rb
+++ b/gems/gitlab-secret_detection/lib/gitlab/secret_detection/status.rb
@@ -2,7 +2,7 @@
module Gitlab
module SecretDetection
- # All the possible statuses emitted by the Scan operation
+ # All the possible statuses emitted by the scan operation
class Status
NOT_FOUND = 0 # When scan operation completes with zero findings
FOUND = 1 # When scan operation completes with one or more findings
diff --git a/gems/gitlab-secret_detection/spec/lib/gitlab/secret_detection/scan_spec.rb b/gems/gitlab-secret_detection/spec/lib/gitlab/secret_detection/scan_spec.rb
index dfe3fdf4bb9..cd268099dd0 100644
--- a/gems/gitlab-secret_detection/spec/lib/gitlab/secret_detection/scan_spec.rb
+++ b/gems/gitlab-secret_detection/spec/lib/gitlab/secret_detection/scan_spec.rb
@@ -13,26 +13,34 @@ RSpec.describe Gitlab::SecretDetection::Scan, feature_category: :secret_detectio
{
"title" => "gitleaks config",
"rules" => [
- { "id" => "gitlab_personal_access_token",
+ {
+ "id" => "gitlab_personal_access_token",
"description" => "GitLab Personal Access Token",
"regex" => "glpat-[0-9a-zA-Z_\\-]{20}",
"tags" => %w[gitlab revocation_type],
- "keywords" => ["glpat"] },
- { "id" => "gitlab_pipeline_trigger_token",
+ "keywords" => ["glpat"]
+ },
+ {
+ "id" => "gitlab_pipeline_trigger_token",
"description" => "GitLab Pipeline Trigger Token",
"regex" => "glptt-[0-9a-zA-Z_\\-]{20}",
"tags" => ["gitlab"],
- "keywords" => ["glptt"] },
- { "id" => "gitlab_runner_registration_token",
+ "keywords" => ["glptt"]
+ },
+ {
+ "id" => "gitlab_runner_registration_token",
"description" => "GitLab Runner Registration Token",
"regex" => "GR1348941[0-9a-zA-Z_-]{20}",
"tags" => ["gitlab"],
- "keywords" => ["GR1348941"] },
- { "id" => "gitlab_feed_token",
+ "keywords" => ["GR1348941"]
+ },
+ {
+ "id" => "gitlab_feed_token",
"description" => "GitLab Feed Token",
"regex" => "glft-[0-9a-zA-Z_-]{20}",
"tags" => ["gitlab"],
- "keywords" => ["glft"] }
+ "keywords" => ["glft"]
+ }
]
}
end
@@ -65,16 +73,21 @@ RSpec.describe Gitlab::SecretDetection::Scan, feature_category: :secret_detectio
it "does not match" do
expected_response = Gitlab::SecretDetection::Response.new(Gitlab::SecretDetection::Status::NOT_FOUND)
+
expect(scan.secrets_scan(blobs)).to eq(expected_response)
end
it "attempts to keyword match returning no blobs for further scan" do
- expect(scan).to receive(:filter_by_keywords).with(blobs).and_return([])
+ expect(scan).to receive(:filter_by_keywords)
+ .with(blobs)
+ .and_return([])
+
scan.secrets_scan(blobs)
end
it "does not attempt to regex match" do
expect(scan).not_to receive(:match_rules_bulk)
+
scan.secrets_scan(blobs)
end
end
@@ -89,7 +102,7 @@ RSpec.describe Gitlab::SecretDetection::Scan, feature_category: :secret_detectio
]
end
- it "matches glpat" do
+ it "matches different types of rules" do
expected_response = Gitlab::SecretDetection::Response.new(
Gitlab::SecretDetection::Status::FOUND,
[
@@ -129,6 +142,8 @@ RSpec.describe Gitlab::SecretDetection::Scan, feature_category: :secret_detectio
end
context "when configured with time out" do
+ let(:each_blob_timeout_secs) { 0.000_001 } # 1 micro-sec to intentionally timeout large blob
+
let(:large_data) do
("large data with a secret glpat-12312312312312312312\n" * 10_000_000).freeze # gitleaks:allow
end
@@ -141,40 +156,44 @@ RSpec.describe Gitlab::SecretDetection::Scan, feature_category: :secret_detectio
]
end
+ let(:all_large_blobs) do
+ [
+ new_blob(id: 111, data: large_data),
+ new_blob(id: 222, data: large_data),
+ new_blob(id: 333, data: large_data)
+ ]
+ end
+
it "whole secret detection scan operation times out" do
scan_timeout_secs = 0.000_001 # 1 micro-sec to intentionally timeout large blob
+
response = Gitlab::SecretDetection::Response.new(Gitlab::SecretDetection::Status::SCAN_TIMEOUT)
+
expect(scan.secrets_scan(blobs, timeout: scan_timeout_secs)).to eq(response)
end
it "one of the blobs times out while others continue to get scanned" do
- each_blob_timeout_secs = 0.000_001 # 1 micro-sec to intentionally timeout large blob
-
expected_response = Gitlab::SecretDetection::Response.new(
Gitlab::SecretDetection::Status::FOUND_WITH_ERRORS,
[
Gitlab::SecretDetection::Finding.new(
- blobs[0].id, Gitlab::SecretDetection::Status::FOUND, 1,
+ blobs[0].id,
+ Gitlab::SecretDetection::Status::FOUND,
+ 1,
ruleset['rules'][2]['id'],
ruleset['rules'][2]['description']
),
Gitlab::SecretDetection::Finding.new(
- blobs[2].id, Gitlab::SecretDetection::Status::BLOB_TIMEOUT
+ blobs[2].id,
+ Gitlab::SecretDetection::Status::BLOB_TIMEOUT
)
- ])
+ ]
+ )
expect(scan.secrets_scan(blobs, blob_timeout: each_blob_timeout_secs)).to eq(expected_response)
end
it "all the blobs time out" do
- each_blob_timeout_secs = 0.000_001 # 1 micro-sec to intentionally timeout large blob
-
- all_large_blobs = [
- new_blob(id: 111, data: large_data),
- new_blob(id: 222, data: large_data),
- new_blob(id: 333, data: large_data)
- ]
-
# scan status changes to SCAN_TIMEOUT when *all* the blobs time out
expected_scan_status = Gitlab::SecretDetection::Status::SCAN_TIMEOUT
@@ -182,15 +201,19 @@ RSpec.describe Gitlab::SecretDetection::Scan, feature_category: :secret_detectio
expected_scan_status,
[
Gitlab::SecretDetection::Finding.new(
- all_large_blobs[0].id, Gitlab::SecretDetection::Status::BLOB_TIMEOUT
+ all_large_blobs[0].id,
+ Gitlab::SecretDetection::Status::BLOB_TIMEOUT
),
Gitlab::SecretDetection::Finding.new(
- all_large_blobs[1].id, Gitlab::SecretDetection::Status::BLOB_TIMEOUT
+ all_large_blobs[1].id,
+ Gitlab::SecretDetection::Status::BLOB_TIMEOUT
),
Gitlab::SecretDetection::Finding.new(
- all_large_blobs[2].id, Gitlab::SecretDetection::Status::BLOB_TIMEOUT
+ all_large_blobs[2].id,
+ Gitlab::SecretDetection::Status::BLOB_TIMEOUT
)
- ])
+ ]
+ )
expect(scan.secrets_scan(all_large_blobs, blob_timeout: each_blob_timeout_secs)).to eq(expected_response)
end
diff --git a/lib/bulk_imports/common/pipelines/entity_finisher.rb b/lib/bulk_imports/common/pipelines/entity_finisher.rb
index a8bbd122445..2ab7a0e12d7 100644
--- a/lib/bulk_imports/common/pipelines/entity_finisher.rb
+++ b/lib/bulk_imports/common/pipelines/entity_finisher.rb
@@ -28,13 +28,8 @@ module BulkImports
end
logger.info(
- bulk_import_id: entity.bulk_import_id,
- bulk_import_entity_id: entity.id,
- bulk_import_entity_type: entity.source_type,
- source_full_path: entity.source_full_path,
pipeline_class: self.class.name,
- message: "Entity #{entity.status_name}",
- source_version: entity.bulk_import.source_version_info.to_s
+ message: "Entity #{entity.status_name}"
)
::BulkImports::FinishProjectImportWorker.perform_async(entity.project_id) if entity.project?
@@ -45,7 +40,7 @@ module BulkImports
attr_reader :context, :entity, :trackers
def logger
- @logger ||= Logger.build
+ @logger ||= Logger.build.with_entity(entity)
end
def all_other_trackers_failed?
diff --git a/lib/bulk_imports/logger.rb b/lib/bulk_imports/logger.rb
index be15c050770..3b62d0ffdf3 100644
--- a/lib/bulk_imports/logger.rb
+++ b/lib/bulk_imports/logger.rb
@@ -4,8 +4,55 @@ module BulkImports
class Logger < ::Gitlab::Import::Logger
IMPORTER_NAME = 'gitlab_migration'
+ # Extract key information from a provided entity and include it in log
+ # entries created from this logger instance.
+ # @param entity [BulkImports::Entity]
+ def with_entity(entity)
+ @entity = entity
+ self
+ end
+
+ # Extract key information from a provided tracker and its entity and include
+ # it in log entries created from this logger instance.
+ # @param tracker [BulkImports::Tracker]
+ def with_tracker(tracker)
+ with_entity(tracker.entity)
+ @tracker = tracker
+ self
+ end
+
+ def entity_attributes
+ return {} unless entity
+
+ {
+ bulk_import_id: entity.bulk_import_id,
+ bulk_import_entity_id: entity.id,
+ bulk_import_entity_type: entity.source_type,
+ source_full_path: entity.source_full_path,
+ source_version: entity.source_version.to_s
+ }
+ end
+
+ def tracker_attributes
+ return {} unless tracker
+
+ {
+ tracker_id: tracker.id,
+ pipeline_class: tracker.pipeline_name,
+ tracker_state: tracker.human_status_name
+ }
+ end
+
def default_attributes
- super.merge(importer: IMPORTER_NAME)
+ super.merge(
+ { importer: IMPORTER_NAME },
+ entity_attributes,
+ tracker_attributes
+ )
end
+
+ private
+
+ attr_reader :entity, :tracker
end
end
diff --git a/lib/bulk_imports/pipeline/runner.rb b/lib/bulk_imports/pipeline/runner.rb
index e1da7c301e9..7b5e1e68459 100644
--- a/lib/bulk_imports/pipeline/runner.rb
+++ b/lib/bulk_imports/pipeline/runner.rb
@@ -166,12 +166,8 @@ module BulkImports
def log_params(extra)
defaults = {
bulk_import_id: context.bulk_import_id,
- bulk_import_entity_id: context.entity.id,
- bulk_import_entity_type: context.entity.source_type,
- source_full_path: context.entity.source_full_path,
pipeline_class: pipeline,
- context_extra: context.extra,
- source_version: context.entity.bulk_import.source_version_info.to_s
+ context_extra: context.extra
}
defaults
@@ -180,7 +176,7 @@ module BulkImports
end
def logger
- @logger ||= Logger.build
+ @logger ||= Logger.build.with_entity(context.entity)
end
def log_exception(exception, payload)
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 9fef2025f04..422f0173c21 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -542,6 +542,9 @@ msgstr ""
msgid "%{authorsName}'s thread"
msgstr ""
+msgid "%{author} has added you as an approver."
+msgstr ""
+
msgid "%{author} requested to merge %{source_branch} %{copy_button} into %{target_branch} %{created_at}"
msgstr ""
@@ -1184,6 +1187,9 @@ msgstr[1] ""
msgid "%{strongStart}Tip:%{strongEnd} You can also %{linkStart}check out with merge request ID%{linkEnd}."
msgstr ""
+msgid "%{strong_start}%{author}%{strong_end} has added you as an approver."
+msgstr ""
+
msgid "%{strong_start}%{branch_count}%{strong_end} Branch"
msgid_plural "%{strong_start}%{branch_count}%{strong_end} Branches"
msgstr[0] ""
@@ -4953,9 +4959,6 @@ msgstr ""
msgid "Allows projects to track errors using an Opstrace integration."
msgstr ""
-msgid "Allows you to add and manage Kubernetes clusters."
-msgstr ""
-
msgid "Almost there"
msgstr ""
@@ -5106,9 +5109,6 @@ msgstr ""
msgid "An error occurred while dismissing the alert. Refresh the page and try again."
msgstr ""
-msgid "An error occurred while dismissing the feature highlight. Refresh the page and try dismissing again."
-msgstr ""
-
msgid "An error occurred while drawing job relationship links."
msgstr ""
@@ -10079,6 +10079,9 @@ msgstr ""
msgid "Checkout|Confirming..."
msgstr ""
+msgid "Checkout|Contact information"
+msgstr ""
+
msgid "Checkout|Continue to billing"
msgstr ""
@@ -10139,6 +10142,9 @@ msgstr ""
msgid "Checkout|Invalid coupon code. Enter a valid coupon code."
msgstr ""
+msgid "Checkout|Manage the subscription and billing contacts for your billing account in the %{customersPortalLinkStart}Customers Portal%{customersPortalLinkEnd}. Learn more about %{manageContactsLinkStart}how to manage your contacts%{manageContactsLinkEnd}."
+msgstr ""
+
msgid "Checkout|Must be %{minimumNumberOfUsers} (your seats in use) or more."
msgstr ""
@@ -22841,9 +22847,6 @@ msgstr ""
msgid "Got it"
msgstr ""
-msgid "Got it!"
-msgstr ""
-
msgid "Grafana URL"
msgstr ""
@@ -23180,9 +23183,6 @@ msgstr ""
msgid "GroupSAML|Could not create SAML group link: %{errors}."
msgstr ""
-msgid "GroupSAML|Custom roles"
-msgstr ""
-
msgid "GroupSAML|Default membership role"
msgstr ""
@@ -23282,9 +23282,6 @@ msgstr ""
msgid "GroupSAML|Some to-do items may be hidden because your SAML session has expired. Select the group’s path to reauthenticate and view the hidden to-do items."
msgstr ""
-msgid "GroupSAML|Standard roles"
-msgstr ""
-
msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to %{linkStart}reset it%{linkEnd}."
msgstr ""
@@ -32429,6 +32426,9 @@ msgid_plural "NotificationEmail|Reviewers: %{users}"
msgstr[0] ""
msgstr[1] ""
+msgid "NotificationEvent|Added as approver"
+msgstr ""
+
msgid "NotificationEvent|Change reviewer merge request"
msgstr ""
@@ -39254,9 +39254,6 @@ msgstr ""
msgid "ProtectedTag|default"
msgstr ""
-msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
-msgstr ""
-
msgid "Provide Feedback"
msgstr ""
@@ -50779,6 +50776,9 @@ msgstr ""
msgid "Todos|has requested access to %{what} %{which}"
msgstr ""
+msgid "Todos|have been added as an approver"
+msgstr ""
+
msgid "Todos|mentioned %{who}"
msgstr ""
diff --git a/qa/.confiner/master.yml b/qa/.confiner/master.yml
deleted file mode 100644
index f58ea5de017..00000000000
--- a/qa/.confiner/master.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-- name: Quarantine E2E tests in Master that fail consistently
- plugin:
- name: gitlab # https://gitlab.com/gitlab-org/quality/confiner/-/blob/main/doc/plugins/gitlab.md
- args:
- threshold: 3 # 3 failures
- private_token: $QA_GITLAB_CI_TOKEN
- project_id: gitlab-org/gitlab
- target_project: gitlab-org/gitlab
- failure_issue_labels: QA,Quality
- failure_issue_prefix: "Failure in "
- pwd: qa # E2E specs reside in the qa subdirectory
- timeout: 30
- ref: master
- actions:
- - quarantine
diff --git a/qa/Gemfile b/qa/Gemfile
index 5c44fa5068a..19800677673 100644
--- a/qa/Gemfile
+++ b/qa/Gemfile
@@ -33,8 +33,6 @@ gem 'fog-google', '~> 1.19', require: false
gem 'fog-core', '2.1.0', require: false # fog-google generates a ton of warnings with latest core
gem "warning", "~> 1.3"
-gem 'confiner', '~> 0.4'
-
gem 'chemlab', '~> 0.11', '>= 0.11.1'
gem 'chemlab-library-www-gitlab-com', '~> 0.1', '>= 0.1.1'
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index c222de2e013..d8d1fb4066a 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -69,9 +69,6 @@ GEM
coderay (1.1.2)
colorize (0.8.1)
concurrent-ruby (1.2.2)
- confiner (0.4.0)
- gitlab (>= 4.17)
- zeitwerk (>= 2.5, < 3)
crass (1.0.6)
debug_inspector (1.1.0)
declarative (0.0.20)
@@ -356,7 +353,6 @@ DEPENDENCIES
capybara-screenshot (~> 1.0.26)
chemlab (~> 0.11, >= 0.11.1)
chemlab-library-www-gitlab-com (~> 0.1, >= 0.1.1)
- confiner (~> 0.4)
deprecation_toolkit (~> 2.0.4)
factory_bot (~> 6.3.0)
faker (~> 3.2, >= 3.2.2)
diff --git a/spec/frontend/feature_highlight/feature_highlight_helper_spec.js b/spec/frontend/feature_highlight/feature_highlight_helper_spec.js
deleted file mode 100644
index 4609bfc23d7..00000000000
--- a/spec/frontend/feature_highlight/feature_highlight_helper_spec.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import MockAdapter from 'axios-mock-adapter';
-import { dismiss } from '~/feature_highlight/feature_highlight_helper';
-import { createAlert } from '~/alert';
-import axios from '~/lib/utils/axios_utils';
-import { HTTP_STATUS_CREATED, HTTP_STATUS_INTERNAL_SERVER_ERROR } from '~/lib/utils/http_status';
-
-jest.mock('~/alert');
-
-describe('feature highlight helper', () => {
- describe('dismiss', () => {
- let mockAxios;
- const endpoint = '/-/callouts/dismiss';
- const highlightId = '123';
-
- beforeEach(() => {
- mockAxios = new MockAdapter(axios);
- });
-
- afterEach(() => {
- mockAxios.reset();
- });
-
- it('calls persistent dismissal endpoint with highlightId', async () => {
- mockAxios.onPost(endpoint, { feature_name: highlightId }).replyOnce(HTTP_STATUS_CREATED);
-
- await expect(dismiss(endpoint, highlightId)).resolves.toEqual(expect.anything());
- });
-
- it('triggers an alert when dismiss request fails', async () => {
- mockAxios
- .onPost(endpoint, { feature_name: highlightId })
- .replyOnce(HTTP_STATUS_INTERNAL_SERVER_ERROR);
-
- await dismiss(endpoint, highlightId);
-
- expect(createAlert).toHaveBeenCalledWith({
- message:
- 'An error occurred while dismissing the feature highlight. Refresh the page and try dismissing again.',
- });
- });
- });
-});
diff --git a/spec/frontend/feature_highlight/feature_highlight_popover_spec.js b/spec/frontend/feature_highlight/feature_highlight_popover_spec.js
deleted file mode 100644
index 66ea22cece3..00000000000
--- a/spec/frontend/feature_highlight/feature_highlight_popover_spec.js
+++ /dev/null
@@ -1,75 +0,0 @@
-import { GlPopover, GlLink, GlButton } from '@gitlab/ui';
-import { mount } from '@vue/test-utils';
-import { nextTick } from 'vue';
-import { POPOVER_TARGET_ID } from '~/feature_highlight/constants';
-import { dismiss } from '~/feature_highlight/feature_highlight_helper';
-import FeatureHighlightPopover from '~/feature_highlight/feature_highlight_popover.vue';
-
-jest.mock('~/feature_highlight/feature_highlight_helper');
-
-describe('feature_highlight/feature_highlight_popover', () => {
- let wrapper;
- const props = {
- autoDevopsHelpPath: '/help/autodevops',
- highlightId: '123',
- dismissEndpoint: '/api/dismiss',
- };
-
- const buildWrapper = (propsData = props) => {
- wrapper = mount(FeatureHighlightPopover, {
- propsData,
- });
- };
- const findPopoverTarget = () => wrapper.find(`#${POPOVER_TARGET_ID}`);
- const findPopover = () => wrapper.findComponent(GlPopover);
- const findAutoDevopsHelpLink = () => wrapper.findComponent(GlLink);
- const findDismissButton = () => wrapper.findComponent(GlButton);
-
- beforeEach(() => {
- buildWrapper();
- });
-
- it('renders popover target', () => {
- expect(findPopoverTarget().exists()).toBe(true);
- });
-
- it('renders popover', () => {
- expect(findPopover().props()).toMatchObject({
- target: POPOVER_TARGET_ID,
- cssClasses: ['feature-highlight-popover'],
- container: 'body',
- placement: 'right',
- boundary: 'viewport',
- });
- });
-
- it('renders link that points to the autodevops help page', () => {
- expect(findAutoDevopsHelpLink().attributes().href).toBe(props.autoDevopsHelpPath);
- expect(findAutoDevopsHelpLink().text()).toBe('Auto DevOps');
- });
-
- it('renders dismiss button', () => {
- expect(findDismissButton().props()).toMatchObject({
- size: 'small',
- icon: 'thumb-up',
- variant: 'confirm',
- });
- });
-
- it('dismisses popover when dismiss button is clicked', async () => {
- await findDismissButton().trigger('click');
-
- expect(findPopover().emitted('close')).toHaveLength(1);
- expect(dismiss).toHaveBeenCalledWith(props.dismissEndpoint, props.highlightId);
- });
-
- describe('when popover is dismissed and hidden', () => {
- it('hides the popover target', async () => {
- await findDismissButton().trigger('click');
- findPopover().vm.$emit('hidden');
- await nextTick();
-
- expect(findPopoverTarget().exists()).toBe(false);
- });
- });
-});
diff --git a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_ready_to_merge_spec.js
index dbfd3cec76c..1b7338744e8 100644
--- a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_ready_to_merge_spec.js
+++ b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_ready_to_merge_spec.js
@@ -1,9 +1,10 @@
-import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import { GlSprintf } from '@gitlab/ui';
import VueApollo from 'vue-apollo';
import produce from 'immer';
+import { createMockSubscription as createMockApolloSubscription } from 'mock-apollo-client';
import readyToMergeResponse from 'test_fixtures/graphql/merge_requests/states/ready_to_merge.query.graphql.json';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import createMockApollo from 'helpers/mock_apollo_helper';
import readyToMergeQuery from 'ee_else_ce/vue_merge_request_widget/queries/states/ready_to_merge.query.graphql';
@@ -15,6 +16,7 @@ import SquashBeforeMerge from '~/vue_merge_request_widget/components/states/squa
import MergeFailedPipelineConfirmationDialog from '~/vue_merge_request_widget/components/states/merge_failed_pipeline_confirmation_dialog.vue';
import { MWPS_MERGE_STRATEGY } from '~/vue_merge_request_widget/constants';
import eventHub from '~/vue_merge_request_widget/event_hub';
+import readyToMergeSubscription from '~/vue_merge_request_widget/queries/states/ready_to_merge.subscription.graphql';
jest.mock('~/lib/utils/simple_poll', () =>
jest.fn().mockImplementation(jest.requireActual('~/lib/utils/simple_poll').default),
@@ -79,6 +81,7 @@ Vue.use(VueApollo);
let service;
let wrapper;
let readyToMergeResponseSpy;
+let mockedSubscription;
const createReadyToMergeResponse = (customMr) => {
return produce(readyToMergeResponse, (draft) => {
@@ -87,7 +90,21 @@ const createReadyToMergeResponse = (customMr) => {
};
const createComponent = (customConfig = {}, createState = true) => {
- wrapper = shallowMount(ReadyToMerge, {
+ mockedSubscription = createMockApolloSubscription();
+ const apolloProvider = createMockApollo([[readyToMergeQuery, readyToMergeResponseSpy]]);
+ const subscriptionResponse = {
+ data: { mergeRequestMergeStatusUpdated: { ...readyToMergeResponse.data.project.mergeRequest } },
+ };
+ subscriptionResponse.data.mergeRequestMergeStatusUpdated.defaultMergeCommitMessage =
+ 'New default merge commit message';
+
+ const subscriptionHandlers = [[readyToMergeSubscription, () => mockedSubscription]];
+
+ subscriptionHandlers.forEach(([query, stream]) => {
+ apolloProvider.defaultClient.setRequestHandler(query, stream);
+ });
+
+ wrapper = shallowMountExtended(ReadyToMerge, {
propsData: {
mr: createTestMr(customConfig),
service,
@@ -109,7 +126,7 @@ const createComponent = (customConfig = {}, createState = true) => {
CommitEdit,
GlSprintf,
},
- apolloProvider: createMockApollo([[readyToMergeQuery, readyToMergeResponseSpy]]),
+ apolloProvider,
});
};
@@ -840,4 +857,60 @@ describe('ReadyToMerge', () => {
expect(wrapper.text()).not.toContain('Auto-merge enabled');
});
});
+
+ describe('commit message', () => {
+ it('updates commit message from subscription', async () => {
+ createComponent({ mr: { id: 1 } });
+
+ await waitForPromises();
+
+ await wrapper.findByTestId('widget_edit_commit_message').vm.$emit('input', true);
+
+ expect(wrapper.findByTestId('merge-commit-message').props('value')).not.toEqual(
+ 'Updated commit message',
+ );
+
+ mockedSubscription.next({
+ data: {
+ mergeRequestMergeStatusUpdated: {
+ ...readyToMergeResponse.data.project.mergeRequest,
+ defaultMergeCommitMessage: 'Updated commit message',
+ },
+ },
+ });
+
+ await waitForPromises();
+
+ expect(wrapper.findByTestId('merge-commit-message').props('value')).toEqual(
+ 'Updated commit message',
+ );
+ });
+
+ it('does not update commit message from subscription if commit message has been manually changed', async () => {
+ createComponent({ mr: { id: 1 } });
+
+ await waitForPromises();
+
+ await wrapper.findByTestId('widget_edit_commit_message').vm.$emit('input', true);
+
+ await wrapper
+ .findByTestId('merge-commit-message')
+ .vm.$emit('input', 'Manually updated commit message');
+
+ mockedSubscription.next({
+ data: {
+ mergeRequestMergeStatusUpdated: {
+ ...readyToMergeResponse.data.project.mergeRequest,
+ defaultMergeCommitMessage: 'Updated commit message',
+ },
+ },
+ });
+
+ await waitForPromises();
+
+ expect(wrapper.findByTestId('merge-commit-message').props('value')).toEqual(
+ 'Manually updated commit message',
+ );
+ });
+ });
});
diff --git a/spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb b/spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb
index b96ea20c676..e1ad9c75dcb 100644
--- a/spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb
+++ b/spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb
@@ -10,16 +10,13 @@ RSpec.describe BulkImports::Common::Pipelines::EntityFinisher, feature_category:
subject = described_class.new(context)
expect_next_instance_of(BulkImports::Logger) do |logger|
+ expect(logger).to receive(:with_entity).with(entity).and_call_original
+
expect(logger)
.to receive(:info)
.with(
- bulk_import_id: entity.bulk_import_id,
- bulk_import_entity_id: entity.id,
- bulk_import_entity_type: entity.source_type,
- source_full_path: entity.source_full_path,
pipeline_class: described_class.name,
- message: 'Entity finished',
- source_version: entity.bulk_import.source_version_info.to_s
+ message: 'Entity finished'
)
end
diff --git a/spec/lib/bulk_imports/common/pipelines/lfs_objects_pipeline_spec.rb b/spec/lib/bulk_imports/common/pipelines/lfs_objects_pipeline_spec.rb
index 5ba9bd08009..5662c4d7bdc 100644
--- a/spec/lib/bulk_imports/common/pipelines/lfs_objects_pipeline_spec.rb
+++ b/spec/lib/bulk_imports/common/pipelines/lfs_objects_pipeline_spec.rb
@@ -192,7 +192,7 @@ RSpec.describe BulkImports::Common::Pipelines::LfsObjectsPipeline, feature_categ
allow(object).to receive(:persisted?).and_return(false)
end
- expect_next_instance_of(Gitlab::Import::Logger) do |logger|
+ expect_next_instance_of(BulkImports::Logger) do |logger|
expect(logger)
.to receive(:warn)
.with(project_id: portable.id,
diff --git a/spec/lib/bulk_imports/logger_spec.rb b/spec/lib/bulk_imports/logger_spec.rb
new file mode 100644
index 00000000000..889e5573c66
--- /dev/null
+++ b/spec/lib/bulk_imports/logger_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe BulkImports::Logger, feature_category: :importers do
+ describe '#with_entity' do
+ subject(:logger) { described_class.new('/dev/null').with_entity(entity) }
+
+ let(:entity) { build(:bulk_import_entity) }
+
+ it 'records the entity information' do
+ output = logger.format_message('INFO', Time.zone.now, 'test', 'Hello world')
+ data = Gitlab::Json.parse(output)
+
+ expect(data).to include(
+ 'bulk_import_id' => entity.bulk_import_id,
+ 'bulk_import_entity_id' => entity.id,
+ 'bulk_import_entity_type' => entity.source_type,
+ 'source_full_path' => entity.source_full_path,
+ 'source_version' => entity.bulk_import.source_version_info.to_s
+ )
+ end
+ end
+
+ describe '#with_tracker' do
+ subject(:logger) { described_class.new('/dev/null').with_tracker(tracker) }
+
+ let_it_be(:tracker) { build(:bulk_import_tracker) }
+
+ it 'records the tracker information' do
+ output = logger.format_message('INFO', Time.zone.now, 'test', 'Hello world')
+ data = Gitlab::Json.parse(output)
+
+ expect(data).to include(
+ 'tracker_id' => tracker.id,
+ 'pipeline_class' => tracker.pipeline_name,
+ 'tracker_state' => tracker.human_status_name
+ )
+ end
+
+ it 'also loads the entity data' do
+ expect_next_instance_of(described_class) do |logger|
+ expect(logger).to receive(:with_entity).once
+ end
+
+ logger
+ end
+ end
+end
diff --git a/spec/lib/bulk_imports/pipeline/runner_spec.rb b/spec/lib/bulk_imports/pipeline/runner_spec.rb
index a88e8fb50d3..72e5e16a5b4 100644
--- a/spec/lib/bulk_imports/pipeline/runner_spec.rb
+++ b/spec/lib/bulk_imports/pipeline/runner_spec.rb
@@ -55,13 +55,11 @@ RSpec.describe BulkImports::Pipeline::Runner, feature_category: :importers do
shared_examples 'failed pipeline' do |exception_class, exception_message|
it 'logs import failure' do
expect_next_instance_of(BulkImports::Logger) do |logger|
+ expect(logger).to receive(:with_entity).with(context.entity).and_call_original
expect(logger).to receive(:error)
.with(
a_hash_including(
- 'bulk_import_entity_id' => entity.id,
'bulk_import_id' => entity.bulk_import_id,
- 'bulk_import_entity_type' => entity.source_type,
- 'source_full_path' => entity.source_full_path,
'pipeline_step' => :extractor,
'pipeline_class' => 'BulkImports::MyPipeline',
'exception.class' => exception_class,
@@ -69,8 +67,7 @@ RSpec.describe BulkImports::Pipeline::Runner, feature_category: :importers do
'correlation_id' => anything,
'class' => 'BulkImports::MyPipeline',
'message' => 'An object of a pipeline failed to import',
- 'exception.backtrace' => anything,
- 'source_version' => entity.bulk_import.source_version_info.to_s
+ 'exception.backtrace' => anything
)
)
end
@@ -94,6 +91,7 @@ RSpec.describe BulkImports::Pipeline::Runner, feature_category: :importers do
it 'logs a warn message and marks entity and tracker as failed' do
expect_next_instance_of(BulkImports::Logger) do |logger|
+ expect(logger).to receive(:with_entity).with(context.entity).and_call_original
expect(logger).to receive(:warn)
.with(
log_params(
@@ -198,7 +196,8 @@ RSpec.describe BulkImports::Pipeline::Runner, feature_category: :importers do
expect(context.bulk_import).to receive(:touch)
expect(context.entity).to receive(:touch)
- expect_next_instance_of(Gitlab::Import::Logger) do |logger|
+ expect_next_instance_of(BulkImports::Logger) do |logger|
+ expect(logger).to receive(:with_entity).with(context.entity).and_call_original
expect(logger).to receive(:info)
.with(
log_params(
@@ -419,6 +418,7 @@ RSpec.describe BulkImports::Pipeline::Runner, feature_category: :importers do
entity.fail_op!
expect_next_instance_of(BulkImports::Logger) do |logger|
+ expect(logger).to receive(:with_entity).with(context.entity).and_call_original
expect(logger).to receive(:warn)
.with(
log_params(
@@ -436,10 +436,6 @@ RSpec.describe BulkImports::Pipeline::Runner, feature_category: :importers do
def log_params(context, extra = {})
{
bulk_import_id: context.bulk_import_id,
- bulk_import_entity_id: context.entity.id,
- bulk_import_entity_type: context.entity.source_type,
- source_full_path: entity.source_full_path,
- source_version: context.entity.bulk_import.source_version_info.to_s,
context_extra: context.extra
}.merge(extra)
end
diff --git a/spec/models/notification_recipient_spec.rb b/spec/models/notification_recipient_spec.rb
index f19c0a68f87..65bf7aec269 100644
--- a/spec/models/notification_recipient_spec.rb
+++ b/spec/models/notification_recipient_spec.rb
@@ -440,8 +440,8 @@ RSpec.describe NotificationRecipient, feature_category: :team_planning do
described_class.new(user, :participating, custom_action: :issue_due, target: target, project: project)
end
- it 'returns true' do
- expect(recipient.suitable_notification_level?).to eq true
+ it 'returns false' do
+ expect(recipient.suitable_notification_level?).to eq false
end
end
end
diff --git a/spec/models/notification_setting_spec.rb b/spec/models/notification_setting_spec.rb
index 1bb639a5907..cb1bbb91a67 100644
--- a/spec/models/notification_setting_spec.rb
+++ b/spec/models/notification_setting_spec.rb
@@ -193,7 +193,11 @@ RSpec.describe NotificationSetting do
end
it 'includes EXCLUDED_WATCHER_EVENTS' do
- expect(subject).to include(*described_class::EXCLUDED_WATCHER_EVENTS)
+ expect(subject).to include(
+ :push_to_merge_request,
+ :issue_due,
+ :success_pipeline
+ )
end
end
diff --git a/spec/services/bulk_imports/file_download_service_spec.rb b/spec/services/bulk_imports/file_download_service_spec.rb
index 0d9fe96bb64..0c3eef69fa5 100644
--- a/spec/services/bulk_imports/file_download_service_spec.rb
+++ b/spec/services/bulk_imports/file_download_service_spec.rb
@@ -95,7 +95,6 @@ RSpec.describe BulkImports::FileDownloadService, feature_category: :importers do
message: 'Invalid content type',
response_code: chunk_code,
response_headers: headers,
- importer: 'gitlab_migration',
last_chunk_context: 'some chunk context'
)
diff --git a/spec/services/bulk_imports/process_service_spec.rb b/spec/services/bulk_imports/process_service_spec.rb
index f5566819039..a295b170c2f 100644
--- a/spec/services/bulk_imports/process_service_spec.rb
+++ b/spec/services/bulk_imports/process_service_spec.rb
@@ -205,28 +205,20 @@ RSpec.describe BulkImports::ProcessService, feature_category: :importers do
it 'logs an info message for the skipped pipelines' do
expect_next_instance_of(BulkImports::Logger) do |logger|
+ expect(logger).to receive(:with_entity).with(entity).and_call_original.twice
+
expect(logger).to receive(:info).with(
message: 'Pipeline skipped as source instance version not compatible with pipeline',
- bulk_import_entity_id: entity.id,
- bulk_import_id: entity.bulk_import_id,
- bulk_import_entity_type: entity.source_type,
- source_full_path: entity.source_full_path,
pipeline_class: 'PipelineClass4',
minimum_source_version: '15.1.0',
- maximum_source_version: nil,
- source_version: '15.0.0'
+ maximum_source_version: nil
)
expect(logger).to receive(:info).with(
message: 'Pipeline skipped as source instance version not compatible with pipeline',
- bulk_import_entity_id: entity.id,
- bulk_import_id: entity.bulk_import_id,
- bulk_import_entity_type: entity.source_type,
- source_full_path: entity.source_full_path,
pipeline_class: 'PipelineClass5',
minimum_source_version: '16.0.0',
- maximum_source_version: nil,
- source_version: '15.0.0'
+ maximum_source_version: nil
)
end
diff --git a/spec/workers/bulk_imports/entity_worker_spec.rb b/spec/workers/bulk_imports/entity_worker_spec.rb
index 4988a368598..325b31c85db 100644
--- a/spec/workers/bulk_imports/entity_worker_spec.rb
+++ b/spec/workers/bulk_imports/entity_worker_spec.rb
@@ -73,6 +73,8 @@ RSpec.describe BulkImports::EntityWorker, feature_category: :importers do
it 'enqueues the pipeline workers from the next stage and re-enqueues itself' do
expect_next_instance_of(BulkImports::Logger) do |logger|
+ expect(logger).to receive(:with_entity).with(entity).and_call_original
+
expect(logger).to receive(:info).with(hash_including('message' => 'Stage starting', 'entity_stage' => 1))
end
diff --git a/spec/workers/bulk_imports/export_request_worker_spec.rb b/spec/workers/bulk_imports/export_request_worker_spec.rb
index e9d0b6b24b2..2cc6348bb27 100644
--- a/spec/workers/bulk_imports/export_request_worker_spec.rb
+++ b/spec/workers/bulk_imports/export_request_worker_spec.rb
@@ -72,17 +72,14 @@ RSpec.describe BulkImports::ExportRequestWorker, feature_category: :importers do
entity.update!(source_xid: nil)
expect_next_instance_of(BulkImports::Logger) do |logger|
+ expect(logger).to receive(:with_entity).with(entity).and_call_original
+
expect(logger).to receive(:error).with(
a_hash_including(
- 'bulk_import_entity_id' => entity.id,
- 'bulk_import_id' => entity.bulk_import_id,
- 'bulk_import_entity_type' => entity.source_type,
- 'source_full_path' => entity.source_full_path,
'exception.backtrace' => anything,
'exception.class' => 'NoMethodError',
'exception.message' => /^undefined method `model_id' for nil:NilClass/,
- 'message' => 'Failed to fetch source entity id',
- 'source_version' => entity.bulk_import.source_version_info.to_s
+ 'message' => 'Failed to fetch source entity id'
)
).twice
end
@@ -148,7 +145,9 @@ RSpec.describe BulkImports::ExportRequestWorker, feature_category: :importers do
entity = create(:bulk_import_entity, bulk_import: bulk_import)
error = 'Exhausted error!'
- expect_next_instance_of(Gitlab::Import::Logger) do |logger|
+ expect_next_instance_of(BulkImports::Logger) do |logger|
+ expect(logger).to receive(:with_entity).with(entity).and_call_original
+
expect(logger)
.to receive(:error)
.with(hash_including('message' => "Request to export #{entity.source_type} failed"))
diff --git a/spec/workers/bulk_imports/finish_batched_pipeline_worker_spec.rb b/spec/workers/bulk_imports/finish_batched_pipeline_worker_spec.rb
index 959b063e061..2dd5b23b3d2 100644
--- a/spec/workers/bulk_imports/finish_batched_pipeline_worker_spec.rb
+++ b/spec/workers/bulk_imports/finish_batched_pipeline_worker_spec.rb
@@ -49,6 +49,9 @@ RSpec.describe BulkImports::FinishBatchedPipelineWorker, feature_category: :impo
it 'marks the tracker as finished' do
expect_next_instance_of(BulkImports::Logger) do |logger|
+ expect(logger).to receive(:with_tracker).with(pipeline_tracker).and_call_original
+ expect(logger).to receive(:with_entity).with(entity).and_call_original
+
expect(logger).to receive(:info).with(
a_hash_including('message' => 'Tracker finished')
)
@@ -96,6 +99,9 @@ RSpec.describe BulkImports::FinishBatchedPipelineWorker, feature_category: :impo
it 'fails pipeline tracker and its batches' do
expect_next_instance_of(BulkImports::Logger) do |logger|
+ expect(logger).to receive(:with_tracker).with(pipeline_tracker).and_call_original
+ expect(logger).to receive(:with_entity).with(entity).and_call_original
+
expect(logger).to receive(:error).with(
a_hash_including('message' => 'Batch stale. Failing batches and tracker')
)
diff --git a/spec/workers/bulk_imports/pipeline_worker_spec.rb b/spec/workers/bulk_imports/pipeline_worker_spec.rb
index 09f76169a12..19688596a18 100644
--- a/spec/workers/bulk_imports/pipeline_worker_spec.rb
+++ b/spec/workers/bulk_imports/pipeline_worker_spec.rb
@@ -65,17 +65,9 @@ RSpec.describe BulkImports::PipelineWorker, feature_category: :importers do
it 'runs the given pipeline successfully' do
expect_next_instance_of(BulkImports::Logger) do |logger|
- expect(logger)
- .to receive(:info)
- .with(
- hash_including(
- 'pipeline_class' => 'FakePipeline',
- 'bulk_import_id' => entity.bulk_import_id,
- 'bulk_import_entity_id' => entity.id,
- 'bulk_import_entity_type' => entity.source_type,
- 'source_full_path' => entity.source_full_path
- )
- )
+ expect(logger).to receive(:with_tracker).with(pipeline_tracker).and_call_original
+ expect(logger).to receive(:with_entity).with(pipeline_tracker.entity).and_call_original
+ expect(logger).to receive(:info)
end
allow(worker).to receive(:jid).and_return('jid')
@@ -102,22 +94,9 @@ RSpec.describe BulkImports::PipelineWorker, feature_category: :importers do
job = { 'args' => [pipeline_tracker.id, pipeline_tracker.stage, entity.id] }
expect_next_instance_of(BulkImports::Logger) do |logger|
- expect(logger)
- .to receive(:error)
- .with(
- hash_including(
- 'pipeline_class' => 'FakePipeline',
- 'bulk_import_entity_id' => entity.id,
- 'bulk_import_id' => entity.bulk_import_id,
- 'bulk_import_entity_type' => entity.source_type,
- 'source_full_path' => entity.source_full_path,
- 'class' => 'BulkImports::PipelineWorker',
- 'exception.message' => 'Error!',
- 'message' => 'Pipeline failed',
- 'source_version' => entity.bulk_import.source_version_info.to_s,
- 'importer' => 'gitlab_migration'
- )
- )
+ expect(logger).to receive(:with_tracker).with(pipeline_tracker).and_call_original
+ expect(logger).to receive(:with_entity).with(pipeline_tracker.entity).and_call_original
+ expect(logger).to receive(:error)
end
expect(Gitlab::ErrorTracking)
@@ -125,13 +104,13 @@ RSpec.describe BulkImports::PipelineWorker, feature_category: :importers do
.with(
instance_of(StandardError),
hash_including(
- 'bulk_import_entity_id' => entity.id,
- 'bulk_import_id' => entity.bulk_import.id,
- 'bulk_import_entity_type' => entity.source_type,
- 'source_full_path' => entity.source_full_path,
- 'pipeline_class' => pipeline_tracker.pipeline_name,
- 'importer' => 'gitlab_migration',
- 'source_version' => entity.bulk_import.source_version_info.to_s
+ bulk_import_entity_id: entity.id,
+ bulk_import_id: entity.bulk_import.id,
+ bulk_import_entity_type: entity.source_type,
+ source_full_path: entity.source_full_path,
+ pipeline_class: pipeline_tracker.pipeline_name,
+ importer: 'gitlab_migration',
+ source_version: entity.bulk_import.source_version_info.to_s
)
)
@@ -302,16 +281,7 @@ RSpec.describe BulkImports::PipelineWorker, feature_category: :importers do
expect(logger)
.to receive(:info)
- .with(
- hash_including(
- 'pipeline_class' => 'FakePipeline',
- 'bulk_import_entity_id' => entity.id,
- 'bulk_import_id' => entity.bulk_import_id,
- 'bulk_import_entity_type' => entity.source_type,
- 'source_full_path' => entity.source_full_path,
- 'message' => 'Skipping pipeline due to failed entity'
- )
- )
+ .with(hash_including(message: 'Skipping pipeline due to failed entity'))
end
worker.perform(pipeline_tracker.id, pipeline_tracker.stage, entity.id)
@@ -350,17 +320,9 @@ RSpec.describe BulkImports::PipelineWorker, feature_category: :importers do
end
expect_next_instance_of(BulkImports::Logger) do |logger|
- expect(logger)
- .to receive(:info)
- .with(
- hash_including(
- 'pipeline_class' => 'FakePipeline',
- 'bulk_import_entity_id' => entity.id,
- 'bulk_import_id' => entity.bulk_import_id,
- 'bulk_import_entity_type' => entity.source_type,
- 'source_full_path' => entity.source_full_path
- )
- )
+ expect(logger).to receive(:with_tracker).and_call_original
+ expect(logger).to receive(:with_entity).and_call_original
+ expect(logger).to receive(:info)
end
expect(described_class)
diff --git a/spec/workers/bulk_imports/stuck_import_worker_spec.rb b/spec/workers/bulk_imports/stuck_import_worker_spec.rb
index 4bcc72326c7..09fd1e1b524 100644
--- a/spec/workers/bulk_imports/stuck_import_worker_spec.rb
+++ b/spec/workers/bulk_imports/stuck_import_worker_spec.rb
@@ -48,16 +48,12 @@ RSpec.describe BulkImports::StuckImportWorker, feature_category: :importers do
it 'updates the status of bulk import entities to timeout' do
expect_next_instance_of(BulkImports::Logger) do |logger|
allow(logger).to receive(:error)
- expect(logger).to receive(:error).with(
- message: 'BulkImports::Entity stale',
- bulk_import_entity_id: stale_created_bulk_import_entity.id,
- bulk_import_id: stale_created_bulk_import_entity.bulk_import_id
- )
- expect(logger).to receive(:error).with(
- message: 'BulkImports::Entity stale',
- bulk_import_entity_id: stale_started_bulk_import_entity.id,
- bulk_import_id: stale_started_bulk_import_entity.bulk_import_id
- )
+
+ expect(logger).to receive(:with_entity).with(stale_created_bulk_import_entity).and_call_original
+ expect(logger).to receive(:error).with(message: 'BulkImports::Entity stale')
+
+ expect(logger).to receive(:with_entity).with(stale_started_bulk_import_entity).and_call_original
+ expect(logger).to receive(:error).with(message: 'BulkImports::Entity stale')
end
expect { subject }.to change { stale_created_bulk_import_entity.reload.status_name }.from(:created).to(:timeout)