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:
-rw-r--r--.gitlab/ci/build-images.gitlab-ci.yml3
-rw-r--r--.rubocop_todo/gitlab/strong_memoize_attr.yml1
-rw-r--r--.rubocop_todo/layout/line_length.yml1
-rw-r--r--.rubocop_todo/rails/file_path.yml1
-rw-r--r--.rubocop_todo/rspec/context_wording.yml1
-rw-r--r--.rubocop_todo/rspec/missing_feature_category.yml3
-rw-r--r--.rubocop_todo/style/if_unless_modifier.yml1
-rw-r--r--app/assets/javascripts/diffs/components/diff_file_header.vue7
-rw-r--r--app/assets/javascripts/editor/schema/ci.json3
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js3
-rw-r--r--app/assets/javascripts/merge_request.js5
-rw-r--r--app/assets/javascripts/merge_requests/components/sticky_header.vue2
-rw-r--r--app/assets/javascripts/persistent_user_callouts.js1
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/widget_failed_job_row.vue94
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue6
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue2
-rw-r--r--app/assets/stylesheets/highlight/themes/dark.scss4
-rw-r--r--app/assets/stylesheets/highlight/themes/monokai.scss4
-rw-r--r--app/assets/stylesheets/highlight/themes/none.scss4
-rw-r--r--app/assets/stylesheets/highlight/themes/solarized-dark.scss4
-rw-r--r--app/assets/stylesheets/highlight/themes/solarized-light.scss4
-rw-r--r--app/assets/stylesheets/highlight/white_base.scss4
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb6
-rw-r--r--app/controllers/projects/merge_requests_controller.rb1
-rw-r--r--app/graphql/graphql_triggers.rb2
-rw-r--r--app/models/concerns/spammable.rb10
-rw-r--r--app/models/note.rb2
-rw-r--r--app/models/packages/nuget/metadatum.rb7
-rw-r--r--app/models/users/callout.rb3
-rw-r--r--app/models/users/group_callout.rb3
-rw-r--r--app/services/error_tracking/collect_error_service.rb82
-rw-r--r--app/services/issues/create_service.rb2
-rw-r--r--app/services/issues/update_service.rb6
-rw-r--r--app/services/merge_requests/create_service.rb2
-rw-r--r--app/services/merge_requests/update_service.rb2
-rw-r--r--app/services/packages/nuget/update_package_from_metadata_service.rb14
-rw-r--r--app/services/snippets/create_service.rb7
-rw-r--r--app/services/snippets/update_service.rb7
-rw-r--r--app/views/layouts/group.html.haml1
-rw-r--r--app/views/layouts/project.html.haml1
-rw-r--r--config/feature_flags/development/instance_streaming_audit_events.yml8
-rw-r--r--config/feature_flags/development/realtime_mr_status_change.yml8
-rw-r--r--db/fixtures/development/31_error_tracking.rb44
-rw-r--r--doc/administration/audit_event_streaming.md18
-rw-r--r--doc/administration/geo/disaster_recovery/index.md6
-rw-r--r--doc/administration/redis/replication_and_failover.md29
-rw-r--r--doc/administration/sidekiq/processing_specific_job_classes.md10
-rw-r--r--doc/api/graphql/reference/index.md1
-rw-r--r--doc/api/runners.md2
-rw-r--r--doc/ci/runners/new_creation_workflow.md47
-rw-r--r--doc/ci/runners/register_runner.md6
-rw-r--r--doc/ci/runners/saas/macos_saas_runner.md2
-rw-r--r--doc/ci/yaml/includes.md13
-rw-r--r--doc/development/spam_protection_and_captcha/model_and_services.md44
-rw-r--r--doc/update/index.md6
-rw-r--r--doc/user/admin_area/settings/package_registry_rate_limits.md2
-rw-r--r--doc/user/analytics/analytics_dashboards.md71
-rw-r--r--doc/user/application_security/api_fuzzing/index.md4
-rw-r--r--doc/user/application_security/configuration/index.md4
-rw-r--r--doc/user/application_security/coverage_fuzzing/index.md12
-rw-r--r--doc/user/application_security/dast/proxy-based.md24
-rw-r--r--doc/user/application_security/dependency_scanning/index.md4
-rw-r--r--doc/user/application_security/iac_scanning/index.md4
-rw-r--r--doc/user/application_security/policies/index.md12
-rw-r--r--doc/user/application_security/sast/index.md8
-rw-r--r--doc/user/application_security/secret_detection/index.md8
-rw-r--r--doc/user/application_security/security_dashboard/index.md28
-rw-r--r--doc/user/application_security/vulnerabilities/index.md32
-rw-r--r--doc/user/application_security/vulnerability_report/index.md8
-rw-r--r--doc/user/application_security/vulnerability_report/pipeline.md4
-rw-r--r--doc/user/workspace/index.md6
-rw-r--r--lib/error_tracking/collector/payload_validator.rb13
-rw-r--r--lib/error_tracking/collector/sentry_auth_parser.rb25
-rw-r--r--lib/error_tracking/collector/sentry_request_parser.rb30
-rw-r--r--lib/gitlab/auth/saml/auth_hash.rb2
-rw-r--r--lib/gitlab/auth/saml/config.rb36
-rw-r--r--lib/gitlab/auth/saml/user.rb2
-rw-r--r--lib/gitlab/ci/config/entry/include/rules/rule.rb2
-rw-r--r--lib/gitlab/ci/config/external/rules.rb2
-rw-r--r--lib/gitlab/git/repository.rb10
-rw-r--r--lib/gitlab/gitaly_client/ref_service.rb4
-rw-r--r--lib/gitlab/spamcheck/client.rb2
-rw-r--r--locale/gitlab.pot15
-rw-r--r--spec/controllers/omniauth_callbacks_controller_spec.rb20
-rw-r--r--spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml28
-rw-r--r--spec/frontend/pipelines/components/pipelines_list/failure_widget/widget_failed_job_row_spec.js99
-rw-r--r--spec/frontend/vue_merge_request_widget/components/approvals/approvals_spec.js8
-rw-r--r--spec/frontend/vue_merge_request_widget/mr_widget_options_spec.js16
-rw-r--r--spec/graphql/graphql_triggers_spec.rb14
-rw-r--r--spec/lib/error_tracking/collector/payload_validator_spec.rb45
-rw-r--r--spec/lib/error_tracking/collector/sentry_auth_parser_spec.rb32
-rw-r--r--spec/lib/error_tracking/collector/sentry_request_parser_spec.rb37
-rw-r--r--spec/lib/gitlab/auth/saml/config_spec.rb26
-rw-r--r--spec/lib/gitlab/ci/config/external/rules_spec.rb28
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb4
-rw-r--r--spec/lib/gitlab/gitaly_client/ref_service_spec.rb6
-rw-r--r--spec/lib/gitlab/spamcheck/client_spec.rb4
-rw-r--r--spec/models/concerns/spammable_spec.rb14
-rw-r--r--spec/models/packages/nuget/metadatum_spec.rb1
-rw-r--r--spec/requests/api/issues/post_projects_issues_spec.rb7
-rw-r--r--spec/services/error_tracking/collect_error_service_spec.rb140
-rw-r--r--spec/services/issues/create_service_spec.rb17
-rw-r--r--spec/services/issues/update_service_spec.rb2
-rw-r--r--spec/services/merge_requests/create_service_spec.rb4
-rw-r--r--spec/services/merge_requests/update_service_spec.rb4
-rw-r--r--spec/services/packages/nuget/update_package_from_metadata_service_spec.rb76
-rw-r--r--spec/services/work_items/create_service_spec.rb19
-rw-r--r--spec/support/helpers/login_helpers.rb17
-rw-r--r--spec/support/rspec_order_todo.yml4
-rw-r--r--spec/support/shared_examples/models/wiki_shared_examples.rb5
111 files changed, 737 insertions, 876 deletions
diff --git a/.gitlab/ci/build-images.gitlab-ci.yml b/.gitlab/ci/build-images.gitlab-ci.yml
index 33cc97cd1d5..1361f1fe412 100644
--- a/.gitlab/ci/build-images.gitlab-ci.yml
+++ b/.gitlab/ci/build-images.gitlab-ci.yml
@@ -40,6 +40,9 @@ build-gdk-image:
script:
- run_timed_command "scripts/build_gdk_image"
+# NOTE: release-tools verifies the presence on this job for a commit that is
+# candidate to an auto-deploy package. This job name can't be changed without
+# changing the code in release-tools.
build-assets-image:
extends:
- .base-image-build
diff --git a/.rubocop_todo/gitlab/strong_memoize_attr.yml b/.rubocop_todo/gitlab/strong_memoize_attr.yml
index 3472fbd9c9d..a6c273cc85b 100644
--- a/.rubocop_todo/gitlab/strong_memoize_attr.yml
+++ b/.rubocop_todo/gitlab/strong_memoize_attr.yml
@@ -182,7 +182,6 @@ Gitlab/StrongMemoizeAttr:
- 'app/services/container_expiration_policies/update_service.rb'
- 'app/services/dependency_proxy/image_ttl_group_policies/update_service.rb'
- 'app/services/discussions/resolve_service.rb'
- - 'app/services/error_tracking/collect_error_service.rb'
- 'app/services/error_tracking/issue_details_service.rb'
- 'app/services/feature_flags/base_service.rb'
- 'app/services/git/base_hooks_service.rb'
diff --git a/.rubocop_todo/layout/line_length.yml b/.rubocop_todo/layout/line_length.yml
index 5dcfc9a16a0..53e122ec700 100644
--- a/.rubocop_todo/layout/line_length.yml
+++ b/.rubocop_todo/layout/line_length.yml
@@ -2635,7 +2635,6 @@ Layout/LineLength:
- 'lib/bulk_imports/projects/pipelines/repository_pipeline.rb'
- 'lib/container_registry/base_client.rb'
- 'lib/declarative_enum.rb'
- - 'lib/error_tracking/collector/payload_validator.rb'
- 'lib/feature.rb'
- 'lib/feature/definition.rb'
- 'lib/file_size_validator.rb'
diff --git a/.rubocop_todo/rails/file_path.yml b/.rubocop_todo/rails/file_path.yml
index 0214b471e59..49182a51ea7 100644
--- a/.rubocop_todo/rails/file_path.yml
+++ b/.rubocop_todo/rails/file_path.yml
@@ -33,7 +33,6 @@ Rails/FilePath:
- 'ee/spec/services/ee/merge_requests/refresh_service_spec.rb'
- 'ee/spec/validators/json_schema_validator_spec.rb'
- 'lib/api/api.rb'
- - 'lib/error_tracking/collector/payload_validator.rb'
- 'lib/feature/definition.rb'
- 'lib/gitlab/audit/type/definition.rb'
- 'lib/gitlab/ci/parsers/sbom/validators/cyclonedx_schema_validator.rb'
diff --git a/.rubocop_todo/rspec/context_wording.yml b/.rubocop_todo/rspec/context_wording.yml
index 065174c243c..d32abc64f94 100644
--- a/.rubocop_todo/rspec/context_wording.yml
+++ b/.rubocop_todo/rspec/context_wording.yml
@@ -2671,7 +2671,6 @@ RSpec/ContextWording:
- 'spec/services/draft_notes/publish_service_spec.rb'
- 'spec/services/environments/schedule_to_delete_review_apps_service_spec.rb'
- 'spec/services/environments/stop_service_spec.rb'
- - 'spec/services/error_tracking/collect_error_service_spec.rb'
- 'spec/services/error_tracking/list_issues_service_spec.rb'
- 'spec/services/error_tracking/list_projects_service_spec.rb'
- 'spec/services/events/destroy_service_spec.rb'
diff --git a/.rubocop_todo/rspec/missing_feature_category.yml b/.rubocop_todo/rspec/missing_feature_category.yml
index 29fce956444..0835191b8f4 100644
--- a/.rubocop_todo/rspec/missing_feature_category.yml
+++ b/.rubocop_todo/rspec/missing_feature_category.yml
@@ -2842,9 +2842,6 @@ RSpec/MissingFeatureCategory:
- 'spec/lib/csv_builder_spec.rb'
- 'spec/lib/csv_builders/stream_spec.rb'
- 'spec/lib/declarative_enum_spec.rb'
- - 'spec/lib/error_tracking/collector/payload_validator_spec.rb'
- - 'spec/lib/error_tracking/collector/sentry_auth_parser_spec.rb'
- - 'spec/lib/error_tracking/collector/sentry_request_parser_spec.rb'
- 'spec/lib/error_tracking/sentry_client/api_urls_spec.rb'
- 'spec/lib/error_tracking/sentry_client/event_spec.rb'
- 'spec/lib/error_tracking/sentry_client/issue_link_spec.rb'
diff --git a/.rubocop_todo/style/if_unless_modifier.yml b/.rubocop_todo/style/if_unless_modifier.yml
index 9fdfb6c960d..9b079a4e3df 100644
--- a/.rubocop_todo/style/if_unless_modifier.yml
+++ b/.rubocop_todo/style/if_unless_modifier.yml
@@ -249,7 +249,6 @@ Style/IfUnlessModifier:
- 'app/services/emails/create_service.rb'
- 'app/services/environments/canary_ingress/update_service.rb'
- 'app/services/environments/reset_auto_stop_service.rb'
- - 'app/services/error_tracking/collect_error_service.rb'
- 'app/services/git/process_ref_changes_service.rb'
- 'app/services/google_cloud/generate_pipeline_service.rb'
- 'app/services/groups/create_service.rb'
diff --git a/app/assets/javascripts/diffs/components/diff_file_header.vue b/app/assets/javascripts/diffs/components/diff_file_header.vue
index 07b60330f43..36252c2cf87 100644
--- a/app/assets/javascripts/diffs/components/diff_file_header.vue
+++ b/app/assets/javascripts/diffs/components/diff_file_header.vue
@@ -462,7 +462,12 @@ export default {
v-if="showGenerateTestFileButton"
@click="setGenerateTestFilePath(diffFile.new_path)"
>
- {{ __('Suggest test cases') }}
+ <span
+ class="gl-display-flex gl-justify-content-space-between gl-align-items-center gl-mr-n3!"
+ >
+ {{ __('Suggest test cases') }}
+ <gl-icon name="tanuki-ai" class="gl-text-purple-600" />
+ </span>
</gl-dropdown-item>
<gl-dropdown-item
v-if="diffFile.replaced_view_path"
diff --git a/app/assets/javascripts/editor/schema/ci.json b/app/assets/javascripts/editor/schema/ci.json
index 8e307bc1f19..3a1188d7aab 100644
--- a/app/assets/javascripts/editor/schema/ci.json
+++ b/app/assets/javascripts/editor/schema/ci.json
@@ -830,7 +830,8 @@
{
"type": "string",
"enum": [
- "never"
+ "never",
+ "always"
]
},
{
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js
index 0fb034e8b3e..7795dac18bc 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js
+++ b/app/assets/javascripts/lib/utils/common_utils.js
@@ -82,6 +82,7 @@ export const handleLocationHash = () => {
const fixedTabs = document.querySelector('.js-tabs-affix');
const fixedDiffStats = document.querySelector('.js-diff-files-changed');
const fixedNav = document.querySelector('.navbar-gitlab');
+ const fixedTopBar = document.querySelector('.top-bar-fixed');
const performanceBar = document.querySelector('#js-peek');
const topPadding = 8;
const diffFileHeader = document.querySelector('.js-file-title');
@@ -93,6 +94,7 @@ export const handleLocationHash = () => {
adjustment -= getElementOffsetHeight(fixedNav);
adjustment -= getElementOffsetHeight(fixedTabs);
adjustment -= getElementOffsetHeight(fixedDiffStats);
+ adjustment -= getElementOffsetHeight(fixedTopBar);
adjustment -= getElementOffsetHeight(performanceBar);
adjustment -= getElementOffsetHeight(diffFileHeader);
adjustment -= getElementOffsetHeight(versionMenusContainer);
@@ -153,6 +155,7 @@ export const contentTop = () => {
const heightCalculators = [
() => getOuterHeight('#js-peek'),
() => getOuterHeight('.navbar-gitlab'),
+ () => getOuterHeight('.top-bar-fixed'),
({ desktop }) => {
const mrStickyHeader = document.querySelector('.merge-request-sticky-header');
if (mrStickyHeader) {
diff --git a/app/assets/javascripts/merge_request.js b/app/assets/javascripts/merge_request.js
index 1e02703cbe7..c837583dd45 100644
--- a/app/assets/javascripts/merge_request.js
+++ b/app/assets/javascripts/merge_request.js
@@ -5,7 +5,6 @@ import { createAlert } from '~/alert';
import { TYPE_MERGE_REQUEST } from '~/issues/constants';
import toast from '~/vue_shared/plugins/global_toast';
import { __ } from '~/locale';
-import eventHub from '~/vue_merge_request_widget/event_hub';
import { loadingIconForLegacyJS } from '~/loading_icon_for_legacy_js';
import axios from './lib/utils/axios_utils';
import { addDelimiter } from './lib/utils/text_utility';
@@ -146,10 +145,6 @@ MergeRequest.decreaseCounter = function (by = 1) {
};
MergeRequest.toggleDraftStatus = function (title, isReady) {
- if (!window.gon?.features?.realtimeMrStatusChange) {
- eventHub.$emit('MRWidgetUpdateRequested');
- }
-
if (isReady) {
toast(__('Marked as ready. Merging is now allowed.'));
} else {
diff --git a/app/assets/javascripts/merge_requests/components/sticky_header.vue b/app/assets/javascripts/merge_requests/components/sticky_header.vue
index a66490b5f75..c6e8a9ea582 100644
--- a/app/assets/javascripts/merge_requests/components/sticky_header.vue
+++ b/app/assets/javascripts/merge_requests/components/sticky_header.vue
@@ -25,7 +25,7 @@ export default {
};
},
skip() {
- return !this.issuableId || !this.glFeatures.realtimeMrStatusChange;
+ return !this.issuableId;
},
result({ data: { mergeRequestMergeStatusUpdated } }) {
if (mergeRequestMergeStatusUpdated) {
diff --git a/app/assets/javascripts/persistent_user_callouts.js b/app/assets/javascripts/persistent_user_callouts.js
index 9940575edc3..2c93b3b636a 100644
--- a/app/assets/javascripts/persistent_user_callouts.js
+++ b/app/assets/javascripts/persistent_user_callouts.js
@@ -26,6 +26,7 @@ const PERSISTENT_USER_CALLOUTS = [
'.js-branch-rules-info-callout',
'.js-new-navigation-callout',
'.js-code-suggestions-third-party-callout',
+ '.js-namespace-over-storage-users-combined-alert',
];
const initCallouts = () => {
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/widget_failed_job_row.vue b/app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/widget_failed_job_row.vue
index d48e6dc289b..e40e30f2b8d 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/widget_failed_job_row.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/widget_failed_job_row.vue
@@ -1,15 +1,107 @@
<script>
+import { GlCollapse, GlIcon, GlLink } from '@gitlab/ui';
+import { s__, sprintf } from '~/locale';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import CiIcon from '~/vue_shared/components/ci_icon.vue';
+import SafeHtml from '~/vue_shared/directives/safe_html';
+
export default {
+ components: {
+ CiIcon,
+ GlCollapse,
+ GlIcon,
+ GlLink,
+ },
+ directives: {
+ SafeHtml,
+ },
props: {
job: {
type: Object,
required: true,
},
},
+ data() {
+ return {
+ isJobLogVisible: false,
+ isHovered: false,
+ };
+ },
+ computed: {
+ activeClass() {
+ return this.isHovered ? 'gl-bg-gray-50' : '';
+ },
+ isVisibleId() {
+ return `log-${this.isJobLogVisible ? 'is-visible' : 'is-hidden'}`;
+ },
+ jobChevronName() {
+ return this.isJobLogVisible ? 'chevron-down' : 'chevron-right';
+ },
+ jobTrace() {
+ return this.job?.trace?.htmlSummary || this.$options.i18n.noTraceText;
+ },
+ parsedJobId() {
+ return getIdFromGraphQLId(this.job.id);
+ },
+ tooltipText() {
+ return sprintf(this.$options.i18n.jobActionTooltipText, { jobName: this.job.name });
+ },
+ },
+ methods: {
+ setActiveRow() {
+ this.isHovered = true;
+ },
+ resetActiveRow() {
+ this.isHovered = false;
+ },
+ toggleJobLog(e) {
+ // Do not toggle the log visibility when clicking on a link
+ if (e.target.tagName === 'A') {
+ return;
+ }
+
+ this.isJobLogVisible = !this.isJobLogVisible;
+ },
+ },
+ i18n: {
+ jobActionTooltipText: s__('Pipelines|Retry %{jobName} Job'),
+ noTraceText: s__('Job|No job log'),
+ },
};
</script>
<template>
<div class="container-fluid gl-grid-tpl-rows-auto">
- {{ job.name }}
+ <div
+ class="row gl-py-4 gl-cursor-pointer gl-display-flex gl-align-items-center"
+ :class="activeClass"
+ :aria-pressed="isJobLogVisible"
+ role="button"
+ tabindex="0"
+ data-testid="widget-row"
+ @click="toggleJobLog"
+ @keyup.enter="toggleJobLog"
+ @keyup.space="toggleJobLog"
+ @mouseover="setActiveRow"
+ @mouseout="resetActiveRow"
+ >
+ <div class="col-6 gl-text-gray-900 gl-font-weight-bold gl-text-left">
+ <gl-icon :name="jobChevronName" class="gl-fill-blue-500" />
+ <ci-icon :status="job.detailedStatus" />
+ {{ job.name }}
+ </div>
+ <div class="col-2 gl-text-left">{{ job.stage.name }}</div>
+ <div class="col-2 gl-text-left">
+ <gl-link :href="job.webPath">#{{ parsedJobId }}</gl-link>
+ </div>
+ </div>
+ <div class="row">
+ <gl-collapse :visible="isJobLogVisible" class="gl-w-full">
+ <pre
+ v-safe-html="jobTrace"
+ class="gl-bg-gray-900 gl-text-white"
+ :data-testid="isVisibleId"
+ ></pre>
+ </gl-collapse>
+ </div>
</div>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue b/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue
index ad78de8728f..95fa01c23f1 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue
@@ -7,7 +7,6 @@ import { HTTP_STATUS_UNAUTHORIZED } from '~/lib/utils/http_status';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { s__, __, sprintf } from '~/locale';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
-import eventHub from '../../event_hub';
import approvalsMixin from '../../mixins/approvals';
import StateContainer from '../state_container.vue';
import { INVALID_RULES_DOCS_PATH } from '../../constants';
@@ -215,11 +214,6 @@ export default {
this.clearError();
return serviceFn()
.then(() => {
- if (!window.gon?.features?.realtimeMrStatusChange) {
- eventHub.$emit('MRWidgetUpdateRequested');
- eventHub.$emit('ApprovalUpdated');
- }
-
// TODO: Remove this line when we move to Apollo subscriptions
this.$apollo.queries.approvals.refetch();
})
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 fad0830388e..52cdafd4717 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
@@ -97,7 +97,7 @@ export default {
return readyToMergeSubscription;
},
skip() {
- return !this.mr?.id || this.loading || !window.gon?.features?.realtimeMrStatusChange;
+ return !this.mr?.id || this.loading;
},
variables() {
return {
diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
index 9dc5bf77da7..af9e303594a 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
@@ -133,7 +133,7 @@ export default {
return getStateSubscription;
},
skip() {
- return !this.mr?.id || this.loading || !window.gon?.features?.realtimeMrStatusChange;
+ return !this.mr?.id || this.loading;
},
variables() {
return {
diff --git a/app/assets/stylesheets/highlight/themes/dark.scss b/app/assets/stylesheets/highlight/themes/dark.scss
index 02469cf5165..9ad7c1b796c 100644
--- a/app/assets/stylesheets/highlight/themes/dark.scss
+++ b/app/assets/stylesheets/highlight/themes/dark.scss
@@ -134,10 +134,6 @@ $dark-il: #de935f;
// Line numbers
- .file-line-num {
- @include line-link($white, 'link');
- }
-
.file-line-blame {
@include line-link($white, 'git');
}
diff --git a/app/assets/stylesheets/highlight/themes/monokai.scss b/app/assets/stylesheets/highlight/themes/monokai.scss
index 30d04b4002e..b1d89d3c253 100644
--- a/app/assets/stylesheets/highlight/themes/monokai.scss
+++ b/app/assets/stylesheets/highlight/themes/monokai.scss
@@ -125,10 +125,6 @@ $monokai-gh: #75715e;
@include hljs-override('params', $monokai-nb);
// Line numbers
- .file-line-num {
- @include line-link($white, 'link');
- }
-
.file-line-blame {
@include line-link($white, 'git');
}
diff --git a/app/assets/stylesheets/highlight/themes/none.scss b/app/assets/stylesheets/highlight/themes/none.scss
index 8339d7eff80..4762aae1d12 100644
--- a/app/assets/stylesheets/highlight/themes/none.scss
+++ b/app/assets/stylesheets/highlight/themes/none.scss
@@ -24,10 +24,6 @@
}
// Line numbers
- .file-line-num {
- @include line-link($black, 'link');
- }
-
.file-line-blame {
@include line-link($black, 'git');
}
diff --git a/app/assets/stylesheets/highlight/themes/solarized-dark.scss b/app/assets/stylesheets/highlight/themes/solarized-dark.scss
index 075510e6e5f..7958959bfc3 100644
--- a/app/assets/stylesheets/highlight/themes/solarized-dark.scss
+++ b/app/assets/stylesheets/highlight/themes/solarized-dark.scss
@@ -128,10 +128,6 @@ $solarized-dark-il: #2aa198;
@include hljs-override('params', $solarized-dark-nb);
// Line numbers
- .file-line-num {
- @include line-link($white, 'link');
- }
-
.file-line-blame {
@include line-link($white, 'git');
}
diff --git a/app/assets/stylesheets/highlight/themes/solarized-light.scss b/app/assets/stylesheets/highlight/themes/solarized-light.scss
index 4e244ed7420..f156077c64d 100644
--- a/app/assets/stylesheets/highlight/themes/solarized-light.scss
+++ b/app/assets/stylesheets/highlight/themes/solarized-light.scss
@@ -118,10 +118,6 @@ $solarized-light-il: #2aa198;
@include hljs-override('params', $solarized-light-nb);
// Line numbers
- .file-line-num {
- @include line-link($black, 'link');
- }
-
.file-line-blame {
@include line-link($black, 'git');
}
diff --git a/app/assets/stylesheets/highlight/white_base.scss b/app/assets/stylesheets/highlight/white_base.scss
index 969a6665634..14524e163b2 100644
--- a/app/assets/stylesheets/highlight/white_base.scss
+++ b/app/assets/stylesheets/highlight/white_base.scss
@@ -94,10 +94,6 @@ $white-gc-bg: #eaf2f5;
}
// Line numbers
-.file-line-num {
- @include line-link($black, 'link');
-}
-
.file-line-blame {
@include line-link($black, 'git');
}
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index f858a0e5cf7..eda72400f17 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -15,7 +15,11 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
feature_category :system_access
def handle_omniauth
- omniauth_flow(Gitlab::Auth::OAuth)
+ if ::AuthHelper.saml_providers.include?(oauth['provider'].to_sym)
+ saml
+ else
+ omniauth_flow(Gitlab::Auth::OAuth)
+ end
end
AuthHelper.providers_for_base_controller.each do |provider|
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 77ff69c669d..60f619a8d20 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -44,7 +44,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:deprecate_vulnerabilities_feedback, @project)
push_frontend_feature_flag(:moved_mr_sidebar, project)
push_frontend_feature_flag(:mr_experience_survey, project)
- push_frontend_feature_flag(:realtime_mr_status_change, project)
push_frontend_feature_flag(:saved_replies, current_user)
push_frontend_feature_flag(:code_quality_inline_drawer, project)
push_frontend_feature_flag(:auto_merge_labels_mr_widget, project)
diff --git a/app/graphql/graphql_triggers.rb b/app/graphql/graphql_triggers.rb
index 7abd1258958..527eb50b644 100644
--- a/app/graphql/graphql_triggers.rb
+++ b/app/graphql/graphql_triggers.rb
@@ -48,8 +48,6 @@ module GraphqlTriggers
end
def self.merge_request_merge_status_updated(merge_request)
- return unless Feature.enabled?(:realtime_mr_status_change, merge_request.project)
-
GitlabSchema.subscriptions.trigger(
:merge_request_merge_status_updated, { issuable_id: merge_request.to_gid }, merge_request
)
diff --git a/app/models/concerns/spammable.rb b/app/models/concerns/spammable.rb
index 36a2242b5b5..8bed8b1211a 100644
--- a/app/models/concerns/spammable.rb
+++ b/app/models/concerns/spammable.rb
@@ -105,8 +105,12 @@ module Spammable
_('issue')
when MergeRequest
_('merge request')
+ when Note
+ _('comment')
when Snippet
_('snippet')
+ when Note
+ _('comment')
else
self.class.model_name.human.downcase
end
@@ -145,9 +149,9 @@ module Spammable
(changed & self.class.spammable_attrs.to_h.keys).any?
end
- def check_for_spam(action:, user:)
- strong_memoize_with(:check_for_spam, action, user) do
- Spam::SpamActionService.new(spammable: self, user: user, action: action).execute
+ def check_for_spam(user:, action:, extra_features: {})
+ strong_memoize_with(:check_for_spam, user, action, extra_features) do
+ Spam::SpamActionService.new(spammable: self, user: user, action: action, extra_features: extra_features).execute
end
end
diff --git a/app/models/note.rb b/app/models/note.rb
index 5f48ec0b56c..09ff7ad3979 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -785,7 +785,7 @@ class Note < ApplicationRecord
# Override method defined in Spammable
# Wildcard argument because user: argument is not used
def check_for_spam?(*)
- return false if system? || !note_changed? || confidential?
+ return false if system? || !spammable_attribute_changed? || confidential?
return false if noteable.try(:confidential?) == true || noteable.try(:public?) == false
return false if noteable.try(:group)&.public? == false || project&.public? == false
diff --git a/app/models/packages/nuget/metadatum.rb b/app/models/packages/nuget/metadatum.rb
index 08276f87568..fae7728cccb 100644
--- a/app/models/packages/nuget/metadatum.rb
+++ b/app/models/packages/nuget/metadatum.rb
@@ -3,13 +3,14 @@
class Packages::Nuget::Metadatum < ApplicationRecord
MAX_AUTHORS_LENGTH = 255
MAX_DESCRIPTION_LENGTH = 4000
+ MAX_URL_LENGTH = 255
belongs_to :package, -> { where(package_type: :nuget) }, inverse_of: :nuget_metadatum
validates :package, presence: true
- validates :license_url, public_url: { allow_blank: true }
- validates :project_url, public_url: { allow_blank: true }
- validates :icon_url, public_url: { allow_blank: true }
+ validates :license_url, public_url: { allow_blank: true }, length: { maximum: MAX_URL_LENGTH }
+ validates :project_url, public_url: { allow_blank: true }, length: { maximum: MAX_URL_LENGTH }
+ validates :icon_url, public_url: { allow_blank: true }, length: { maximum: MAX_URL_LENGTH }
validates :authors, presence: true, length: { maximum: MAX_AUTHORS_LENGTH }
validates :description, presence: true, length: { maximum: MAX_DESCRIPTION_LENGTH }
diff --git a/app/models/users/callout.rb b/app/models/users/callout.rb
index 34a116c36be..38e518b6d3e 100644
--- a/app/models/users/callout.rb
+++ b/app/models/users/callout.rb
@@ -71,7 +71,8 @@ module Users
repository_storage_limit_banner_alert_threshold: 69, # EE-only
repository_storage_limit_banner_error_threshold: 70, # EE-only
new_navigation_callout: 71,
- code_suggestions_third_party_callout: 72 # EE-only
+ code_suggestions_third_party_callout: 72, # EE-only
+ namespace_over_storage_users_combined_alert: 73 # EE-only
}
validates :feature_name,
diff --git a/app/models/users/group_callout.rb b/app/models/users/group_callout.rb
index 03384b594d6..c5946197b6f 100644
--- a/app/models/users/group_callout.rb
+++ b/app/models/users/group_callout.rb
@@ -29,7 +29,8 @@ module Users
repository_storage_limit_banner_info_threshold: 19, # EE-only
repository_storage_limit_banner_warning_threshold: 20, # EE-only
repository_storage_limit_banner_alert_threshold: 21, # EE-only
- repository_storage_limit_banner_error_threshold: 22 # EE-only
+ repository_storage_limit_banner_error_threshold: 22, # EE-only
+ namespace_over_storage_users_combined_alert: 23 # EE-only
}
validates :group, presence: true
diff --git a/app/services/error_tracking/collect_error_service.rb b/app/services/error_tracking/collect_error_service.rb
deleted file mode 100644
index 8cb3793ba97..00000000000
--- a/app/services/error_tracking/collect_error_service.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-# frozen_string_literal: true
-
-module ErrorTracking
- class CollectErrorService < ::BaseService
- include Gitlab::Utils::StrongMemoize
-
- def execute
- error_repository.report_error(
- name: exception['type'],
- description: exception['value'],
- actor: actor,
- platform: event['platform'],
- occurred_at: timestamp,
- environment: event['environment'],
- level: event['level'],
- payload: event
- )
- end
-
- private
-
- def error_repository
- Gitlab::ErrorTracking::ErrorRepository.build(project)
- end
-
- def event
- @event ||= format_event(params[:event])
- end
-
- def format_event(event)
- # Some SDK send exception payload as Array. For exmple Go lang SDK.
- # We need to convert it to hash format we expect.
- if event['exception'].is_a?(Array)
- exception = event['exception']
- event['exception'] = { 'values' => exception }
- end
-
- event
- end
-
- def exception
- strong_memoize(:exception) do
- # Find the first exception that has a stacktrace since the first
- # exception may not provide adequate context (e.g. in the Go SDK).
- entries = event['exception']['values']
- entries.find { |x| x.key?('stacktrace') } || entries.first
- end
- end
-
- def stacktrace_frames
- strong_memoize(:stacktrace_frames) do
- exception.dig('stacktrace', 'frames')
- end
- end
-
- def actor
- return event['transaction'] if event['transaction'].present?
-
- # Some SDKs do not have a transaction attribute.
- # So we build it by combining function name and module name from
- # the last item in stacktrace.
- return unless stacktrace_frames.present?
-
- last_line = stacktrace_frames.last
-
- "#{last_line['function']}(#{last_line['module']})"
- end
-
- def timestamp
- return @timestamp if @timestamp
-
- @timestamp = (event['timestamp'] || Time.zone.now)
-
- # Some SDK send timestamp in numeric format like '1630945472.13'.
- if @timestamp.to_s =~ /\A\d+(\.\d+)?\z/
- @timestamp = Time.zone.at(@timestamp.to_f)
- end
-
- @timestamp
- end
- end
-end
diff --git a/app/services/issues/create_service.rb b/app/services/issues/create_service.rb
index 4731a5dd39c..17b6866773e 100644
--- a/app/services/issues/create_service.rb
+++ b/app/services/issues/create_service.rb
@@ -47,7 +47,7 @@ module Issues
end
def before_create(issue)
- Spam::SpamActionService.new(spammable: issue, user: current_user, action: :create).execute if perform_spam_check
+ issue.check_for_spam(user: current_user, action: :create) if perform_spam_check
# current_user (defined in BaseService) is not available within run_after_commit block
user = current_user
diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb
index a17ca62ccab..7ad56d5a755 100644
--- a/app/services/issues/update_service.rb
+++ b/app/services/issues/update_service.rb
@@ -28,11 +28,7 @@ module Issues
return if skip_spam_check || !perform_spam_check
- Spam::SpamActionService.new(
- spammable: issue,
- user: current_user,
- action: :update
- ).execute
+ issue.check_for_spam(user: current_user, action: :update)
end
def change_work_item_type(issue)
diff --git a/app/services/merge_requests/create_service.rb b/app/services/merge_requests/create_service.rb
index a042e570132..9135a80c883 100644
--- a/app/services/merge_requests/create_service.rb
+++ b/app/services/merge_requests/create_service.rb
@@ -41,7 +41,7 @@ module MergeRequests
# timeout, we do this before we attempt to save the merge request.
merge_request.skip_ensure_merge_request_diff = true
- Spam::SpamActionService.new(spammable: merge_request, user: current_user, action: :create).execute
+ merge_request.check_for_spam(user: current_user, action: :create)
end
def set_projects!
diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb
index 123420d9af3..598dbaf93a9 100644
--- a/app/services/merge_requests/update_service.rb
+++ b/app/services/merge_requests/update_service.rb
@@ -211,7 +211,7 @@ module MergeRequests
override :before_update
def before_update(merge_request, skip_spam_check: false)
- Spam::SpamActionService.new(spammable: merge_request, user: current_user, action: :update).execute unless skip_spam_check
+ merge_request.check_for_spam(user: current_user, action: :update) unless skip_spam_check
end
override :handle_quick_actions
diff --git a/app/services/packages/nuget/update_package_from_metadata_service.rb b/app/services/packages/nuget/update_package_from_metadata_service.rb
index 7153a9035b8..8e2679db31b 100644
--- a/app/services/packages/nuget/update_package_from_metadata_service.rb
+++ b/app/services/packages/nuget/update_package_from_metadata_service.rb
@@ -9,6 +9,9 @@ module Packages
# used by ExclusiveLeaseGuard
DEFAULT_LEASE_TIMEOUT = 1.hour.to_i.freeze
SYMBOL_PACKAGE_IDENTIFIER = 'SymbolsPackage'
+ INVALID_METADATA_ERROR_MESSAGE = 'package name, version, authors and/or description not found in metadata'
+ INVALID_METADATA_ERROR_SYMBOL_MESSAGE = 'package name, version and/or description not found in metadata'
+ MISSING_MATCHING_PACKAGE_ERROR_MESSAGE = 'symbol package is invalid, matching package does not exist'
InvalidMetadataError = Class.new(StandardError)
@@ -17,7 +20,10 @@ module Packages
end
def execute
- raise InvalidMetadataError, 'package name, version, authors and/or description not found in metadata' unless valid_metadata?
+ unless valid_metadata?
+ error_message = symbol_package? ? INVALID_METADATA_ERROR_SYMBOL_MESSAGE : INVALID_METADATA_ERROR_MESSAGE
+ raise InvalidMetadataError, error_message
+ end
try_obtain_lease do
@package_file.transaction do
@@ -39,7 +45,7 @@ module Packages
target_package = existing_package
else
if symbol_package?
- raise InvalidMetadataError, 'symbol package is invalid, matching package does not exist'
+ raise InvalidMetadataError, MISSING_MATCHING_PACKAGE_ERROR_MESSAGE
end
update_linked_package
@@ -67,7 +73,9 @@ module Packages
end
def valid_metadata?
- [package_name, package_version, package_authors, package_description].all?(&:present?)
+ fields = [package_name, package_version, package_description]
+ fields << package_authors unless symbol_package?
+ fields.all?(&:present?)
end
def link_to_existing_package
diff --git a/app/services/snippets/create_service.rb b/app/services/snippets/create_service.rb
index 111c6211dab..569b8b76518 100644
--- a/app/services/snippets/create_service.rb
+++ b/app/services/snippets/create_service.rb
@@ -19,12 +19,7 @@ module Snippets
@snippet.author = current_user
if perform_spam_check
- Spam::SpamActionService.new(
- spammable: @snippet,
- user: current_user,
- action: :create,
- extra_features: { files: file_paths_to_commit }
- ).execute
+ @snippet.check_for_spam(user: current_user, action: :create, extra_features: { files: file_paths_to_commit })
end
if save_and_commit
diff --git a/app/services/snippets/update_service.rb b/app/services/snippets/update_service.rb
index 684ede1f2eb..662e31a93aa 100644
--- a/app/services/snippets/update_service.rb
+++ b/app/services/snippets/update_service.rb
@@ -23,12 +23,7 @@ module Snippets
files = snippet.all_files.map { |f| { path: f } } + file_paths_to_commit
if perform_spam_check
- Spam::SpamActionService.new(
- spammable: snippet,
- user: current_user,
- action: :update,
- extra_features: { files: files }
- ).execute
+ snippet.check_for_spam(user: current_user, action: :update, extra_features: { files: files })
end
if save_and_commit(snippet)
diff --git a/app/views/layouts/group.html.haml b/app/views/layouts/group.html.haml
index 36e773ea1ae..c75b02aa6a6 100644
--- a/app/views/layouts/group.html.haml
+++ b/app/views/layouts/group.html.haml
@@ -9,6 +9,7 @@
- content_for :flash_message do
= dispensable_render_if_exists "groups/storage_enforcement_alert", context: @group
= dispensable_render_if_exists "shared/namespace_storage_limit_alert", context: @group
+ = dispensable_render_if_exists "shared/namespace_combined_storage_users_alert", context: @group
- content_for :page_specific_javascripts do
- if current_user
diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml
index 9a7995090e3..4ecae875056 100644
--- a/app/views/layouts/project.html.haml
+++ b/app/views/layouts/project.html.haml
@@ -10,6 +10,7 @@
- content_for :flash_message do
= dispensable_render_if_exists "projects/storage_enforcement_alert", context: @project
= dispensable_render_if_exists "shared/namespace_storage_limit_alert", context: @project
+ = dispensable_render_if_exists "shared/namespace_combined_storage_users_alert", context: @project
- content_for :project_javascripts do
- project = @target_project || @project
diff --git a/config/feature_flags/development/instance_streaming_audit_events.yml b/config/feature_flags/development/instance_streaming_audit_events.yml
deleted file mode 100644
index 964d7ac7cbd..00000000000
--- a/config/feature_flags/development/instance_streaming_audit_events.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: instance_streaming_audit_events
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119008
-rollout_issue_url:
-milestone: '16.0'
-type: development
-group: group::compliance
-default_enabled: false
diff --git a/config/feature_flags/development/realtime_mr_status_change.yml b/config/feature_flags/development/realtime_mr_status_change.yml
deleted file mode 100644
index a922ba7d12a..00000000000
--- a/config/feature_flags/development/realtime_mr_status_change.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: realtime_mr_status_change
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/103011
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/385077
-milestone: '15.7'
-type: development
-group: group::code review
-default_enabled: true
diff --git a/db/fixtures/development/31_error_tracking.rb b/db/fixtures/development/31_error_tracking.rb
deleted file mode 100644
index d4d59f4046a..00000000000
--- a/db/fixtures/development/31_error_tracking.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-class Gitlab::Seeder::ErrorTrackingSeeder
- attr_reader :project
-
- def initialize(project)
- @project = project
- end
-
- def seed
- parsed_event = Gitlab::Json.parse(read_fixture_file('parsed_event.json'))
-
- ErrorTracking::CollectErrorService
- .new(project, nil, event: parsed_event)
- .execute
- end
-
- private
-
- def read_fixture_file(file)
- File.read(fixture_path(file))
- end
-
- def fixture_path(file)
- Rails.root.join('spec', 'fixtures', 'error_tracking', file)
- end
-end
-
-
-Gitlab::Seeder.quiet do
- admin_user = User.admins.first
-
- Project.not_mass_generated.visible_to_user(admin_user).sample(1).each do |project|
- puts "\nActivating integrated error tracking for the '#{project.full_path}' project"
-
- puts '- enabling in settings'
- project.error_tracking_setting || project.create_error_tracking_setting
- project.error_tracking_setting.update!(enabled: true, integrated: true)
-
- puts '- seeding an error'
- seeder = Gitlab::Seeder::ErrorTrackingSeeder.new(project)
- seeder.seed
- end
-end
diff --git a/doc/administration/audit_event_streaming.md b/doc/administration/audit_event_streaming.md
index af97e902645..b8d5324c0b4 100644
--- a/doc/administration/audit_event_streaming.md
+++ b/doc/administration/audit_event_streaming.md
@@ -20,7 +20,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - User-specified verification token API support [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/360813) in GitLab 15.4.
> - Event type filters API [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/344845) in GitLab 15.7.
> - APIs for instance level streaming destinations [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/335175) in GitLab 16.0 [with a flag](../administration/feature_flags.md) named `ff_external_audit_events`. Disabled by default.
-> - UI for instance level streaming destinations [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/398107) in GitLab 16.1 [with a flag](../administration/feature_flags.md) named `instance_streaming_audit_events`. Disabled by default.
+> - UI for instance level streaming destinations [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/398107) in GitLab 16.1 [with a flag](../administration/feature_flags.md) named `ff_external_audit_events`. Disabled by default.
Users can set a streaming destination for a top-level group or instance to receive all audit events about the group, subgroups, and
projects as structured JSON.
@@ -58,11 +58,11 @@ Users with the Owner role for a group can add streaming destinations for it:
#### Instance streaming destinations
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/398107) in GitLab 16.1 [with a flag](../administration/feature_flags.md) named `instance_streaming_audit_events`. Disabled by default.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/398107) in GitLab 16.1 [with a flag](../administration/feature_flags.md) named `ff_external_audit_events`. Disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](feature_flags.md) named
-`instance_streaming_audit_events`. On GitLab.com, this feature is not available. The feature is not ready for production use.
+`ff_external_audit_events`. On GitLab.com, this feature is not available. The feature is not ready for production use.
Prerequisites:
@@ -188,11 +188,11 @@ To list the streaming destinations for a top-level group:
#### For instance streaming destinations
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/398107) in GitLab 16.1 [with a flag](../administration/feature_flags.md) named `instance_streaming_audit_events`. Disabled by default.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/398107) in GitLab 16.1 [with a flag](../administration/feature_flags.md) named `ff_external_audit_events`. Disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](feature_flags.md) named
-`instance_streaming_audit_events`. On GitLab.com, this feature is not available. The feature is not ready for production use.
+`ff_external_audit_events`. On GitLab.com, this feature is not available. The feature is not ready for production use.
Prerequisites:
@@ -388,11 +388,11 @@ To delete only the custom HTTP headers for a streaming destination:
#### Instance streaming destinations
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/398107) in GitLab 16.1 [with a flag](../administration/feature_flags.md) named `instance_streaming_audit_events`. Disabled by default.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/398107) in GitLab 16.1 [with a flag](../administration/feature_flags.md) named `ff_external_audit_events`. Disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](feature_flags.md) named
-`instance_streaming_audit_events`. On GitLab.com, this feature is not available. The feature is not ready for production use.
+`ff_external_audit_events`. On GitLab.com, this feature is not available. The feature is not ready for production use.
Prerequisites:
@@ -494,11 +494,11 @@ Users with the Owner role for a group can list streaming destinations and see th
#### Instance streaming destinations
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/398107) in GitLab 16.1 [with a flag](../administration/feature_flags.md) named `instance_streaming_audit_events`. Disabled by default.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/398107) in GitLab 16.1 [with a flag](../administration/feature_flags.md) named `ff_external_audit_events`. Disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](feature_flags.md) named
-`instance_streaming_audit_events`. On GitLab.com, this feature is not available. The feature is not ready for production use.
+`ff_external_audit_events`. On GitLab.com, this feature is not available. The feature is not ready for production use.
Prerequisites:
diff --git a/doc/administration/geo/disaster_recovery/index.md b/doc/administration/geo/disaster_recovery/index.md
index 29fe72a9dce..396162fe9ef 100644
--- a/doc/administration/geo/disaster_recovery/index.md
+++ b/doc/administration/geo/disaster_recovery/index.md
@@ -542,19 +542,19 @@ Geo on the new **primary** site.
To bring a new **secondary** site online, follow the [Geo setup instructions](../index.md#setup-instructions).
-### Step 6. (Optional) Removing the secondary's tracking database
+### Step 6. Removing the secondary's tracking database
Every **secondary** has a special tracking database that is used to save the status of the synchronization of all the items from the **primary**.
Because the **secondary** is already promoted, that data in the tracking database is no longer required.
-The data can be removed with the following command:
+You can remove the data with the following command:
```shell
sudo rm -rf /var/opt/gitlab/geo-postgresql
```
If you have any `geo_secondary[]` configuration options enabled in your `gitlab.rb`
-file, these can be safely commented out or removed, and then [reconfigure GitLab](../../restart_gitlab.md#reconfigure-a-linux-package-installation)
+file, comment them out or remove them, and then [reconfigure GitLab](../../restart_gitlab.md#reconfigure-a-linux-package-installation)
for the changes to take effect.
## Promoting secondary Geo replica in multi-secondary configurations
diff --git a/doc/administration/redis/replication_and_failover.md b/doc/administration/redis/replication_and_failover.md
index 257d6cb54cb..4a6f58a8d6a 100644
--- a/doc/administration/redis/replication_and_failover.md
+++ b/doc/administration/redis/replication_and_failover.md
@@ -348,11 +348,7 @@ the same Sentinels.
### Step 3. Configuring the Redis Sentinel instances
NOTE:
-If you are using an external Redis Sentinel instance, be sure
-to exclude the `requirepass` parameter from the Sentinel
-configuration. This parameter causes clients to report `NOAUTH
-Authentication required.`.
-[Redis Sentinel 3.2.x does not support password authentication](https://github.com/antirez/redis/issues/3279).
+[Support for Sentinel password authentication](https://gitlab.com/gitlab-org/gitlab/-/issues/235938) was introduced in GitLab 16.1.
Now that the Redis servers are all set up, let's configure the Sentinel
servers.
@@ -408,6 +404,9 @@ multiple machines with the Sentinel daemon.
## Configure Sentinel
sentinel['bind'] = '10.0.0.1'
+ ## Optional password for Sentinel authentication. Defaults to no password required.
+ # sentinel['password'] = 'sentinel-password-goes here'
+
# Port that Sentinel listens on, uncomment to change to non default. Defaults
# to `26379`.
# sentinel['port'] = 26379
@@ -493,6 +492,7 @@ which ideally should not have Redis or Sentinels on it for a HA setup.
{'host' => '10.0.0.2', 'port' => 26379},
{'host' => '10.0.0.3', 'port' => 26379}
]
+ # gitlab_rails['redis_sentinels_password'] = 'sentinel-password-goes-here' # uncomment and set it to the same value as in sentinel['password']
```
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@@ -570,6 +570,7 @@ redis['master_password'] = 'redis-password-goes-here' # the same value defined i
redis['master_ip'] = '10.0.0.1' # ip of the initial primary redis instance
#redis['master_port'] = 6379 # port of the initial primary redis instance, uncomment to change to non default
sentinel['bind'] = '10.0.0.1'
+# sentinel['password'] = 'sentinel-password-goes-here' # must be the same in every sentinel node, uncomment to set a password
# sentinel['port'] = 26379 # uncomment to change default port
sentinel['quorum'] = 2
# sentinel['down_after_milliseconds'] = 10000
@@ -592,6 +593,7 @@ redis['master_ip'] = '10.0.0.1' # IP of primary Redis server
#redis['master_port'] = 6379 # Port of primary Redis server, uncomment to change to non default
redis['master_name'] = 'gitlab-redis' # must be the same in every sentinel node
sentinel['bind'] = '10.0.0.2'
+# sentinel['password'] = 'sentinel-password-goes-here' # must be the same in every sentinel node, uncomment to set a password
# sentinel['port'] = 26379 # uncomment to change default port
sentinel['quorum'] = 2
# sentinel['down_after_milliseconds'] = 10000
@@ -614,6 +616,7 @@ redis['master_ip'] = '10.0.0.1' # IP of primary Redis server
#redis['master_port'] = 6379 # Port of primary Redis server, uncomment to change to non default
redis['master_name'] = 'gitlab-redis' # must be the same in every sentinel node
sentinel['bind'] = '10.0.0.3'
+# sentinel['password'] = 'sentinel-password-goes-here' # must be the same in every sentinel node, uncomment to set a password
# sentinel['port'] = 26379 # uncomment to change default port
sentinel['quorum'] = 2
# sentinel['down_after_milliseconds'] = 10000
@@ -634,6 +637,7 @@ gitlab_rails['redis_sentinels'] = [
{'host' => '10.0.0.2', 'port' => 26379},
{'host' => '10.0.0.3', 'port' => 26379}
]
+# gitlab_rails['redis_sentinels_password'] = 'sentinel-password-goes-here' # uncomment and set it to the same value as in sentinel['password']
```
[Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
@@ -657,6 +661,7 @@ persistence classes.
| `trace_chunks` | Store [CI trace chunks](../job_logs.md#enable-or-disable-incremental-logging) data. |
| `rate_limiting` | Store [rate limiting](../../user/admin_area/settings/user_and_ip_rate_limits.md) state. |
| `sessions` | Store [sessions](../../../ee/development/session.md#gitlabsession). |
+| `repository_cache` | Store cache data specific to repositories. |
To make this work with Sentinel:
@@ -671,6 +676,7 @@ To make this work with Sentinel:
gitlab_rails['redis_trace_chunks_instance'] = REDIS_TRACE_CHUNKS_URL
gitlab_rails['redis_rate_limiting_instance'] = REDIS_RATE_LIMITING_URL
gitlab_rails['redis_sessions_instance'] = REDIS_SESSIONS_URL
+ gitlab_rails['redis_repository_cache_instance'] = REDIS_REPOSITORY_CACHE_URL
# Configure the Sentinels
gitlab_rails['redis_cache_sentinels'] = [
@@ -701,6 +707,19 @@ To make this work with Sentinel:
{ host: SESSIONS_SENTINEL_HOST, port: 26379 },
{ host: SESSIONS_SENTINEL_HOST2, port: 26379 }
]
+ gitlab_rails['redis_repository_cache_sentinels'] = [
+ { host: REPOSITORY_CACHE_SENTINEL_HOST, port: 26379 },
+ { host: REPOSITORY_CACHE_SENTINEL_HOST2, port: 26379 }
+ ]
+
+ # gitlab_rails['redis_cache_sentinels_password'] = 'sentinel-password-goes-here'
+ # gitlab_rails['redis_queues_sentinels_password'] = 'sentinel-password-goes-here'
+ # gitlab_rails['redis_shared_state_sentinels_password'] = 'sentinel-password-goes-here'
+ # gitlab_rails['redis_actioncable_sentinels_password'] = 'sentinel-password-goes-here'
+ # gitlab_rails['redis_trace_chunks_sentinels_password'] = 'sentinel-password-goes-here'
+ # gitlab_rails['redis_rate_limiting_sentinels_password'] = 'sentinel-password-goes-here'
+ # gitlab_rails['redis_sessions_sentinels_password'] = 'sentinel-password-goes-here'
+ # gitlab_rails['redis_repository_cache_sentinels_password'] = 'sentinel-password-goes-here'
```
- Redis URLs should be in the format: `redis://:PASSWORD@SENTINEL_PRIMARY_NAME`, where:
diff --git a/doc/administration/sidekiq/processing_specific_job_classes.md b/doc/administration/sidekiq/processing_specific_job_classes.md
index 26c2804f130..696b0b9444c 100644
--- a/doc/administration/sidekiq/processing_specific_job_classes.md
+++ b/doc/administration/sidekiq/processing_specific_job_classes.md
@@ -25,10 +25,6 @@ Both of these use the same [worker matching query](#worker-matching-query)
syntax. While they can technically be used together, most deployments should
choose one or the other; there is no particular benefit in combining them.
-Routing rules must be the same across all GitLab nodes as they are part of the
-application configuration. Queue selectors can be different across GitLab nodes
-because they only change the arguments to the launched Sidekiq process.
-
## Routing rules
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59604) in GitLab 13.12.
@@ -61,6 +57,12 @@ the migration to avoid losing jobs entirely, especially in a system with long
queues of jobs. The migration can be done by following the migration steps
mentioned in [Sidekiq job migration](sidekiq_job_migration.md).
+### Routing rules in a scaled architecture
+
+Routing rules must be the same across all GitLab nodes (especially GitLab Rails and Sidekiq nodes) as they are part of the
+application configuration. Queue selectors can be different across GitLab nodes
+because they only change the arguments to the launched Sidekiq process.
+
### Detailed example
This is a comprehensive example intended to show different possibilities. It is
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 0fc857a4ebd..6c879648e68 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -26560,6 +26560,7 @@ Name of the feature that the callout is for.
| <a id="usercalloutfeaturenameenumgold_trial_billings"></a>`GOLD_TRIAL_BILLINGS` | Callout feature name for gold_trial_billings. |
| <a id="usercalloutfeaturenameenummerge_request_settings_moved_callout"></a>`MERGE_REQUEST_SETTINGS_MOVED_CALLOUT` | Callout feature name for merge_request_settings_moved_callout. |
| <a id="usercalloutfeaturenameenummr_experience_survey"></a>`MR_EXPERIENCE_SURVEY` | Callout feature name for mr_experience_survey. |
+| <a id="usercalloutfeaturenameenumnamespace_over_storage_users_combined_alert"></a>`NAMESPACE_OVER_STORAGE_USERS_COMBINED_ALERT` | Callout feature name for namespace_over_storage_users_combined_alert. |
| <a id="usercalloutfeaturenameenumnamespace_storage_limit_banner_alert_threshold"></a>`NAMESPACE_STORAGE_LIMIT_BANNER_ALERT_THRESHOLD` | Callout feature name for namespace_storage_limit_banner_alert_threshold. |
| <a id="usercalloutfeaturenameenumnamespace_storage_limit_banner_error_threshold"></a>`NAMESPACE_STORAGE_LIMIT_BANNER_ERROR_THRESHOLD` | Callout feature name for namespace_storage_limit_banner_error_threshold. |
| <a id="usercalloutfeaturenameenumnamespace_storage_limit_banner_info_threshold"></a>`NAMESPACE_STORAGE_LIMIT_BANNER_INFO_THRESHOLD` | Callout feature name for namespace_storage_limit_banner_info_threshold. |
diff --git a/doc/api/runners.md b/doc/api/runners.md
index a2614b95bb9..574bce82793 100644
--- a/doc/api/runners.md
+++ b/doc/api/runners.md
@@ -23,7 +23,7 @@ There are two tokens to take into account when connecting a runner with GitLab.
| Token | Description |
| ----- | ----------- |
| Registration token | Token used to [register the runner](https://docs.gitlab.com/runner/register/). It can be [obtained through GitLab](../ci/runners/index.md). |
-| Authentication token | Token used to authenticate the runner with the GitLab instance. It is obtained automatically when you [register a runner](https://docs.gitlab.com/runner/register/) or by the Runner API when you manually [register a runner](#register-a-new-runner) or [reset the authentication token](#reset-runners-authentication-token-by-using-the-runner-id). |
+| Authentication token | Token used to authenticate the runner with the GitLab instance. It is obtained automatically when you [register a runner](https://docs.gitlab.com/runner/register/) or by the Runner API when you manually [register a runner](#register-a-new-runner) or [reset the authentication token](#reset-runners-authentication-token-by-using-the-runner-id). You can also obtain the authentication token using [Create a runner](users.md#create-a-runner) API method. |
Here's an example of how the two tokens are used in runner registration:
diff --git a/doc/ci/runners/new_creation_workflow.md b/doc/ci/runners/new_creation_workflow.md
index 95118cf4b8a..0c43fd21d1d 100644
--- a/doc/ci/runners/new_creation_workflow.md
+++ b/doc/ci/runners/new_creation_workflow.md
@@ -150,3 +150,50 @@ gitlab-runner register \
--url "https://gitlab.com/" \
--token "$RUNNER_TOKEN"
```
+
+## Installing GitLab Runner with Helm chart
+
+Several runner configuration options cannot be set during runner registration. These options can only be configured:
+
+- When you create a runner in the UI.
+- With the `user/runners` REST API endpoint.
+
+The following configuration options are no longer supported in [`values.yaml`](https://gitlab.com/gitlab-org/charts/gitlab-runner/-/blob/main/values.yaml):
+
+```yaml
+## All these fields are DEPRECATED and the runner WILL FAIL TO START if you specify them
+runnerRegistrationToken: ""
+locked: true
+tags: ""
+maximumTimeout: ""
+runUntagged: true
+protected: true
+```
+
+If you store the runner token in `secrets`, you must also modify them.
+
+In the legacy runner registration workflow, fields were specified with:
+
+```yaml
+apiVersion: v1
+kind: Secret
+metadata:
+ name: gitlab-runner-secret
+type: Opaque
+data:
+ runner-registration-token: "REDACTED" # DEPRECATED, set to ""
+ runner-token: ""
+```
+
+In the new runner registration workflow, you must use `runner-token` instead:
+
+```yaml
+apiVersion: v1
+kind: Secret
+metadata:
+ name: gitlab-runner-secret
+type: Opaque
+data:
+ runner-registration-token: "" # need to leave as an empty string for compatibility reasons
+ runner-token: "REDACTED"
+```
diff --git a/doc/ci/runners/register_runner.md b/doc/ci/runners/register_runner.md
index 3b0ed1f7637..9c63850e38a 100644
--- a/doc/ci/runners/register_runner.md
+++ b/doc/ci/runners/register_runner.md
@@ -42,6 +42,8 @@ To generate an authentication token for a shared runner:
1. Select **Submit**.
1. Follow the instructions to register the runner from the command line.
+You can also [create a runner](../../api/users.md#create-a-runner) with the API to generate an authentication token.
+
### For a group runner
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/383143) in GitLab 15.10. Deployed behind the `create_runner_workflow_for_namespace` [flag](../../administration/feature_flags.md). Disabled by default.
@@ -65,6 +67,8 @@ To generate an authentication token for a group runner:
1. Select **Submit**.
1. Follow the instructions to register the runner from the command line.
+You can also [create a runner](../../api/users.md#create-a-runner) with the API to generate an authentication token.
+
### For a project runner
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/383143) in GitLab 15.10. Deployed behind the `create_runner_workflow_for_namespace` [flag](../../administration/feature_flags.md). Disabled by default.
@@ -89,6 +93,8 @@ To generate an authentication token for a project runner:
1. Select **Submit**.
1. Follow the instructions to register the runner from the command line.
+You can also [create a runner](../../api/users.md#create-a-runner) with the API to generate an authentication token.
+
## Generate a registration token (deprecated)
WARNING:
diff --git a/doc/ci/runners/saas/macos_saas_runner.md b/doc/ci/runners/saas/macos_saas_runner.md
index 2d897e978ed..836a14d7521 100644
--- a/doc/ci/runners/saas/macos_saas_runner.md
+++ b/doc/ci/runners/saas/macos_saas_runner.md
@@ -115,7 +115,7 @@ Related topics:
## Optimizing Homebrew
By default, Homebrew checks for updates at the start of any operation. Homebrew has a
-release cycle that may be more frequent than the GitLab MacOS image release cycle. This
+release cycle that may be more frequent than the GitLab MacOS image release cycle. This
difference in release cycles may cause steps that call `brew` to take extra time to complete
while Homebrew makes updates.
diff --git a/doc/ci/yaml/includes.md b/doc/ci/yaml/includes.md
index 5c818a81ff8..69595b62de2 100644
--- a/doc/ci/yaml/includes.md
+++ b/doc/ci/yaml/includes.md
@@ -418,7 +418,7 @@ these keywords:
### `include` with `rules:if`
-> Support for `when: never` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/348146) in GitLab 16.1.
+> Support for `when: never` and `when:always` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/348146) in GitLab 16.1 [with a flag](../../administration/feature_flags.md) named `ci_support_include_rules_when_never`. Disabled by default.
Use [`rules:if`](index.md#rulesif) to conditionally include other configuration files
based on the status of CI/CD variables. For example:
@@ -431,6 +431,10 @@ include:
when: never
- local: builds.yml
rules:
+ - if: $ALWAYS_INCLUDE_BUILDS == "true"
+ when: always
+ - local: builds.yml
+ rules:
- if: $INCLUDE_BUILDS == "true"
- local: deploys.yml
rules:
@@ -443,7 +447,7 @@ test:
### `include` with `rules:exists`
-> Support for `when: never` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/348146) in GitLab 16.1.
+> Support for `when: never` and `when:always` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/348146) in GitLab 16.1 [with a flag](../../administration/feature_flags.md) named `ci_support_include_rules_when_never`. Disabled by default.
Use [`rules:exists`](index.md#rulesexists) to conditionally include other configuration files
based on the existence of files. For example:
@@ -458,6 +462,11 @@ include:
- local: builds.yml
rules:
- exists:
+ - important-file.md
+ when: always
+ - local: builds.yml
+ rules:
+ - exists:
- file.md
test:
diff --git a/doc/development/spam_protection_and_captcha/model_and_services.md b/doc/development/spam_protection_and_captcha/model_and_services.md
index 2c7ec8c3f50..5f91bf47af4 100644
--- a/doc/development/spam_protection_and_captcha/model_and_services.md
+++ b/doc/development/spam_protection_and_captcha/model_and_services.md
@@ -20,7 +20,7 @@ To do this:
1. [Add `Spammable` support to the ActiveRecord model](#add-spammable-support-to-the-activerecord-model).
1. [Add support for the `mark_as_spam` action to the controller](#add-support-for-the-mark_as_spam-action-to-the-controller).
-1. [Add a call to SpamActionService to the execute method of services](#add-a-call-to-spamactionservice-to-the-execute-method-of-services).
+1. [Add a call to `check_for_spam` to the execute method of services](#add-a-call-to-check_for_spam-to-the-execute-method-of-services).
## Add `Spammable` support to the ActiveRecord model
@@ -80,13 +80,11 @@ NOTE:
There may be other changes needed to controllers, depending on how the feature is
implemented. See [Web UI](web_ui.md) for more details.
-## Add a call to SpamActionService to the execute method of services
+## Add a call to `check_for_spam` to the execute method of services
This approach applies to any service which can persist spammable attributes:
-1. In the relevant Create or Update service under `app/services`, pass in a populated
- `Spam::SpamParams` instance. (Refer to instructions later on in this page.)
-1. Use it and the `Spammable` model instance to execute a `Spam::SpamActionService` instance.
+1. In the relevant Create or Update service under `app/services`, call the `check_for_spam` method on the model.
1. If the spam check fails:
- An error is added to the model, which causes it to be invalid and prevents it from being saved.
- The `needs_recaptcha` property is set to `true`.
@@ -95,38 +93,24 @@ This approach applies to any service which can persist spammable attributes:
Make these changes to each relevant service:
-1. Change the constructor to take a `spam_params:` argument as a required named argument.
-
- Using named arguments for the constructor helps you identify all the calls to
- the constructor that need changing. It's less risky because the interpreter raises
- type errors unless the caller is changed to pass the `spam_params` argument.
- If you use an IDE (such as RubyMine) which supports this, your
- IDE flags it as an error in the editor.
-
-1. In the constructor, set the `@spam_params` instance variable from the `spam_params` constructor
- argument. Add an `attr_reader: :spam_params` in the `private` section of the class.
-
-1. In the `execute` method, add a call to execute the `Spam::SpamActionService`.
+1. In the `execute` method, call the `check_for_spam` method on the model.
(You can also use `before_create` or `before_update`, if the service
uses that pattern.) This method uses named arguments, so its usage is clear if
you refer to existing examples. However, two important considerations exist:
- 1. The `SpamActionService` must be executed _after_ all necessary changes are made to
+ 1. The `check_for_spam` must be executed _after_ all necessary changes are made to
the unsaved (and dirty) `Spammable` model instance. This ordering ensures
spammable attributes exist to be spam-checked.
- 1. The `SpamActionService` must be executed _before_ the model is checked for errors and
+ 1. The `check_for_spam` must be executed _before_ the model is checked for errors and
attempting a `save`. If potential spam is detected in the model's changed attributes, we must prevent a save.
```ruby
module Widget
class CreateService < ::Widget::BaseService
- # NOTE: We require the spam_params and do not default it to nil, because
- # spam_checking is likely to be necessary. However, if there is not a request available in scope
- # in the caller (for example, a note created via email) and the required arguments to the
- # SpamParams constructor are not otherwise available, spam_params: must be explicitly passed as nil.
- def initialize(project:, current_user: nil, params: {}, spam_params:)
+ # NOTE: We add a default value of `true` for `perform_spam_check`, because spam checking is likely to be necessary.
+ def initialize(project:, current_user: nil, params: {}, perform_spam_check: true)
super(project: project, current_user: current_user, params: params)
- @spam_params = spam_params
+ @perform_spam_check = perform_spam_check
end
def execute
@@ -136,13 +120,7 @@ module Widget
# NOTE: do this AFTER the spammable model is instantiated, but BEFORE
# it is validated or saved.
- Spam::SpamActionService.new(
- spammable: widget,
- spam_params: spam_params,
- user: current_user,
- # Or `action: :update` for a UpdateService or service for an existing model.
- action: :create
- ).execute
+ widget.check_for_spam(user: current_user, action: :create) if perform_spam_check
# Possibly more code related to saving model, but should not change any attributes.
@@ -151,5 +129,5 @@ module Widget
private
- attr_reader :spam_params
+ attr_reader :perform_spam_check
```
diff --git a/doc/update/index.md b/doc/update/index.md
index 54686567e5b..0380f1a69ef 100644
--- a/doc/update/index.md
+++ b/doc/update/index.md
@@ -1198,6 +1198,8 @@ for how to proceed.
sudo gitlab-rake "gitlab:password:reset[user_handle]"
```
+- If you encounter the error, `I18n::InvalidLocale: :en is not a valid locale`, when starting the application, follow the [patching](https://about.gitlab.com/handbook/support/workflows/patching_an_instance.html) process. Use [122978](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/122978) as the `mr_iid`.
+
### 14.2.0
- [Instances running 14.0.0 - 14.0.4 should not upgrade directly to GitLab 14.2 or later](#upgrading-to-later-14y-releases).
@@ -1237,6 +1239,8 @@ for how to proceed.
end
```
+- If you encounter the error, `I18n::InvalidLocale: :en is not a valid locale`, when starting the application, follow the [patching](https://about.gitlab.com/handbook/support/workflows/patching_an_instance.html) process. Use [123476](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123476) as the `mr_iid`.
+
### 14.1.0
- [Instances running 14.0.0 - 14.0.4 should not upgrade directly to GitLab 14.2 or later](#upgrading-to-later-14y-releases)
@@ -1254,6 +1258,8 @@ for how to proceed.
- See [Maintenance mode issue in GitLab 13.9 to 14.4](#maintenance-mode-issue-in-gitlab-139-to-144).
+- If you encounter the error, `I18n::InvalidLocale: :en is not a valid locale`, when starting the application, follow the [patching](https://about.gitlab.com/handbook/support/workflows/patching_an_instance.html) process. Use [123475](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123475) as the `mr_iid`.
+
### 14.0.0
Prerequisites:
diff --git a/doc/user/admin_area/settings/package_registry_rate_limits.md b/doc/user/admin_area/settings/package_registry_rate_limits.md
index 61abf68e75c..a1bc339ddd9 100644
--- a/doc/user/admin_area/settings/package_registry_rate_limits.md
+++ b/doc/user/admin_area/settings/package_registry_rate_limits.md
@@ -32,7 +32,7 @@ To enable the unauthenticated request rate limit:
1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
1. Select **Admin Area**.
-1. Select **Settings > Network**.
+1. Select **Settings > Network**.
1. Expand **Package registry rate limits**.
1. Select **Enable unauthenticated request rate limit**.
diff --git a/doc/user/analytics/analytics_dashboards.md b/doc/user/analytics/analytics_dashboards.md
index 71a51dbf824..e29e02c867f 100644
--- a/doc/user/analytics/analytics_dashboards.md
+++ b/doc/user/analytics/analytics_dashboards.md
@@ -40,41 +40,6 @@ To view a list of dashboards for a project:
1. Select **Analyze > Dashboards**.
1. From the list of available dashboards, select the dashboard you want to view.
-### Change the location of group dashboards
-
-NOTE:
-This feature will be connected to group-level dashboards as part of [issue #411572](https://gitlab.com/gitlab-org/gitlab/-/issues/411572).
-
-To change the location of a group's dashboards:
-
-1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find the project you want to store your dashboard files in.
- The project must belong to the group for which you create the dashboards.
-1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your group.
-1. Select **Settings > General**.
-1. Expand **Analytics**.
-1. In the **Analytics Dashboards** section, select your dashboard files project.
-1. Select **Save changes**.
-
-### Change the location of project dashboards
-
-Dashboards are usually defined in the project where the analytics data is being retrieved from.
-However, you can also have a separate project for dashboards.
-This is recommended if you want to enforce specific access rules to the dashboard definitions or share dashboards across multiple projects.
-
-NOTE:
-You can share dashboards only between projects that are located in the same group.
-
-To change the location of project dashboards:
-
-1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project,
- or select **Create new...** (**{plus}**) and **New project/repository**
- to create the project to store your dashboard files.
-1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) and find the analytics project.
-1. Select **Settings > General**.
-1. Expand **Analytics**.
-1. In the **Analytics Dashboards** section, select your dashboard files project.
-1. Select **Save changes**.
-
### Define a dashboard
To define a dashboard:
@@ -126,6 +91,42 @@ create a `line_chart.yaml` file with the following required fields:
- data
- options
+### Change the location of project dashboards
+
+Dashboards are usually defined in the project where analytics data is being retrieved.
+However, you can also have a separate project for dashboards.
+This is recommended if you want to enforce specific access rules to the dashboard definitions or share dashboards across multiple projects.
+
+NOTE:
+You can share dashboards only between projects that are located in the same group.
+
+To change the location of project dashboards:
+
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project,
+ or select **Create new...** (**{plus}**) and **New project/repository**
+ to create the project to store your dashboard files.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) and find the project you want to use the dashboards for.
+1. Select **Settings > General**.
+1. Expand **Analytics**.
+1. In the **Analytics Dashboards** section, select the project that contains the dashboard files.
+1. Select **Save changes**.
+
+### Change the location of group dashboards
+
+NOTE:
+This feature will be connected to group-level dashboards in [issue 411572](https://gitlab.com/gitlab-org/gitlab/-/issues/411572).
+
+If you want to use dashboards for a group, you must store the dashboard files in a project that belongs to that group.
+You can change the source project of a group's dashboards at any time.
+
+To change the location of a group's dashboards:
+
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your group.
+1. Select **Settings > General**.
+1. Expand **Analytics**.
+1. In the **Analytics Dashboards** section, select the project that contains the dashboard files.
+1. Select **Save changes**.
+
## Dashboards designer
> Introduced in GitLab 16.1 [with a flag](../../administration/feature_flags.md) named `combined_analytics_dashboards_editor`. Disabled by default.
diff --git a/doc/user/application_security/api_fuzzing/index.md b/doc/user/application_security/api_fuzzing/index.md
index 46f6dd63d3f..28e72816a99 100644
--- a/doc/user/application_security/api_fuzzing/index.md
+++ b/doc/user/application_security/api_fuzzing/index.md
@@ -101,8 +101,8 @@ a YAML snippet that you can paste in your GitLab CI/CD configuration.
To generate an API Fuzzing configuration snippet:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Security configuration**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Security configuration**.
1. In the **API Fuzzing** row, select **Enable API Fuzzing**.
1. Complete the fields. For details see [Available CI/CD variables](#available-cicd-variables).
1. Select **Generate code snippet**.
diff --git a/doc/user/application_security/configuration/index.md b/doc/user/application_security/configuration/index.md
index d5a05477ddf..bbb7bf2f625 100644
--- a/doc/user/application_security/configuration/index.md
+++ b/doc/user/application_security/configuration/index.md
@@ -40,8 +40,8 @@ all security features are configured by default.
To view a project's security configuration:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Security configuration**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Security configuration**.
Select **Configuration history** to see the `.gitlab-ci.yml` file's history.
diff --git a/doc/user/application_security/coverage_fuzzing/index.md b/doc/user/application_security/coverage_fuzzing/index.md
index 4fd9863d643..b0571c8a6ca 100644
--- a/doc/user/application_security/coverage_fuzzing/index.md
+++ b/doc/user/application_security/coverage_fuzzing/index.md
@@ -58,8 +58,8 @@ You can use the following fuzzing engines to test the specified languages.
To confirm the status of coverage-guided fuzz testing:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Security configuration**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Security configuration**.
1. In the **Coverage Fuzzing** section the status is:
- **Not configured**
- **Enabled**
@@ -172,8 +172,8 @@ artifacts files you can download from the CI/CD pipeline. Also, a project member
To view details of the corpus registry:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Security configuration**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Security configuration**.
1. In the **Coverage Fuzzing** section, select **Manage corpus**.
### Create a corpus in the corpus registry
@@ -200,8 +200,8 @@ provided by the `COVFUZZ_CORPUS_NAME` variable. The corpus is updated on every p
To upload an existing corpus file:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Security configuration**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Security configuration**.
1. In the **Coverage Fuzzing** section, select **Manage corpus**.
1. Select **New corpus**.
1. Complete the fields.
diff --git a/doc/user/application_security/dast/proxy-based.md b/doc/user/application_security/dast/proxy-based.md
index f65501712cc..499efd3f60d 100644
--- a/doc/user/application_security/dast/proxy-based.md
+++ b/doc/user/application_security/dast/proxy-based.md
@@ -89,8 +89,8 @@ In this method you manually edit the existing `.gitlab-ci.yml` file. Use this me
To include the DAST template:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **CI/CD > Editor**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Build > Pipeline editor**.
1. Copy and paste the following to the bottom of the `.gitlab-ci.yml` file.
To use the DAST stable template:
@@ -156,8 +156,8 @@ snippet is created that you paste into the `.gitlab-ci.yml` file.
To configure DAST using the UI:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security & Compliance > Configuration**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Security configuration**.
1. In the **Dynamic Application Security Testing (DAST)** section, select **Enable DAST** or
**Configure DAST**.
1. Select the desired **Scanner profile**, or select **Create scanner profile** and save a
@@ -548,8 +548,8 @@ The on-demand DAST scan runs and the project's dashboard shows the results.
To run a saved on-demand scan:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security & Compliance > On-demand Scans**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > On-demand scans**.
1. Select the **Scan library** tab.
1. In the scan's row, select **Run scan**.
@@ -567,8 +567,8 @@ The on-demand DAST scan runs, and the project's dashboard shows the results.
To schedule a scan:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security & Compliance > On-demand Scans**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > On-demand scans**.
1. Select **New scan**.
1. Complete the **Scan name** and **Description** text boxes.
1. In GitLab 13.10 and later, from the **Branch** dropdown list, select the desired branch.
@@ -715,8 +715,8 @@ Validating a site is required to run an active scan.
To validate a site profile:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security & Compliance > Configuration**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Security configuration**.
1. In the **Dynamic Application Security Testing (DAST)** section, select **Manage profiles**.
1. Select the **Site Profiles** tab.
1. In the profile's row, select **Validate**.
@@ -752,8 +752,8 @@ page.
To retry a site profile's failed validation:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security & Compliance > Configuration**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Security configuration**.
1. In the **Dynamic Application Security Testing (DAST)** section, select **Manage profiles**.
1. Select the **Site Profiles** tab.
1. In the profile's row, select **Retry validation**.
diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md
index 4b0f4d19f95..df9e1d72dba 100644
--- a/doc/user/application_security/dependency_scanning/index.md
+++ b/doc/user/application_security/dependency_scanning/index.md
@@ -578,8 +578,8 @@ always take the latest dependency scanning artifact available.
To enable Dependency Scanning in a project, you can create a merge request:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Security configuration**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Security configuration**.
1. In the **Dependency Scanning** row, select **Configure with a merge request**.
1. Review and merge the merge request to enable Dependency Scanning.
diff --git a/doc/user/application_security/iac_scanning/index.md b/doc/user/application_security/iac_scanning/index.md
index ae23b0b0f78..8e2f54fed44 100644
--- a/doc/user/application_security/iac_scanning/index.md
+++ b/doc/user/application_security/iac_scanning/index.md
@@ -121,8 +121,8 @@ The **Configure with a merge request** button been temporarily disabled due to a
To enable IaC Scanning in a project, you can create a merge request:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Security configuration**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Security configuration**.
1. In the **Infrastructure as Code (IaC) Scanning** row, select **Configure with a merge request**.
1. Review and merge the merge request to enable IaC Scanning.
diff --git a/doc/user/application_security/policies/index.md b/doc/user/application_security/policies/index.md
index 0b5ea6993a2..bd3da0b5913 100644
--- a/doc/user/application_security/policies/index.md
+++ b/doc/user/application_security/policies/index.md
@@ -58,8 +58,8 @@ to select, edit, and unlink a security policy project.
As a project owner, take the following steps to create or edit an association between your current
project and a project that you would like to designate as the security policy project:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Policies**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Policies**.
1. Select **Edit Policy Project**, and search for and select the
project you would like to link from the dropdown list.
1. Select **Save**.
@@ -82,8 +82,8 @@ policies for all available environments. You can check a
policy's information (for example, description or enforcement
status), and create and edit deployed policies:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Policies**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Policies**.
![Policies List Page](img/policies_list_v15_1.png)
@@ -93,8 +93,8 @@ status), and create and edit deployed policies:
You can use the policy editor to create, edit, and delete policies:
-1. On the top bar, select **Main menu > Projects** and find your group.
-1. On the left sidebar, select **Security and Compliance > Policies**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Policies**.
- To create a new policy, select **New policy** which is located in the **Policies** page's header.
You can then select which type of policy to create.
- To edit an existing policy, select **Edit policy** in the selected policy drawer.
diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md
index c23fe1f2aa7..2008375d2a2 100644
--- a/doc/user/application_security/sast/index.md
+++ b/doc/user/application_security/sast/index.md
@@ -301,8 +301,8 @@ successfully, and an error may occur.
To enable and configure SAST with customizations:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Security configuration**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Security configuration**.
1. If the project does not have a `.gitlab-ci.yml` file, select **Enable SAST** in the Static
Application Security Testing (SAST) row, otherwise select **Configure SAST**.
1. Enter the custom SAST values.
@@ -328,8 +328,8 @@ successfully, and an error may occur.
To enable and configure SAST with default settings:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance** > **Configuration**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Security configuration**.
1. In the SAST section, select **Configure with a merge request**.
1. Review and merge the merge request to enable SAST.
diff --git a/doc/user/application_security/secret_detection/index.md b/doc/user/application_security/secret_detection/index.md
index 86551b1c5d5..2e6de222ec3 100644
--- a/doc/user/application_security/secret_detection/index.md
+++ b/doc/user/application_security/secret_detection/index.md
@@ -155,8 +155,8 @@ To enable Secret Detection, either:
This method requires you to manually edit the existing `.gitlab-ci.yml` file. Use this method if
your GitLab CI/CD configuration file is complex.
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **CI/CD > Editor**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Build > Pipeline editor**.
1. Copy and paste the following to the bottom of the `.gitlab-ci.yml` file:
```yaml
@@ -188,8 +188,8 @@ error may occur. In that case, use the [manual](#edit-the-gitlab-ciyml-file-manu
To enable Secret Detection:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Security configuration**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Security configuration**.
1. In the **Secret Detection** row, select **Configure with a merge request**.
1. Optional. Complete the fields.
1. Select **Create merge request**.
diff --git a/doc/user/application_security/security_dashboard/index.md b/doc/user/application_security/security_dashboard/index.md
index e6cb4cef4b2..e28c06236aa 100644
--- a/doc/user/application_security/security_dashboard/index.md
+++ b/doc/user/application_security/security_dashboard/index.md
@@ -66,8 +66,8 @@ Project Security Dashboards show statistics for all vulnerabilities with a curre
To view total number of vulnerabilities over time:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Security Dashboard**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Security dashboard**.
1. Filter and search for what you need.
- To filter the chart by severity, select the legend name.
- To view a specific time frame, use the time range handles (**{scroll-handle}**).
@@ -79,8 +79,8 @@ To view total number of vulnerabilities over time:
To download an SVG image of the vulnerabilities chart:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Security dashboard**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Security dashboard**.
1. Select **Save chart as an image** (**{download}**).
## View vulnerabilities over time for a group
@@ -90,8 +90,8 @@ branches of projects in a group and its subgroups.
To view vulnerabilities over time for a group:
-1. On the top bar, select **Main menu > Groups** and select a group.
-1. Select **Security > Security Dashboard**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your group.
+1. Select **Security > Security dashboard**.
1. Hover over the chart to get more details about vulnerabilities.
- You can display the vulnerability trends over a 30, 60, or 90-day time frame (the default is 90 days).
- To view aggregated data beyond a 90-day time frame, use the
@@ -104,8 +104,8 @@ Use the group Security Dashboard to view the security status of projects.
To view project security status for a group:
-1. On the top bar, select **Main menu > Groups** and select a group.
-1. Select **Security > Security Dashboard**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your group.
+1. Select **Secure > Security dashboard**.
Each project is assigned a letter [grade](#project-vulnerability-grades) according to the highest-severity open vulnerability.
Dismissed or resolved vulnerabilities are excluded. Each project can receive only one letter grade and appears only once
@@ -140,14 +140,20 @@ The Security Center includes:
### View the Security Center
-To view the Security Center, on the top bar, select **Main menu > Security**.
+To view the Security Center:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Your work**.
+1. Select **Security > Security dashboard**.
### Add projects to the Security Center
To add projects to the Security Center:
-1. On the top bar, select **Main menu > Security**.
-1. On the left sidebar, select **Settings**, or select **Add projects**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Your work**.
+1. Expand **Security**.
+1. Select **Settings**.
1. Use the **Search your projects** text box to search for and select projects.
1. Select **Add projects**.
diff --git a/doc/user/application_security/vulnerabilities/index.md b/doc/user/application_security/vulnerabilities/index.md
index c21a197bcb7..39d8e28e564 100644
--- a/doc/user/application_security/vulnerabilities/index.md
+++ b/doc/user/application_security/vulnerabilities/index.md
@@ -55,8 +55,8 @@ When dismissing a vulnerability, one of the following reasons must be chosen to
To change a vulnerability's status from its Vulnerability Page:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Vulnerability report**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Vulnerability report**.
1. Select the vulnerability's description.
1. From the **Status** dropdown list select a status, then select **Change status**.
@@ -85,8 +85,8 @@ that when Jira integration is enabled, the GitLab issue feature is not available
To create a GitLab issue for a vulnerability:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Vulnerability report**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Vulnerability report**.
1. Select the vulnerability's description.
1. Select **Create issue**.
@@ -104,8 +104,8 @@ Prerequisites:
To create a Jira issue for a vulnerability:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Vulnerability report**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Vulnerability report**.
1. Select the vulnerability's description.
1. Select **Create Jira issue**.
1. If you're not already logged in to Jira, sign in.
@@ -137,8 +137,8 @@ Be aware of the following conditions between a vulnerability and a linked issue:
To link a vulnerability to existing issues:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Vulnerability report**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Vulnerability report**.
1. Select the vulnerability's description.
1. In the **Linked issues** section, select the plus icon (**{plus}**).
1. For each issue to be linked, either:
@@ -172,8 +172,8 @@ To resolve a vulnerability, you can either:
To resolve the vulnerability with a merge request:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Vulnerability report**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Vulnerability report**.
1. Select the vulnerability's description.
1. From the **Resolve with merge request** dropdown list, select **Resolve with merge request**.
@@ -184,8 +184,8 @@ Process the merge request according to your standard workflow.
To manually apply the patch that GitLab generated for a vulnerability:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Vulnerability report**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Vulnerability report**.
1. Select the vulnerability's description.
1. From the **Resolve with merge request** dropdown list, select **Download patch to resolve**.
1. Ensure your local project has the same commit checked out that was used to generate the patch.
@@ -206,8 +206,8 @@ Security training helps your developers learn how to fix vulnerabilities. Develo
To enable security training for vulnerabilities in your project:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Security configuration**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Security configuration**.
1. On the tab bar, select **Vulnerability Management**.
1. To enable a security training provider, turn on the toggle.
@@ -224,7 +224,7 @@ Vulnerabilities with a CWE are most likely to return a training result.
To view the security training for a vulnerability:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Vulnerability report**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Vulnerability report**.
1. Select the vulnerability for which you want to view security training.
1. Select **View training**.
diff --git a/doc/user/application_security/vulnerability_report/index.md b/doc/user/application_security/vulnerability_report/index.md
index 08a64c52f18..78f8bbdb0c3 100644
--- a/doc/user/application_security/vulnerability_report/index.md
+++ b/doc/user/application_security/vulnerability_report/index.md
@@ -52,8 +52,8 @@ At the project level, the Vulnerability Report also contains:
To view the project-level vulnerability report:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Vulnerability report**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Vulnerability report**.
## Vulnerability Report actions
@@ -257,8 +257,8 @@ To undo this action, select a different status from the same menu.
To add a new vulnerability finding from your project level Vulnerability Report page:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Security and Compliance > Vulnerability Report**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Secure > Vulnerability report**.
1. Select **Submit vulnerability**.
1. Complete the fields and submit the form.
diff --git a/doc/user/application_security/vulnerability_report/pipeline.md b/doc/user/application_security/vulnerability_report/pipeline.md
index 0e5bb5e10f7..a53e0a8970b 100644
--- a/doc/user/application_security/vulnerability_report/pipeline.md
+++ b/doc/user/application_security/vulnerability_report/pipeline.md
@@ -11,8 +11,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
To view vulnerabilities in a pipeline:
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **CI/CD > Pipelines**.
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
+1. Select **Build > Pipelines**.
1. From the list, select the pipeline you want to check for vulnerabilities.
1. Select the **Security** tab.
diff --git a/doc/user/workspace/index.md b/doc/user/workspace/index.md
index 70beed20786..50164adcd77 100644
--- a/doc/user/workspace/index.md
+++ b/doc/user/workspace/index.md
@@ -37,6 +37,7 @@ Each workspace includes its own set of dependencies, libraries, and tools, which
dns_zone: "workspaces.example.dev"
```
+ You can use any agent defined under the root group of your project, provided that remote development is properly configured for that agent.
- You must have at least the Developer role in the root group.
- In each public project you want to use this feature for, create a [devfile](#devfile):
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project
@@ -157,8 +158,3 @@ You can provide your own container image, which can run as any Linux user ID. It
GitLab uses the Linux root group ID permission to create, update, or delete files in a container. The container runtime used by the Kubernetes cluster must ensure all containers have a default Linux group ID of `0`.
If you have a container image that does not support arbitrary user IDs, you cannot create, update, or delete files in a workspace. To create a container image that supports arbitrary user IDs, see the [OpenShift documentation](https://docs.openshift.com/container-platform/4.12/openshift_images/create-images.html#use-uid_create-images).
-
-## Selecting an agent for your workspace
-
-A project can use any agent defined under the root group of the project,
-provided that remote development is properly configured for that agent.
diff --git a/lib/error_tracking/collector/payload_validator.rb b/lib/error_tracking/collector/payload_validator.rb
deleted file mode 100644
index aae19a3635a..00000000000
--- a/lib/error_tracking/collector/payload_validator.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-module ErrorTracking
- module Collector
- class PayloadValidator
- PAYLOAD_SCHEMA_PATH = Rails.root.join('app', 'validators', 'json_schemas', 'error_tracking_event_payload.json').to_s
-
- def valid?(payload)
- JSONSchemer.schema(Pathname.new(PAYLOAD_SCHEMA_PATH)).valid?(payload)
- end
- end
- end
-end
diff --git a/lib/error_tracking/collector/sentry_auth_parser.rb b/lib/error_tracking/collector/sentry_auth_parser.rb
deleted file mode 100644
index 4945b8f73e1..00000000000
--- a/lib/error_tracking/collector/sentry_auth_parser.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-module ErrorTracking
- module Collector
- class SentryAuthParser
- def self.parse(request)
- # Sentry client sends auth in X-Sentry-Auth header
- #
- # Example of content:
- # "Sentry sentry_version=7, sentry_client=sentry-ruby/4.5.1, sentry_timestamp=1623923398,
- # sentry_key=afadk312..., sentry_secret=123456asd32131..."
- auth = request.headers['X-Sentry-Auth']
-
- # Sentry DSN contains key and secret.
- # The key is required while secret is optional.
- # We are going to use only the key since secret is deprecated.
- public_key = auth[/sentry_key=(\w+)/, 1]
-
- {
- public_key: public_key
- }
- end
- end
- end
-end
diff --git a/lib/error_tracking/collector/sentry_request_parser.rb b/lib/error_tracking/collector/sentry_request_parser.rb
deleted file mode 100644
index ae632ebd518..00000000000
--- a/lib/error_tracking/collector/sentry_request_parser.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-module ErrorTracking
- module Collector
- class SentryRequestParser
- def self.parse(request)
- body = request.body.read
-
- # Request body contains 3 json objects merged together in one StringIO.
- # We need to separate and parse them into array of hash objects.
- json_objects = []
- parser = Yajl::Parser.new
-
- parser.parse(body) do |json_object|
- json_objects << json_object
- end
-
- # The request contains 3 objects: sentry metadata, type data and event data.
- # We need only last two. Type to decide what to do with the request.
- # And event data as it contains all information about the exception.
- _, type, event = json_objects
-
- {
- request_type: type['type'],
- event: event
- }
- end
- end
- end
-end
diff --git a/lib/gitlab/auth/saml/auth_hash.rb b/lib/gitlab/auth/saml/auth_hash.rb
index a2b0dfd5c66..592d88264e9 100644
--- a/lib/gitlab/auth/saml/auth_hash.rb
+++ b/lib/gitlab/auth/saml/auth_hash.rb
@@ -5,7 +5,7 @@ module Gitlab
module Saml
class AuthHash < Gitlab::Auth::OAuth::AuthHash
def groups
- Array.wrap(get_raw(Gitlab::Auth::Saml::Config.groups))
+ Array.wrap(get_raw(Gitlab::Auth::Saml::Config.new(auth_hash.provider).groups))
end
def authn_context
diff --git a/lib/gitlab/auth/saml/config.rb b/lib/gitlab/auth/saml/config.rb
index 815130aeee2..7524d8b9f85 100644
--- a/lib/gitlab/auth/saml/config.rb
+++ b/lib/gitlab/auth/saml/config.rb
@@ -8,26 +8,32 @@ module Gitlab
def enabled?
::AuthHelper.saml_providers.any?
end
+ end
- def options
- Gitlab::Auth::OAuth::Provider.config_for('saml')
- end
+ DEFAULT_PROVIDER_NAME = 'saml'
- def upstream_two_factor_authn_contexts
- options.args[:upstream_two_factor_authn_contexts]
- end
+ def initialize(provider = DEFAULT_PROVIDER_NAME)
+ @provider = provider
+ end
- def groups
- options[:groups_attribute]
- end
+ def options
+ Gitlab::Auth::OAuth::Provider.config_for(@provider)
+ end
- def external_groups
- options[:external_groups]
- end
+ def upstream_two_factor_authn_contexts
+ options.args[:upstream_two_factor_authn_contexts]
+ end
- def admin_groups
- options[:admin_groups]
- end
+ def groups
+ options[:groups_attribute]
+ end
+
+ def external_groups
+ options[:external_groups]
+ end
+
+ def admin_groups
+ options[:admin_groups]
end
end
end
diff --git a/lib/gitlab/auth/saml/user.rb b/lib/gitlab/auth/saml/user.rb
index d14da41deb6..6f72f185c8d 100644
--- a/lib/gitlab/auth/saml/user.rb
+++ b/lib/gitlab/auth/saml/user.rb
@@ -43,7 +43,7 @@ module Gitlab
protected
def saml_config
- Gitlab::Auth::Saml::Config
+ Gitlab::Auth::Saml::Config.new(auth_hash.provider)
end
def auto_link_saml_user?
diff --git a/lib/gitlab/ci/config/entry/include/rules/rule.rb b/lib/gitlab/ci/config/entry/include/rules/rule.rb
index 60ce43a1546..9cdbd8cd037 100644
--- a/lib/gitlab/ci/config/entry/include/rules/rule.rb
+++ b/lib/gitlab/ci/config/entry/include/rules/rule.rb
@@ -10,7 +10,7 @@ module Gitlab
include ::Gitlab::Config::Entry::Attributable
ALLOWED_KEYS = %i[if exists when].freeze
- ALLOWED_WHEN = %w[never].freeze
+ ALLOWED_WHEN = %w[never always].freeze
attributes :if, :exists, :when
diff --git a/lib/gitlab/ci/config/external/rules.rb b/lib/gitlab/ci/config/external/rules.rb
index 8aaa14b3d7b..134306332e6 100644
--- a/lib/gitlab/ci/config/external/rules.rb
+++ b/lib/gitlab/ci/config/external/rules.rb
@@ -19,7 +19,7 @@ module Gitlab
def evaluate(context)
if Feature.enabled?(:ci_support_include_rules_when_never, context.project)
if @rule_list.nil?
- Result.new(nil)
+ Result.new('always')
elsif matched_rule = match_rule(context)
Result.new(matched_rule.attributes[:when])
else
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index 80d0fd17568..6cae0fc1780 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -91,12 +91,10 @@ module Gitlab
end
# Default branch in the repository
- def root_ref
- gitaly_ref_client.default_branch_name
- rescue GRPC::NotFound => e
- raise NoRepository, e.message
- rescue GRPC::Unknown => e
- raise Gitlab::Git::CommandError, e.message
+ def root_ref(head_only: false)
+ wrapped_gitaly_errors do
+ gitaly_ref_client.default_branch_name(head_only: head_only)
+ end
end
def exists?
diff --git a/lib/gitlab/gitaly_client/ref_service.rb b/lib/gitlab/gitaly_client/ref_service.rb
index 88c79eb8954..45edfd4cbbf 100644
--- a/lib/gitlab/gitaly_client/ref_service.rb
+++ b/lib/gitlab/gitaly_client/ref_service.rb
@@ -50,8 +50,8 @@ module Gitlab
consume_find_all_branches_response(response)
end
- def default_branch_name
- request = Gitaly::FindDefaultBranchNameRequest.new(repository: @gitaly_repo)
+ def default_branch_name(head_only: false)
+ request = Gitaly::FindDefaultBranchNameRequest.new(repository: @gitaly_repo, head_only: head_only)
response = gitaly_client_call(@storage, :ref_service, :find_default_branch_name, request, timeout: GitalyClient.fast_timeout)
Gitlab::Git.branch_name(response.name)
end
diff --git a/lib/gitlab/spamcheck/client.rb b/lib/gitlab/spamcheck/client.rb
index 6fbdafc3446..0afaf46fa9b 100644
--- a/lib/gitlab/spamcheck/client.rb
+++ b/lib/gitlab/spamcheck/client.rb
@@ -58,7 +58,7 @@ module Gitlab
pb.title = spammable.spam_title || '' if pb.respond_to?(:title)
pb.description = spammable.spam_description || '' if pb.respond_to?(:description)
pb.text = spammable.spammable_text || '' if pb.respond_to?(:text)
- pb.type = spammable.class.name if pb.respond_to?(:type)
+ pb.type = spammable.spammable_entity_type if pb.respond_to?(:type)
pb.created_at = convert_to_pb_timestamp(spammable.created_at) if spammable.created_at
pb.updated_at = convert_to_pb_timestamp(spammable.updated_at) if spammable.updated_at
pb.action = ACTION_MAPPING.fetch(context.fetch(:action)) if context.has_key?(:action)
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 7f2995d2bb4..a81e1c409a1 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -19620,6 +19620,9 @@ msgid_plural "Free groups are limited to %{free_user_limit} members and the rema
msgstr[0] ""
msgstr[1] ""
+msgid "Free top-level groups will soon be limited to %{free_users_limit} users and %{free_storage_limit} of data"
+msgstr ""
+
msgid "Free trial will expire in %{days}"
msgstr ""
@@ -27646,6 +27649,9 @@ msgstr ""
msgid "Manage two-factor authentication"
msgstr ""
+msgid "Manage usage"
+msgstr ""
+
msgid "Manage your project's triggers"
msgstr ""
@@ -33763,6 +33769,9 @@ msgstr ""
msgid "Pipelines|Rebasing creates a pipeline that runs code originating from a forked project merge request. Consequently there are potential security implications, such as the exposure of CI variables."
msgstr ""
+msgid "Pipelines|Retry %{jobName} Job"
+msgstr ""
+
msgid "Pipelines|Revoke trigger"
msgstr ""
@@ -53243,6 +53252,12 @@ msgstr ""
msgid "Your top-level group is over the user limit and has been placed in a read-only state."
msgstr ""
+msgid "Your top-level group, %{group_name}, has more than %{free_users_limit} users and uses more than %{free_storage_limit} of data. After usage limits are applied to Free top-level groups, projects in this group will be in a %{read_only_link_start}read-only state%{link_end}. To ensure that your group does not become read-only, you should contact a user with the Owner role for this group to upgrade to a paid tier, or manage your usage. For more information about the upcoming usage limits, see our %{faq_link_start}FAQ%{link_end}"
+msgstr ""
+
+msgid "Your top-level group, %{group_name}, has more than %{free_users_limit} users and uses more than %{free_storage_limit} of data. After usage limits are applied to Free top-level groups, projects in this group will be in a %{read_only_link_start}read-only state%{link_end}. To get more seats and additional storage, upgrade to a paid tier. You can also manage your usage. For more information about the upcoming usage limits, see our %{faq_link_start}FAQ%{link_end}"
+msgstr ""
+
msgid "Your update failed. You can only upload one design when dropping onto an existing design."
msgstr ""
diff --git a/spec/controllers/omniauth_callbacks_controller_spec.rb b/spec/controllers/omniauth_callbacks_controller_spec.rb
index 0f470d9344a..75bdad8b19e 100644
--- a/spec/controllers/omniauth_callbacks_controller_spec.rb
+++ b/spec/controllers/omniauth_callbacks_controller_spec.rb
@@ -513,7 +513,6 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category:
it 'denies login if sign up is enabled, but block_auto_created_users is set' do
post :saml, params: { SAMLResponse: mock_saml_response }
-
expect(flash[:alert]).to start_with 'Your account is pending approval'
end
@@ -608,6 +607,25 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category:
it { expect { post_action }.not_to raise_error }
end
+
+ context 'with a non default SAML provider' do
+ let(:user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'saml') }
+
+ controller(described_class) do
+ alias_method :saml_okta, :handle_omniauth
+ end
+
+ before do
+ allow(AuthHelper).to receive(:saml_providers).and_return([:saml, :saml_okta])
+ allow(@routes).to receive(:generate_extras).and_return(['/users/auth/saml_okta/callback', []])
+ end
+
+ it 'authenticate with SAML module' do
+ expect(@controller).to receive(:omniauth_flow).with(Gitlab::Auth::Saml).and_call_original
+ post :saml_okta, params: { SAMLResponse: mock_saml_response }
+ expect(request.env['warden']).to be_authenticated
+ end
+ end
end
describe 'enable admin mode' do
diff --git a/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml
index fffdda8e6d6..909911debf1 100644
--- a/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml
+++ b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml
@@ -5,8 +5,34 @@ stages:
include:
- local: builds.yml
rules:
- - if: '$INCLUDE_BUILDS == "false"'
+ - if: $DONT_INCLUDE_BUILDS == "true"
when: never
+ - local: builds.yml
+ rules:
+ - if: $INCLUDE_BUILDS == "true"
+ when: always
+ - local: deploys.yml
+ rules:
+ - if: $CI_COMMIT_BRANCH == "main"
+ - local: builds.yml
+ rules:
+ - exists:
+ - exception-file.md
+ when: never
+ - local: builds.yml
+ rules:
+ - exists:
+ - file.md
+ when: always
+ - local: builds.yml
+ rules:
+ - exists:
+ - file.md
+ when: null
+ - local: deploys.yml
+ rules:
+ - exists:
+ - file.md
# valid trigger:include
trigger:include accepts project and file properties:
diff --git a/spec/frontend/pipelines/components/pipelines_list/failure_widget/widget_failed_job_row_spec.js b/spec/frontend/pipelines/components/pipelines_list/failure_widget/widget_failed_job_row_spec.js
index 63f5d80e95e..dfc2806840f 100644
--- a/spec/frontend/pipelines/components/pipelines_list/failure_widget/widget_failed_job_row_spec.js
+++ b/spec/frontend/pipelines/components/pipelines_list/failure_widget/widget_failed_job_row_spec.js
@@ -1,4 +1,7 @@
+import { GlIcon, GlLink } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import CiIcon from '~/vue_shared/components/ci_icon.vue';
import WidgetFailedJobRow from '~/pipelines/components/pipelines_list/failure_widget/widget_failed_job_row.vue';
describe('WidgetFailedJobRow component', () => {
@@ -31,13 +34,107 @@ describe('WidgetFailedJobRow component', () => {
});
};
+ const findArrowIcon = () => wrapper.findComponent(GlIcon);
+ const findJobCiStatus = () => wrapper.findComponent(CiIcon);
+ const findJobId = () => wrapper.findComponent(GlLink);
+ const findHiddenJobLog = () => wrapper.findByTestId('log-is-hidden');
+ const findVisibleJobLog = () => wrapper.findByTestId('log-is-visible');
+ const findJobName = () => wrapper.findByText(defaultProps.job.name);
+ const findRow = () => wrapper.findByTestId('widget-row');
+ const findStageName = () => wrapper.findByText(defaultProps.job.stage.name);
+
describe('ui', () => {
beforeEach(() => {
createComponent();
});
it('renders the job name', () => {
- expect(wrapper.html()).toContain(defaultProps.job.name);
+ expect(findJobName().exists()).toBe(true);
+ });
+
+ it('renders the stage name', () => {
+ expect(findStageName().exists()).toBe(true);
+ });
+
+ it('renders the job id as a link', () => {
+ const jobId = getIdFromGraphQLId(defaultProps.job.id);
+
+ expect(findJobId().exists()).toBe(true);
+ expect(findJobId().text()).toContain(String(jobId));
+ });
+
+ it('renders the ci status badge', () => {
+ expect(findJobCiStatus().exists()).toBe(true);
+ });
+
+ it('renders the right arrow', () => {
+ expect(findArrowIcon().props().name).toBe('chevron-right');
+ });
+
+ it('does not renders the job lob', () => {
+ expect(findHiddenJobLog().exists()).toBe(true);
+ expect(findVisibleJobLog().exists()).toBe(false);
+ });
+ });
+
+ describe('Job log', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ describe('when clicking on the row', () => {
+ beforeEach(async () => {
+ await findRow().trigger('click');
+ });
+
+ describe('while collapsed', () => {
+ it('expands the job log', () => {
+ expect(findHiddenJobLog().exists()).toBe(false);
+ expect(findVisibleJobLog().exists()).toBe(true);
+ });
+
+ it('renders the down arrow', () => {
+ expect(findArrowIcon().props().name).toBe('chevron-down');
+ });
+
+ it('renders the received html', () => {
+ expect(findVisibleJobLog().html()).toContain(defaultProps.job.trace.htmlSummary);
+ });
+ });
+
+ describe('while expanded', () => {
+ it('collapes the job log', async () => {
+ expect(findHiddenJobLog().exists()).toBe(false);
+ expect(findVisibleJobLog().exists()).toBe(true);
+
+ await findRow().trigger('click');
+
+ expect(findHiddenJobLog().exists()).toBe(true);
+ expect(findVisibleJobLog().exists()).toBe(false);
+ });
+
+ it('renders the right arrow', async () => {
+ expect(findArrowIcon().props().name).toBe('chevron-down');
+
+ await findRow().trigger('click');
+
+ expect(findArrowIcon().props().name).toBe('chevron-right');
+ });
+ });
+ });
+
+ describe('when clicking on a link element within the row', () => {
+ it('does not expands/collapse the job log', async () => {
+ expect(findHiddenJobLog().exists()).toBe(true);
+ expect(findVisibleJobLog().exists()).toBe(false);
+ expect(findArrowIcon().props().name).toBe('chevron-right');
+
+ await findJobId().vm.$emit('click');
+
+ expect(findHiddenJobLog().exists()).toBe(true);
+ expect(findVisibleJobLog().exists()).toBe(false);
+ expect(findArrowIcon().props().name).toBe('chevron-right');
+ });
});
});
});
diff --git a/spec/frontend/vue_merge_request_widget/components/approvals/approvals_spec.js b/spec/frontend/vue_merge_request_widget/components/approvals/approvals_spec.js
index 724f9ea0346..2aed037be6f 100644
--- a/spec/frontend/vue_merge_request_widget/components/approvals/approvals_spec.js
+++ b/spec/frontend/vue_merge_request_widget/components/approvals/approvals_spec.js
@@ -243,10 +243,6 @@ describe('MRWidget approvals', () => {
it('calls service approve', () => {
expect(service.approveMergeRequest).toHaveBeenCalled();
});
-
- it('emits to eventHub', () => {
- expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
- });
});
describe('and error', () => {
@@ -297,10 +293,6 @@ describe('MRWidget approvals', () => {
it('calls service unapprove', () => {
expect(service.unapproveMergeRequest).toHaveBeenCalled();
});
-
- it('emits to eventHub', () => {
- expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
- });
});
describe('and error', () => {
diff --git a/spec/frontend/vue_merge_request_widget/mr_widget_options_spec.js b/spec/frontend/vue_merge_request_widget/mr_widget_options_spec.js
index 4161d51526f..0533471bece 100644
--- a/spec/frontend/vue_merge_request_widget/mr_widget_options_spec.js
+++ b/spec/frontend/vue_merge_request_widget/mr_widget_options_spec.js
@@ -31,6 +31,7 @@ import WidgetContainer from '~/vue_merge_request_widget/components/widget/app.vu
import StatusIcon from '~/vue_merge_request_widget/components/extensions/status_icon.vue';
import getStateQuery from '~/vue_merge_request_widget/queries/get_state.query.graphql';
import getStateSubscription from '~/vue_merge_request_widget/queries/get_state.subscription.graphql';
+import readyToMergeSubscription from '~/vue_merge_request_widget/queries/states/ready_to_merge.subscription.graphql';
import readyToMergeQuery from 'ee_else_ce/vue_merge_request_widget/queries/states/ready_to_merge.query.graphql';
import approvalsQuery from 'ee_else_ce/vue_merge_request_widget/components/approvals/queries/approvals.query.graphql';
import approvedBySubscription from 'ee_else_ce/vue_merge_request_widget/components/approvals/queries/approvals.subscription.graphql';
@@ -70,6 +71,7 @@ describe('MrWidgetOptions', () => {
let queryResponse;
let wrapper;
let mock;
+ let stateSubscription;
const COLLABORATION_MESSAGE = 'Members who can merge are allowed to add commits';
const findApprovalsWidget = () => wrapper.findComponent(Approvals);
@@ -110,6 +112,7 @@ describe('MrWidgetOptions', () => {
},
};
stateQueryHandler = jest.fn().mockResolvedValue(queryResponse);
+ stateSubscription = createMockApolloSubscription();
const mounting = fullMount ? mount : shallowMount;
const queryHandlers = [
@@ -130,6 +133,8 @@ describe('MrWidgetOptions', () => {
];
const subscriptionHandlers = [
[approvedBySubscription, () => mockedApprovalsSubscription],
+ [getStateSubscription, () => stateSubscription],
+ [readyToMergeSubscription, () => createMockApolloSubscription()],
...(options.apolloSubscriptions || []),
];
const apolloProvider = createMockApollo(queryHandlers);
@@ -1262,11 +1267,8 @@ describe('MrWidgetOptions', () => {
});
describe('when the MR is updated by observing its status', () => {
- let stateSubscription;
-
beforeEach(() => {
window.gon.features.realtimeMrStatusChange = true;
- stateSubscription = createMockApolloSubscription();
});
it("shows the Preparing widget when the MR reports it's not ready yet", async () => {
@@ -1276,9 +1278,7 @@ describe('MrWidgetOptions', () => {
state: 'opened',
detailedMergeStatus: 'PREPARING',
},
- {
- apolloSubscriptions: [[getStateSubscription, () => stateSubscription]],
- },
+ {},
{},
false,
);
@@ -1293,9 +1293,7 @@ describe('MrWidgetOptions', () => {
state: 'opened',
detailedMergeStatus: 'PREPARING',
},
- {
- apolloSubscriptions: [[getStateSubscription, () => stateSubscription]],
- },
+ {},
{},
false,
);
diff --git a/spec/graphql/graphql_triggers_spec.rb b/spec/graphql/graphql_triggers_spec.rb
index f59ce805fcd..864818351a1 100644
--- a/spec/graphql/graphql_triggers_spec.rb
+++ b/spec/graphql/graphql_triggers_spec.rb
@@ -116,20 +116,6 @@ RSpec.describe GraphqlTriggers, feature_category: :shared do
GraphqlTriggers.merge_request_merge_status_updated(merge_request)
end
-
- context 'when realtime_mr_status_change feature flag is disabled' do
- before do
- stub_feature_flags(realtime_mr_status_change: false)
- end
-
- it 'does not trigger realtime_mr_status_change subscription' do
- merge_request = build_stubbed(:merge_request)
-
- expect(GitlabSchema.subscriptions).not_to receive(:trigger)
-
- GraphqlTriggers.merge_request_merge_status_updated(merge_request)
- end
- end
end
describe '.merge_request_approval_state_updated' do
diff --git a/spec/lib/error_tracking/collector/payload_validator_spec.rb b/spec/lib/error_tracking/collector/payload_validator_spec.rb
deleted file mode 100644
index 96ad66e9b58..00000000000
--- a/spec/lib/error_tracking/collector/payload_validator_spec.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe ErrorTracking::Collector::PayloadValidator do
- let(:validator) { described_class.new }
-
- describe '#valid?' do
- RSpec.shared_examples 'valid payload' do
- specify do
- expect(validator).to be_valid(payload)
- end
- end
-
- RSpec.shared_examples 'invalid payload' do
- specify do
- expect(validator).not_to be_valid(payload)
- end
- end
-
- context 'with event fixtures' do
- where(:event_fixture) do
- Dir.glob(Rails.root.join('spec/fixtures/error_tracking/*event*.json'))
- end
-
- with_them do
- let(:payload) { Gitlab::Json.parse(File.read(event_fixture)) }
-
- it_behaves_like 'valid payload'
- end
- end
-
- context 'when empty' do
- let(:payload) { '' }
-
- it_behaves_like 'invalid payload'
- end
-
- context 'when invalid' do
- let(:payload) { { 'foo' => 'bar' } }
-
- it_behaves_like 'invalid payload'
- end
- end
-end
diff --git a/spec/lib/error_tracking/collector/sentry_auth_parser_spec.rb b/spec/lib/error_tracking/collector/sentry_auth_parser_spec.rb
deleted file mode 100644
index 0e4bba04baa..00000000000
--- a/spec/lib/error_tracking/collector/sentry_auth_parser_spec.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe ErrorTracking::Collector::SentryAuthParser do
- describe '.parse' do
- let(:headers) { { 'X-Sentry-Auth' => "Sentry sentry_key=glet_1fedb514e17f4b958435093deb02048c" } }
- let(:request) { instance_double('ActionDispatch::Request', headers: headers) }
-
- subject { described_class.parse(request) }
-
- context 'with empty headers' do
- let(:headers) { {} }
-
- it 'fails with exception' do
- expect { subject }.to raise_error(StandardError)
- end
- end
-
- context 'with missing sentry_key' do
- let(:headers) { { 'X-Sentry-Auth' => "Sentry foo=bar" } }
-
- it 'returns empty value for public_key' do
- expect(subject[:public_key]).to be_nil
- end
- end
-
- it 'returns correct value for public_key' do
- expect(subject[:public_key]).to eq('glet_1fedb514e17f4b958435093deb02048c')
- end
- end
-end
diff --git a/spec/lib/error_tracking/collector/sentry_request_parser_spec.rb b/spec/lib/error_tracking/collector/sentry_request_parser_spec.rb
deleted file mode 100644
index e86ee67c129..00000000000
--- a/spec/lib/error_tracking/collector/sentry_request_parser_spec.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe ErrorTracking::Collector::SentryRequestParser do
- describe '.parse' do
- let_it_be(:raw_event) { fixture_file('error_tracking/event.txt') }
- let_it_be(:parsed_event) { Gitlab::Json.parse(fixture_file('error_tracking/parsed_event.json')) }
-
- let(:body) { raw_event }
- let(:headers) { { 'Content-Encoding' => '' } }
- let(:request) { instance_double('ActionDispatch::Request', headers: headers, body: StringIO.new(body)) }
-
- subject { described_class.parse(request) }
-
- RSpec.shared_examples 'valid parser' do
- it 'returns a valid hash' do
- parsed_request = subject
-
- expect(parsed_request[:request_type]).to eq('event')
- expect(parsed_request[:event]).to eq(parsed_event)
- end
- end
-
- context 'with empty body content' do
- let(:body) { '' }
-
- it 'fails with exception' do
- expect { subject }.to raise_error(StandardError)
- end
- end
-
- context 'with plain text sentry request' do
- it_behaves_like 'valid parser'
- end
- end
-end
diff --git a/spec/lib/gitlab/auth/saml/config_spec.rb b/spec/lib/gitlab/auth/saml/config_spec.rb
index 12f5da48873..d657622c9f2 100644
--- a/spec/lib/gitlab/auth/saml/config_spec.rb
+++ b/spec/lib/gitlab/auth/saml/config_spec.rb
@@ -16,4 +16,30 @@ RSpec.describe Gitlab::Auth::Saml::Config do
it { is_expected.to eq(true) }
end
end
+
+ describe '#external_groups' do
+ let(:config_1) { described_class.new('saml1') }
+
+ let(:config_2) { described_class.new('saml2') }
+
+ before do
+ saml1_config = ActiveSupport::InheritableOptions.new(name: 'saml1', label: 'saml1', args: {
+ 'strategy_class' => 'OmniAuth::Strategies::SAML'
+ })
+
+ saml2_config = ActiveSupport::InheritableOptions.new(name: 'saml2',
+ external_groups: ['FreeLancers'],
+ label: 'saml2',
+ args: {
+ 'strategy_class' => 'OmniAuth::Strategies::SAML'
+ })
+
+ stub_omniauth_setting(enabled: true, auto_link_saml_user: true, providers: [saml1_config, saml2_config])
+ end
+
+ it "lists groups" do
+ expect(config_1.external_groups).to be_nil
+ expect(config_2.external_groups).to be_eql(['FreeLancers'])
+ end
+ end
end
diff --git a/spec/lib/gitlab/ci/config/external/rules_spec.rb b/spec/lib/gitlab/ci/config/external/rules_spec.rb
index 3cb9dedbefe..1ba5caa1d4b 100644
--- a/spec/lib/gitlab/ci/config/external/rules_spec.rb
+++ b/spec/lib/gitlab/ci/config/external/rules_spec.rb
@@ -80,6 +80,20 @@ RSpec.describe Gitlab::Ci::Config::External::Rules, feature_category: :pipeline_
end
end
+ context 'with when: always' do
+ let(:rule_hashes) { [{ if: '$MY_VAR == "hello"', when: 'always' }] }
+
+ it_behaves_like 'when there is a rule with if'
+
+ context 'when FF `ci_support_include_rules_when_never` is disabled' do
+ before do
+ stub_feature_flags(ci_support_include_rules_when_never: false)
+ end
+
+ it_behaves_like 'when there is a rule with if'
+ end
+ end
+
context 'with when: <invalid string>' do
let(:rule_hashes) { [{ if: '$MY_VAR == "hello"', when: 'on_success' }] }
@@ -111,6 +125,20 @@ RSpec.describe Gitlab::Ci::Config::External::Rules, feature_category: :pipeline_
end
end
+ context 'with when: always' do
+ let(:rule_hashes) { [{ exists: 'Dockerfile', when: 'always' }] }
+
+ it_behaves_like 'when there is a rule with exists'
+
+ context 'when FF `ci_support_include_rules_when_never` is disabled' do
+ before do
+ stub_feature_flags(ci_support_include_rules_when_never: false)
+ end
+
+ it_behaves_like 'when there is a rule with exists'
+ end
+ end
+
context 'with when: <invalid string>' do
let(:rule_hashes) { [{ exists: 'Dockerfile', when: 'on_success' }] }
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index 23f5c61d335..78a2470b808 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -41,8 +41,8 @@ RSpec.describe Gitlab::Git::Repository, feature_category: :source_code_managemen
end
it 'gets the branch name from GitalyClient' do
- expect_any_instance_of(Gitlab::GitalyClient::RefService).to receive(:default_branch_name)
- repository.root_ref
+ expect_any_instance_of(Gitlab::GitalyClient::RefService).to receive(:default_branch_name).with(head_only: true)
+ repository.root_ref(head_only: true)
end
it_behaves_like 'wrapping gRPC errors', Gitlab::GitalyClient::RefService, :default_branch_name do
diff --git a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
index 89ac0c119bf..fe04ad36e9a 100644
--- a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
@@ -138,9 +138,11 @@ RSpec.describe Gitlab::GitalyClient::RefService, feature_category: :gitaly do
expect_any_instance_of(Gitaly::RefService::Stub)
.to receive(:find_default_branch_name)
.with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
- .and_return(double(name: 'foo'))
+ .and_return(double(name: 'refs/heads/main'))
- client.default_branch_name
+ response = client.default_branch_name
+
+ expect(response).to eq('main')
end
end
diff --git a/spec/lib/gitlab/spamcheck/client_spec.rb b/spec/lib/gitlab/spamcheck/client_spec.rb
index 57ce6334c1c..080c2803ddd 100644
--- a/spec/lib/gitlab/spamcheck/client_spec.rb
+++ b/spec/lib/gitlab/spamcheck/client_spec.rb
@@ -106,8 +106,8 @@ RSpec.describe Gitlab::Spamcheck::Client, feature_category: :instance_resiliency
let_it_be(:generic_updated_at) { issue.updated_at }
before do
- allow(generic_spammable.class).to receive(:name).and_return('GenericSpam')
allow(generic_spammable).to receive_messages(
+ spammable_entity_type: 'generic',
spammable_text: 'generic spam',
created_at: generic_created_at,
updated_at: generic_updated_at,
@@ -152,7 +152,7 @@ RSpec.describe Gitlab::Spamcheck::Client, feature_category: :instance_resiliency
generic_pb, _ = described_class.new.send(:build_protobuf, spammable: generic_spammable, user: user, context: cxt, extra_features: {})
expect(generic_pb.text).to eq 'generic spam'
- expect(generic_pb.type).to eq 'GenericSpam'
+ expect(generic_pb.type).to eq 'generic'
expect(generic_pb.created_at).to eq timestamp_to_protobuf_timestamp(generic_created_at)
expect(generic_pb.updated_at).to eq timestamp_to_protobuf_timestamp(generic_updated_at)
expect(generic_pb.action).to be ::Spamcheck::Action.lookup(::Spamcheck::Action::CREATE)
diff --git a/spec/models/concerns/spammable_spec.rb b/spec/models/concerns/spammable_spec.rb
index a18a4b067dd..8a2fa6675e5 100644
--- a/spec/models/concerns/spammable_spec.rb
+++ b/spec/models/concerns/spammable_spec.rb
@@ -97,6 +97,20 @@ RSpec.describe Spammable, feature_category: :instance_resiliency do
.to match_array /Your #{subject.class.model_name.human.downcase} has been recognized as spam./
end
end
+
+ context 'when the spammable model is a Note' do
+ subject do
+ Note.new.tap do |m|
+ m.spam!
+ m.invalidate_if_spam
+ end
+ end
+
+ it 'has an error related to spam on the model' do
+ expect(subject.errors.messages[:base])
+ .to match_array /Your comment has been recognized as spam./
+ end
+ end
end
context 'when the model needs recaptcha' do
diff --git a/spec/models/packages/nuget/metadatum_spec.rb b/spec/models/packages/nuget/metadatum_spec.rb
index 6c652f78849..4b02353d6e8 100644
--- a/spec/models/packages/nuget/metadatum_spec.rb
+++ b/spec/models/packages/nuget/metadatum_spec.rb
@@ -21,6 +21,7 @@ RSpec.describe Packages::Nuget::Metadatum, type: :model, feature_category: :pack
it { is_expected.to allow_value('https://sandbox.com').for(url) }
it { is_expected.not_to allow_value('123').for(url) }
it { is_expected.not_to allow_value('sandbox.com').for(url) }
+ it { is_expected.to validate_length_of(url).is_at_most(described_class::MAX_URL_LENGTH) }
end
describe '#ensure_nuget_package_type' do
diff --git a/spec/requests/api/issues/post_projects_issues_spec.rb b/spec/requests/api/issues/post_projects_issues_spec.rb
index 5a15a0b6dad..1cd20680afb 100644
--- a/spec/requests/api/issues/post_projects_issues_spec.rb
+++ b/spec/requests/api/issues/post_projects_issues_spec.rb
@@ -416,11 +416,12 @@ RSpec.describe API::Issues, :aggregate_failures, feature_category: :team_plannin
end
before do
- expect_next_instance_of(Spam::SpamActionService) do |spam_service|
- expect(spam_service).to receive_messages(check_for_spam?: true)
+ expect_next_instance_of(Issue) do |instance|
+ expect(instance).to receive(:check_for_spam).with(user: user, action: :create).and_call_original
end
+
expect_next_instance_of(Spam::AkismetService) do |akismet_service|
- expect(akismet_service).to receive_messages(spam?: true)
+ expect(akismet_service).to receive(:spam?).and_return(true)
end
end
diff --git a/spec/services/error_tracking/collect_error_service_spec.rb b/spec/services/error_tracking/collect_error_service_spec.rb
deleted file mode 100644
index 3ff753e8c65..00000000000
--- a/spec/services/error_tracking/collect_error_service_spec.rb
+++ /dev/null
@@ -1,140 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe ErrorTracking::CollectErrorService, feature_category: :error_tracking do
- let_it_be(:project) { create(:project) }
-
- let(:parsed_event_file) { 'error_tracking/parsed_event.json' }
- let(:parsed_event) { parse_valid_event(parsed_event_file) }
-
- subject { described_class.new(project, nil, event: parsed_event) }
-
- describe '#execute' do
- it 'creates Error and creates ErrorEvent' do
- expect { subject.execute }
- .to change { ErrorTracking::Error.count }.by(1)
- .and change { ErrorTracking::ErrorEvent.count }.by(1)
- end
-
- it 'updates Error and created ErrorEvent on second hit' do
- subject.execute
-
- expect { subject.execute }.not_to change { ErrorTracking::Error.count }
- expect { subject.execute }.to change { ErrorTracking::ErrorEvent.count }.by(1)
- end
-
- it 'has correct values set' do
- subject.execute
-
- event = ErrorTracking::ErrorEvent.last
- error = event.error
-
- expect(error.name).to eq 'ActionView::MissingTemplate'
- expect(error.description).to start_with 'Missing template posts/error2'
- expect(error.actor).to eq 'PostsController#error2'
- expect(error.platform).to eq 'ruby'
- expect(error.last_seen_at).to eq '2021-07-08T12:59:16Z'
-
- expect(event.description).to start_with 'Missing template posts/error2'
- expect(event.occurred_at).to eq '2021-07-08T12:59:16Z'
- expect(event.level).to eq 'error'
- expect(event.environment).to eq 'development'
- expect(event.payload).to eq parsed_event
- end
-
- context 'python sdk event' do
- let(:parsed_event_file) { 'error_tracking/python_event.json' }
-
- it 'creates a valid event' do
- expect { subject.execute }.to change { ErrorTracking::ErrorEvent.count }.by(1)
- end
- end
-
- context 'with unusual payload' do
- let(:event) { ErrorTracking::ErrorEvent.last! }
-
- context 'when transaction is missing' do
- it 'builds actor from stacktrace' do
- parsed_event.delete('transaction')
-
- subject.execute
-
- expect(event.error.actor).to eq 'find()'
- end
- end
-
- context 'when transaction is an empty string' do \
- it 'builds actor from stacktrace' do
- parsed_event['transaction'] = ''
-
- subject.execute
-
- expect(event.error.actor).to eq 'find()'
- end
- end
-
- context 'when timestamp is numeric' do
- it 'parses timestamp' do
- parsed_event['timestamp'] = '1631015580.50'
-
- subject.execute
-
- expect(event.occurred_at).to eq '2021-09-07T11:53:00.5'
- end
- end
- end
-
- context 'go payload' do
- let(:parsed_event_file) { 'error_tracking/go_parsed_event.json' }
-
- it 'has correct values set' do
- subject.execute
-
- event = ErrorTracking::ErrorEvent.last
- error = event.error
-
- expect(error.name).to eq '*errors.errorString'
- expect(error.description).to start_with 'Hello world'
- expect(error.platform).to eq 'go'
-
- expect(event.description).to start_with 'Hello world'
- expect(event.level).to eq 'error'
- expect(event.environment).to eq 'Accumulate'
- expect(event.payload).to eq parsed_event
- end
-
- context 'with two exceptions' do
- let(:parsed_event_file) { 'error_tracking/go_two_exception_event.json' }
-
- it 'reports using second exception', :aggregate_failures do
- subject.execute
-
- event = ErrorTracking::ErrorEvent.last
- error = event.error
-
- expect(error.name).to eq '*url.Error'
- expect(error.description).to eq(%(Get \"foobar\": unsupported protocol scheme \"\"))
- expect(error.platform).to eq 'go'
- expect(error.actor).to eq('main(main)')
-
- expect(event.description).to eq(%(Get \"foobar\": unsupported protocol scheme \"\"))
- expect(event.payload).to eq parsed_event
- end
- end
- end
- end
-
- private
-
- def parse_valid_event(parsed_event_file)
- parsed_event = Gitlab::Json.parse(fixture_file(parsed_event_file))
-
- validator = ErrorTracking::Collector::PayloadValidator.new
- # This a precondition for all specs to verify that
- # submitted JSON payload is valid.
- expect(validator).to be_valid(parsed_event)
-
- parsed_event
- end
-end
diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb
index cbedf3263d8..3dfc9571c9c 100644
--- a/spec/services/issues/create_service_spec.rb
+++ b/spec/services/issues/create_service_spec.rb
@@ -833,16 +833,9 @@ RSpec.describe Issues::CreateService, feature_category: :team_planning do
described_class.new(container: project, current_user: user, params: params, perform_spam_check: perform_spam_check)
end
- it 'executes SpamActionService' do
- expect_next_instance_of(
- Spam::SpamActionService,
- {
- spammable: kind_of(Issue),
- user: an_instance_of(User),
- action: :create
- }
- ) do |instance|
- expect(instance).to receive(:execute)
+ it 'checks for spam' do
+ expect_next_instance_of(Issue) do |instance|
+ expect(instance).to receive(:check_for_spam).with(user: user, action: :create)
end
subject.execute
@@ -852,7 +845,9 @@ RSpec.describe Issues::CreateService, feature_category: :team_planning do
let(:perform_spam_check) { false }
it 'does not execute the SpamActionService' do
- expect(Spam::SpamActionService).not_to receive(:new)
+ expect_next_instance_of(Issue) do |instance|
+ expect(instance).not_to receive(:check_for_spam)
+ end
subject.execute
end
diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb
index ea4e582b239..a5151925c52 100644
--- a/spec/services/issues/update_service_spec.rb
+++ b/spec/services/issues/update_service_spec.rb
@@ -901,7 +901,7 @@ RSpec.describe Issues::UpdateService, :mailer, feature_category: :team_planning
}
service = described_class.new(container: project, current_user: user, params: params)
- expect(Spam::SpamActionService).not_to receive(:new)
+ expect(issue).not_to receive(:check_for_spam)
service.execute(issue)
end
diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb
index b5926c09153..51b1bed1dd3 100644
--- a/spec/services/merge_requests/create_service_spec.rb
+++ b/spec/services/merge_requests/create_service_spec.rb
@@ -68,8 +68,8 @@ RSpec.describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state, f
describe 'checking for spam' do
it 'checks for spam' do
- expect_next_instance_of(Spam::SpamActionService, spammable: instance_of(MergeRequest), user: user, action: :create) do |instance|
- expect(instance).to receive(:execute)
+ expect_next_instance_of(MergeRequest) do |instance|
+ expect(instance).to receive(:check_for_spam).with(user: user, action: :create)
end
service.execute
diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb
index 5d703cd5969..52999b5a1ea 100644
--- a/spec/services/merge_requests/update_service_spec.rb
+++ b/spec/services/merge_requests/update_service_spec.rb
@@ -428,9 +428,7 @@ RSpec.describe MergeRequests::UpdateService, :mailer, feature_category: :code_re
describe 'checking for spam' do
it 'checks for spam' do
- expect_next_instance_of(Spam::SpamActionService, spammable: merge_request, user: user, action: :update) do |instance|
- expect(instance).to receive(:execute)
- end
+ expect(merge_request).to receive(:check_for_spam).with(user: user, action: :update)
update_merge_request(opts)
end
diff --git a/spec/services/packages/nuget/update_package_from_metadata_service_spec.rb b/spec/services/packages/nuget/update_package_from_metadata_service_spec.rb
index aebd5457075..fa7d994c13c 100644
--- a/spec/services/packages/nuget/update_package_from_metadata_service_spec.rb
+++ b/spec/services/packages/nuget/update_package_from_metadata_service_spec.rb
@@ -12,13 +12,15 @@ RSpec.describe Packages::Nuget::UpdatePackageFromMetadataService, :clean_gitlab_
let(:package_version) { '1.0.0' }
let(:package_file_name) { 'dummyproject.dummypackage.1.0.0.nupkg' }
- shared_examples 'raising an' do |error_class|
+ shared_examples 'raising an' do |error_class, with_message:|
it "raises an #{error_class}" do
- expect { subject }.to raise_error(error_class)
+ expect { subject }.to raise_error(error_class, with_message)
end
end
describe '#execute' do
+ using RSpec::Parameterized::TableSyntax
+
subject { service.execute }
shared_examples 'taking the lease' do
@@ -168,24 +170,24 @@ RSpec.describe Packages::Nuget::UpdatePackageFromMetadataService, :clean_gitlab_
context 'with too long url' do
let_it_be(:too_long_url) { "http://localhost/#{'bananas' * 50}" }
- let(:metadata) { { package_name: package_name, package_version: package_version, license_url: too_long_url } }
+ let(:metadata) { { package_name: package_name, package_version: package_version, authors: 'Author Test', description: 'Description Test', license_url: too_long_url } }
before do
allow(service).to receive(:metadata).and_return(metadata)
end
- it_behaves_like 'raising an', described_class::InvalidMetadataError
+ it_behaves_like 'raising an', described_class::InvalidMetadataError, with_message: /Validation failed: License url is too long/
end
context 'without authors or description' do
%i[authors description].each do |property|
- let(:metadata) { { package_name: package_name, package_version: package_version, license_url: 'http://localhost/', property => nil } }
+ let(:metadata) { { package_name: package_name, package_version: package_version, property => nil } }
before do
allow(service).to receive(:metadata).and_return(metadata)
end
- it_behaves_like 'raising an', described_class::InvalidMetadataError
+ it_behaves_like 'raising an', described_class::InvalidMetadataError, with_message: described_class::INVALID_METADATA_ERROR_MESSAGE
end
end
end
@@ -226,7 +228,7 @@ RSpec.describe Packages::Nuget::UpdatePackageFromMetadataService, :clean_gitlab_
end
end
- it_behaves_like 'raising an', ::Packages::Nuget::MetadataExtractionService::ExtractionError
+ it_behaves_like 'raising an', ::Packages::Nuget::MetadataExtractionService::ExtractionError, with_message: 'nuspec file not found'
end
context 'with a symbol package' do
@@ -236,17 +238,13 @@ RSpec.describe Packages::Nuget::UpdatePackageFromMetadataService, :clean_gitlab_
context 'with no existing package' do
let(:package_id) { package.id }
- it_behaves_like 'raising an', described_class::InvalidMetadataError
+ it_behaves_like 'raising an', described_class::InvalidMetadataError, with_message: described_class::MISSING_MATCHING_PACKAGE_ERROR_MESSAGE
end
context 'with existing package' do
let!(:existing_package) { create(:nuget_package, project: package.project, name: package_name, version: package_version) }
let(:package_id) { existing_package.id }
- before do
- allow(service).to receive(:metadata).and_return(service.send(:metadata).merge(authors: 'Author Test'))
- end
-
it 'link existing package and updates package file', :aggregate_failures do
expect(service).to receive(:try_obtain_lease).and_call_original
expect(::Packages::Nuget::SyncMetadatumService).not_to receive(:new)
@@ -269,41 +267,41 @@ RSpec.describe Packages::Nuget::UpdatePackageFromMetadataService, :clean_gitlab_
end
context 'with an invalid package name' do
- invalid_names = [
- '',
- 'My/package',
- '../../../my_package',
- '%2e%2e%2fmy_package'
- ]
-
- invalid_names.each do |invalid_name|
- context "with #{invalid_name}" do
- before do
- allow(service).to receive(:package_name).and_return(invalid_name)
- end
+ invalid_name_error_msg = 'Validation failed: Name is invalid'
+
+ where(:invalid_name, :error_message) do
+ '' | described_class::INVALID_METADATA_ERROR_MESSAGE
+ 'My/package' | invalid_name_error_msg
+ '../../../my_package' | invalid_name_error_msg
+ '%2e%2e%2fmy_package' | invalid_name_error_msg
+ end
- it_behaves_like 'raising an', described_class::InvalidMetadataError
+ with_them do
+ before do
+ allow(service).to receive(:package_name).and_return(invalid_name)
end
+
+ it_behaves_like 'raising an', described_class::InvalidMetadataError, with_message: params[:error_message]
end
end
context 'with an invalid package version' do
- invalid_versions = [
- '',
- '555',
- '1./2.3',
- '../../../../../1.2.3',
- '%2e%2e%2f1.2.3'
- ]
-
- invalid_versions.each do |invalid_version|
- context "with #{invalid_version}" do
- before do
- allow(service).to receive(:package_version).and_return(invalid_version)
- end
+ invalid_version_error_msg = 'Validation failed: Version is invalid'
+
+ where(:invalid_version, :error_message) do
+ '' | described_class::INVALID_METADATA_ERROR_MESSAGE
+ '555' | invalid_version_error_msg
+ '1./2.3' | invalid_version_error_msg
+ '../../../../../1.2.3' | invalid_version_error_msg
+ '%2e%2e%2f1.2.3' | invalid_version_error_msg
+ end
- it_behaves_like 'raising an', described_class::InvalidMetadataError
+ with_them do
+ before do
+ allow(service).to receive(:package_version).and_return(invalid_version)
end
+
+ it_behaves_like 'raising an', described_class::InvalidMetadataError, with_message: params[:error_message]
end
end
end
diff --git a/spec/services/work_items/create_service_spec.rb b/spec/services/work_items/create_service_spec.rb
index ec775ba36f3..b64d9a29fbf 100644
--- a/spec/services/work_items/create_service_spec.rb
+++ b/spec/services/work_items/create_service_spec.rb
@@ -149,16 +149,9 @@ RSpec.describe WorkItems::CreateService, feature_category: :team_planning do
context 'checking spam' do
let(:perform_spam_check) { true }
- it 'executes SpamActionService' do
- expect_next_instance_of(
- Spam::SpamActionService,
- {
- spammable: kind_of(WorkItem),
- user: an_instance_of(User),
- action: :create
- }
- ) do |instance|
- expect(instance).to receive(:execute)
+ it 'checks for spam' do
+ expect_next_instance_of(WorkItem) do |instance|
+ expect(instance).to receive(:check_for_spam).with(user: current_user, action: :create)
end
service_result
@@ -167,8 +160,10 @@ RSpec.describe WorkItems::CreateService, feature_category: :team_planning do
context 'when `perform_spam_check` is set to `false`' do
let(:perform_spam_check) { false }
- it 'does not execute the SpamActionService' do
- expect(Spam::SpamActionService).not_to receive(:new)
+ it 'does not check for spam' do
+ expect_next_instance_of(WorkItem) do |instance|
+ expect(instance).not_to receive(:check_for_spam)
+ end
service_result
end
diff --git a/spec/support/helpers/login_helpers.rb b/spec/support/helpers/login_helpers.rb
index acd654bc96d..abe21d2b74c 100644
--- a/spec/support/helpers/login_helpers.rb
+++ b/spec/support/helpers/login_helpers.rb
@@ -241,14 +241,9 @@ module LoginHelpers
def stub_omniauth_saml_config(context: Rails.application, **messages)
set_devise_mapping(context: context)
- routes = Rails.application.routes
- routes.disable_clear_and_finalize = true
- routes.formatter.clear
- routes.draw do
- post '/users/auth/saml' => 'omniauth_callbacks#saml'
- end
saml_config = messages.key?(:providers) ? messages[:providers].first : mock_saml_config
- allow(Gitlab::Auth::OAuth::Provider).to receive_messages(providers: [:saml], config_for: saml_config)
+ prepare_provider_route(saml_config.name)
+ allow(Gitlab::Auth::OAuth::Provider).to receive_messages(providers: [saml_config.name], config_for: saml_config)
stub_omniauth_setting(messages)
stub_saml_authorize_path_helpers
end
@@ -268,11 +263,15 @@ module LoginHelpers
end
def stub_basic_saml_config
- allow(Gitlab::Auth::Saml::Config).to receive_messages({ options: { name: 'saml', args: {} } })
+ allow_next_instance_of(Gitlab::Auth::Saml::Config) do |config|
+ allow(config).to receive_messages({ options: { name: 'saml', args: {} } })
+ end
end
def stub_saml_group_config(groups)
- allow(Gitlab::Auth::Saml::Config).to receive_messages({ options: { name: 'saml', groups_attribute: 'groups', external_groups: groups, args: {} } })
+ allow_next_instance_of(Gitlab::Auth::Saml::Config) do |config|
+ allow(config).to receive_messages({ options: { name: 'saml', groups_attribute: 'groups', external_groups: groups, args: {} } })
+ end
end
end
diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml
index d001ff8e85e..4168820a2b3 100644
--- a/spec/support/rspec_order_todo.yml
+++ b/spec/support/rspec_order_todo.yml
@@ -5465,9 +5465,6 @@
- './spec/lib/csv_builder_spec.rb'
- './spec/lib/csv_builders/stream_spec.rb'
- './spec/lib/declarative_enum_spec.rb'
-- './spec/lib/error_tracking/collector/payload_validator_spec.rb'
-- './spec/lib/error_tracking/collector/sentry_auth_parser_spec.rb'
-- './spec/lib/error_tracking/collector/sentry_request_parser_spec.rb'
- './spec/lib/error_tracking/stacktrace_builder_spec.rb'
- './spec/lib/event_filter_spec.rb'
- './spec/lib/expand_variables_spec.rb'
@@ -9129,7 +9126,6 @@
- './spec/services/environments/schedule_to_delete_review_apps_service_spec.rb'
- './spec/services/environments/stop_service_spec.rb'
- './spec/services/error_tracking/base_service_spec.rb'
-- './spec/services/error_tracking/collect_error_service_spec.rb'
- './spec/services/error_tracking/issue_details_service_spec.rb'
- './spec/services/error_tracking/issue_latest_event_service_spec.rb'
- './spec/services/error_tracking/issue_update_service_spec.rb'
diff --git a/spec/support/shared_examples/models/wiki_shared_examples.rb b/spec/support/shared_examples/models/wiki_shared_examples.rb
index 017e51ecd24..a0187252108 100644
--- a/spec/support/shared_examples/models/wiki_shared_examples.rb
+++ b/spec/support/shared_examples/models/wiki_shared_examples.rb
@@ -939,7 +939,6 @@ RSpec.shared_examples 'wiki model' do
end
describe '#create_wiki_repository' do
- let(:head_path) { Gitlab::GitalyClient::StorageSettings.allow_disk_access { Rails.root.join(TestEnv.repos_path, "#{wiki.disk_path}.git", 'HEAD') } }
let(:default_branch) { 'foo' }
before do
@@ -956,7 +955,7 @@ RSpec.shared_examples 'wiki model' do
subject
- expect(File.read(head_path).squish).to eq "ref: refs/heads/#{default_branch}"
+ expect(wiki.repository.raw.root_ref(head_only: true)).to eq default_branch
end
end
@@ -968,7 +967,7 @@ RSpec.shared_examples 'wiki model' do
subject
- expect(File.read(head_path).squish).to eq "ref: refs/heads/#{default_branch}"
+ expect(wiki.repository.raw.root_ref(head_only: true)).to eq default_branch
end
end
end