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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-12-06 21:08:22 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-12-06 21:08:22 +0300
commit5a73318262aab6ab952f2b7205b3674ea1f20053 (patch)
treee53191adbc529ce23ca08a73e1235c7b6fb6ced5
parent552877c4d1c535f529be13862692a8fe826a72a2 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--app/assets/javascripts/editor/components/source_editor_toolbar_button.vue8
-rw-r--r--app/assets/javascripts/editor/extensions/source_editor_markdown_livepreview_ext.js3
-rw-r--r--app/models/ci/build_need.rb3
-rw-r--r--app/models/ci/processable.rb2
-rw-r--r--app/models/concerns/ci/partitionable.rb1
-rw-r--r--app/workers/all_queues.yml9
-rw-r--r--app/workers/gitlab/github_gists_import/import_gist_worker.rb75
-rw-r--r--config/feature_flags/development/display_merge_conflicts_in_diff.yml2
-rw-r--r--config/feature_flags/development/rate_limit_gitlab_shell_by_ip.yml2
-rw-r--r--config/sidekiq_queues.yml2
-rw-r--r--db/migrate/20221122141046_add_allow_pipeline_trigger_approve_deployment_to_project_settings.rb9
-rw-r--r--db/schema_migrations/202211221410461
-rw-r--r--db/structure.sql1
-rw-r--r--doc/.vale/gitlab/spelling-exceptions.txt15
-rw-r--r--doc/administration/geo/replication/version_specific_upgrades.md2
-rw-r--r--doc/administration/img/impersonated_audit_events_v15_7.pngbin37162 -> 11909 bytes
-rw-r--r--doc/administration/job_artifacts.md2
-rw-r--r--doc/administration/package_information/index.md6
-rw-r--r--doc/administration/pages/index.md6
-rw-r--r--doc/api/applications.md2
-rw-r--r--doc/api/epic_issues.md2
-rw-r--r--doc/api/index.md2
-rw-r--r--doc/api/integrations.md16
-rw-r--r--doc/api/projects.md4
-rw-r--r--doc/architecture/blueprints/ci_data_decay/pipeline_partitioning.md2
-rw-r--r--doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md18
-rw-r--r--doc/architecture/blueprints/container_registry_metadata_database/index.md4
-rw-r--r--doc/ci/ci_cd_for_external_repos/bitbucket_integration.md2
-rw-r--r--doc/ci/environments/index.md2
-rw-r--r--doc/ci/examples/authenticating-with-hashicorp-vault/index.md10
-rw-r--r--doc/ci/large_repositories/index.md2
-rw-r--r--doc/ci/runners/configure_runners.md12
-rw-r--r--doc/ci/secrets/index.md2
-rw-r--r--doc/development/cicd/pipeline_wizard.md2
-rw-r--r--doc/development/contributing/style_guides.md2
-rw-r--r--doc/development/database/creating_enums.md2
-rw-r--r--doc/development/database/efficient_in_operator_queries.md2
-rw-r--r--doc/development/database/query_recorder.md2
-rw-r--r--doc/development/documentation/styleguide/index.md4
-rw-r--r--doc/development/ee_features.md19
-rw-r--r--doc/development/elasticsearch.md2
-rw-r--r--doc/development/fe_guide/dark_mode.md4
-rw-r--r--doc/development/fe_guide/haml.md12
-rw-r--r--doc/development/fe_guide/view_component.md2
-rw-r--r--doc/development/fe_guide/vue3_migration.md4
-rw-r--r--doc/development/file_storage.md2
-rw-r--r--doc/development/geo.md2
-rw-r--r--doc/development/licensing.md2
-rw-r--r--doc/development/merge_request_performance_guidelines.md6
-rw-r--r--doc/development/migration_style_guide.md2
-rw-r--r--doc/development/packages/dependency_proxy.md2
-rw-r--r--doc/development/performance.md2
-rw-r--r--doc/development/pipelines/internals.md6
-rw-r--r--doc/development/product_qualified_lead_guide/index.md20
-rw-r--r--doc/development/profiling.md4
-rw-r--r--doc/development/redis/new_redis_instance.md16
-rw-r--r--doc/development/sec/analyzer_development_guide.md2
-rw-r--r--doc/development/service_ping/implement.md8
-rw-r--r--doc/development/sidekiq/idempotent_jobs.md2
-rw-r--r--doc/development/snowplow/schemas.md4
-rw-r--r--doc/development/snowplow/troubleshooting.md2
-rw-r--r--doc/development/testing_guide/best_practices.md2
-rw-r--r--doc/development/testing_guide/end_to_end/rspec_metadata_tests.md2
-rw-r--r--doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md4
-rw-r--r--doc/operations/incident_management/incidents.md11
-rw-r--r--doc/operations/incident_management/integrations.md2
-rw-r--r--doc/operations/incident_management/paging.md11
-rw-r--r--doc/operations/incident_management/slack.md117
-rw-r--r--doc/operations/metrics/dashboards/panel_types.md28
-rw-r--r--doc/operations/metrics/dashboards/variables.md4
-rw-r--r--doc/operations/metrics/dashboards/yaml.md2
-rw-r--r--doc/raketasks/backup_restore.md2
-rw-r--r--doc/subscriptions/img/add-license.pngbin36742 -> 16222 bytes
-rw-r--r--doc/topics/awesome_co.md2
-rw-r--r--doc/update/index.md22
-rw-r--r--doc/user/application_security/dast/checks/16.3.md2
-rw-r--r--doc/user/compliance/license_compliance/index.md2
-rw-r--r--doc/user/infrastructure/iac/terraform_template_recipes.md2
-rw-r--r--doc/user/packages/helm_repository/index.md2
-rw-r--r--doc/user/packages/terraform_module_registry/index.md2
-rw-r--r--doc/user/project/import/bitbucket.md2
-rw-r--r--doc/user/project/import/github.md2
-rw-r--r--doc/user/project/integrations/mlflow_client.md4
-rw-r--r--doc/user/project/merge_requests/changes.md11
-rw-r--r--doc/user/project/merge_requests/reviews/data_usage.md2
-rw-r--r--doc/user/project/merge_requests/reviews/index.md2
-rw-r--r--doc/user/project/ml/experiment_tracking/img/candidate_v15_7.pngbin106770 -> 35164 bytes
-rw-r--r--doc/user/project/ml/experiment_tracking/img/candidates_v15_7.pngbin153995 -> 47800 bytes
-rw-r--r--doc/user/project/ml/experiment_tracking/img/experiments_v15_7.pngbin76730 -> 23475 bytes
-rw-r--r--doc/user/project/wiki/index.md2
-rw-r--r--doc/user/search/index.md2
-rw-r--r--lib/api/award_emoji.rb2
-rw-r--r--lib/api/ci/runners.rb10
-rw-r--r--lib/api/entities/ci/runner_details.rb4
-rw-r--r--lib/api/groups.rb2
-rw-r--r--lib/api/helpers.rb4
-rw-r--r--lib/api/users.rb14
-rw-r--r--lib/api/v3/github.rb4
-rw-r--r--lib/gitlab/github_gists_import/importer/gist_importer.rb84
-rw-r--r--lib/gitlab/github_gists_import/representation/gist.rb71
-rw-r--r--lib/gitlab/memory/watchdog/configurator.rb2
-rw-r--r--lib/gitlab/memory/watchdog/sidekiq_event_reporter.rb56
-rw-r--r--lib/gitlab/sidekiq_daemon/monitor.rb6
-rw-r--r--lib/version_check.rb8
-rw-r--r--qa/qa/page/file/edit.rb4
-rwxr-xr-xscripts/review_apps/review-apps.sh11
-rw-r--r--spec/features/incidents/incident_details_spec.rb2
-rw-r--r--spec/features/milestones/user_creates_milestone_spec.rb2
-rw-r--r--spec/frontend/editor/components/source_editor_toolbar_button_spec.js19
-rw-r--r--spec/lib/gitlab/github_gists_import/importer/gist_importer_spec.rb128
-rw-r--r--spec/lib/gitlab/github_gists_import/representation/gist_spec.rb111
-rw-r--r--spec/lib/gitlab/memory/watchdog/configurator_spec.rb2
-rw-r--r--spec/lib/gitlab/memory/watchdog/sidekiq_event_reporter_spec.rb64
-rw-r--r--spec/lib/gitlab/merge_requests/message_generator_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb11
-rw-r--r--spec/lib/version_check_spec.rb41
-rw-r--r--spec/models/ci/build_need_spec.rb60
-rw-r--r--spec/models/ci/processable_spec.rb4
-rw-r--r--spec/requests/api/helpers_spec.rb2
-rw-r--r--spec/requests/api/project_attributes.yml1
-rw-r--r--spec/services/ci/create_pipeline_service/partitioning_spec.rb21
-rw-r--r--spec/support/models/ci/partitioning_testing/cascade_check.rb7
-rw-r--r--spec/workers/every_sidekiq_worker_spec.rb1
-rw-r--r--spec/workers/gitlab/github_gists_import/import_gist_worker_spec.rb94
125 files changed, 1233 insertions, 237 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 086716624be..0cac7ba6c87 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-3161435166d6fc0f951c9a926a2584a8abb3aeeb
+22722e29aa21a554ed1e729f9b23a485929ac4cf
diff --git a/app/assets/javascripts/editor/components/source_editor_toolbar_button.vue b/app/assets/javascripts/editor/components/source_editor_toolbar_button.vue
index 8c37ed1642c..e440feb5a22 100644
--- a/app/assets/javascripts/editor/components/source_editor_toolbar_button.vue
+++ b/app/assets/javascripts/editor/components/source_editor_toolbar_button.vue
@@ -31,6 +31,13 @@ export default {
return Object.entries(this.button).length > 0;
},
},
+ mounted() {
+ if (this.button.data) {
+ Object.entries(this.button.data).forEach(([attr, value]) => {
+ this.$el.dataset[attr] = value;
+ });
+ }
+ },
methods: {
clickHandler(event) {
if (this.button.onClick) {
@@ -52,7 +59,6 @@ export default {
:icon="icon"
:title="label"
:aria-label="label"
- data-qa-selector="editor_toolbar_button"
@click="clickHandler($event)"
/>
</template>
diff --git a/app/assets/javascripts/editor/extensions/source_editor_markdown_livepreview_ext.js b/app/assets/javascripts/editor/extensions/source_editor_markdown_livepreview_ext.js
index dd4a7a689d7..58ddaa94d5e 100644
--- a/app/assets/javascripts/editor/extensions/source_editor_markdown_livepreview_ext.js
+++ b/app/assets/javascripts/editor/extensions/source_editor_markdown_livepreview_ext.js
@@ -120,6 +120,9 @@ export class EditorMarkdownPreviewExtension {
category: 'primary',
selectedLabel: EXTENSION_MARKDOWN_HIDE_PREVIEW_LABEL,
onClick: () => instance.togglePreview(),
+ data: {
+ qaSelector: 'editor_toolbar_button',
+ },
},
];
instance.toolbar.addItems(this.toolbarButtons);
diff --git a/app/models/ci/build_need.rb b/app/models/ci/build_need.rb
index 98d2f8e4fc0..3fa17d6d286 100644
--- a/app/models/ci/build_need.rb
+++ b/app/models/ci/build_need.rb
@@ -2,10 +2,13 @@
module Ci
class BuildNeed < Ci::ApplicationRecord
+ include Ci::Partitionable
include BulkInsertSafe
belongs_to :build, class_name: "Ci::Processable", foreign_key: :build_id, inverse_of: :needs
+ partitionable scope: :build
+
validates :build, presence: true
validates :name, presence: true, length: { maximum: 128 }
validates :optional, inclusion: { in: [true, false] }
diff --git a/app/models/ci/processable.rb b/app/models/ci/processable.rb
index 65600858650..eb805ffae0a 100644
--- a/app/models/ci/processable.rb
+++ b/app/models/ci/processable.rb
@@ -172,7 +172,7 @@ module Ci
def needs_attributes
strong_memoize(:needs_attributes) do
- needs.map { |need| need.attributes.except('id', 'build_id', 'partition_id') }
+ needs.map { |need| need.attributes.except('id', 'build_id') }
end
end
diff --git a/app/models/concerns/ci/partitionable.rb b/app/models/concerns/ci/partitionable.rb
index 1923681b72e..6e01da2e9df 100644
--- a/app/models/concerns/ci/partitionable.rb
+++ b/app/models/concerns/ci/partitionable.rb
@@ -25,6 +25,7 @@ module Ci
PARTITIONABLE_MODELS = %w[
CommitStatus
Ci::BuildMetadata
+ Ci::BuildNeed
Ci::BuildReportResult
Ci::BuildRunnerSession
Ci::BuildTraceChunk
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index 40c74e9429f..17931152bd0 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -1038,6 +1038,15 @@
:weight: 1
:idempotent: false
:tags: []
+- :name: github_gists_importer:github_gists_import_import_gist
+ :worker_name: Gitlab::GithubGistsImport::ImportGistWorker
+ :feature_category: :importers
+ :has_external_dependencies: false
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: false
+ :tags: []
- :name: github_importer:github_import_attachments_import_issue
:worker_name: Gitlab::GithubImport::Attachments::ImportIssueWorker
:feature_category: :importers
diff --git a/app/workers/gitlab/github_gists_import/import_gist_worker.rb b/app/workers/gitlab/github_gists_import/import_gist_worker.rb
new file mode 100644
index 00000000000..7e2b3709597
--- /dev/null
+++ b/app/workers/gitlab/github_gists_import/import_gist_worker.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module GithubGistsImport
+ class ImportGistWorker # rubocop:disable Scalability/IdempotentWorker
+ include ApplicationWorker
+ include Gitlab::NotifyUponDeath
+
+ data_consistency :always
+ queue_namespace :github_gists_importer
+ feature_category :importers
+
+ sidekiq_options dead: false, retry: 5
+
+ def perform(user_id, gist_hash, notify_key)
+ gist = ::Gitlab::GithubGistsImport::Representation::Gist.from_json_hash(gist_hash)
+
+ with_logging(user_id, gist.github_identifiers) do
+ result = importer_class.new(gist, user_id).execute
+ error(user_id, result.errors, gist.github_identifiers) unless result.success?
+
+ JobWaiter.notify(notify_key, jid)
+ end
+ rescue StandardError => e
+ log_and_track_error(user_id, e, gist.github_identifiers)
+
+ raise
+ end
+
+ private
+
+ def importer_class
+ ::Gitlab::GithubGistsImport::Importer::GistImporter
+ end
+
+ def with_logging(user_id, gist_id)
+ info(user_id, 'start importer', gist_id)
+
+ yield
+
+ info(user_id, 'importer finished', gist_id)
+ end
+
+ def log_and_track_error(user_id, exception, gist_id)
+ error(user_id, exception.message, gist_id)
+
+ Gitlab::ErrorTracking.track_exception(exception,
+ import_type: :github_gists,
+ user_id: user_id
+ )
+ end
+
+ def error(user_id, error_message, gist_id)
+ attributes = {
+ user_id: user_id,
+ github_identifiers: gist_id,
+ message: 'importer failed',
+ 'error.message': error_message
+ }
+
+ Gitlab::GithubImport::Logger.error(structured_payload(attributes))
+ end
+
+ def info(user_id, message, gist_id)
+ attributes = {
+ user_id: user_id,
+ message: message,
+ github_identifiers: gist_id
+ }
+
+ Gitlab::GithubImport::Logger.info(structured_payload(attributes))
+ end
+ end
+ end
+end
diff --git a/config/feature_flags/development/display_merge_conflicts_in_diff.yml b/config/feature_flags/development/display_merge_conflicts_in_diff.yml
index 50c22b52d11..71146d9236b 100644
--- a/config/feature_flags/development/display_merge_conflicts_in_diff.yml
+++ b/config/feature_flags/development/display_merge_conflicts_in_diff.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/276918
milestone: '13.5'
type: development
group: group::code review
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/rate_limit_gitlab_shell_by_ip.yml b/config/feature_flags/development/rate_limit_gitlab_shell_by_ip.yml
index 67a465ef6d6..667c0db7ee0 100644
--- a/config/feature_flags/development/rate_limit_gitlab_shell_by_ip.yml
+++ b/config/feature_flags/development/rate_limit_gitlab_shell_by_ip.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/367998
milestone: '15.3'
type: development
group: group::source code
-default_enabled: false
+default_enabled: true
diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml
index a71dc84cbc4..ecfb0ba7798 100644
--- a/config/sidekiq_queues.yml
+++ b/config/sidekiq_queues.yml
@@ -193,6 +193,8 @@
- 1
- - geo
- 1
+- - github_gists_importer
+ - 1
- - github_import_advance_stage
- 1
- - github_importer
diff --git a/db/migrate/20221122141046_add_allow_pipeline_trigger_approve_deployment_to_project_settings.rb b/db/migrate/20221122141046_add_allow_pipeline_trigger_approve_deployment_to_project_settings.rb
new file mode 100644
index 00000000000..b9397d80211
--- /dev/null
+++ b/db/migrate/20221122141046_add_allow_pipeline_trigger_approve_deployment_to_project_settings.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddAllowPipelineTriggerApproveDeploymentToProjectSettings < Gitlab::Database::Migration[2.1]
+ enable_lock_retries!
+
+ def change
+ add_column :project_settings, :allow_pipeline_trigger_approve_deployment, :boolean, default: false, null: false
+ end
+end
diff --git a/db/schema_migrations/20221122141046 b/db/schema_migrations/20221122141046
new file mode 100644
index 00000000000..4baebb0dda6
--- /dev/null
+++ b/db/schema_migrations/20221122141046
@@ -0,0 +1 @@
+64b59128c42f55725a268b051c2f9fc656b2a49a2e721af995e3e25fc7c7e85d \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 065c1db2f77..3c884e05285 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -20379,6 +20379,7 @@ CREATE TABLE project_settings (
suggested_reviewers_enabled boolean DEFAULT false NOT NULL,
only_allow_merge_if_all_status_checks_passed boolean DEFAULT false NOT NULL,
mirror_branch_regex text,
+ allow_pipeline_trigger_approve_deployment boolean DEFAULT false NOT NULL,
CONSTRAINT check_2981f15877 CHECK ((char_length(jitsu_key) <= 100)),
CONSTRAINT check_3a03e7557a CHECK ((char_length(previous_default_branch) <= 4096)),
CONSTRAINT check_3ca5cbffe6 CHECK ((char_length(issue_branch_template) <= 255)),
diff --git a/doc/.vale/gitlab/spelling-exceptions.txt b/doc/.vale/gitlab/spelling-exceptions.txt
index 3c76e35826d..6270f710972 100644
--- a/doc/.vale/gitlab/spelling-exceptions.txt
+++ b/doc/.vale/gitlab/spelling-exceptions.txt
@@ -21,7 +21,7 @@ anonymized
Ansible
Anthos
Anycast
-Apdex
+apdex
API
APIs
Apparmor
@@ -123,6 +123,7 @@ callouts
callstack
callstacks
camelCase
+camelCased
Camo
canonicalization
canonicalized
@@ -264,6 +265,8 @@ deserialization
deserialize
deserializers
deserializes
+desugar
+desugars
desynchronized
Dev
DevOps
@@ -344,13 +347,14 @@ Fio
firewalled
firewalling
fixup
-Flamegraph
+flamegraph
flamegraphs
Flawfinder
Flickr
Fluentd
Flutterwave
Flycheck
+focusable
Forgerock
formatters
Fortinet
@@ -539,6 +543,7 @@ Mattermost
mbox
memoization
memoize
+memoizes
memoized
memoizing
Memorystore
@@ -629,9 +634,12 @@ Packwerk
paginator
parallelization
parallelizations
+PascalCase
+PascalCased
passthrough
passthroughs
passwordless
+parsable
Patroni
PDFs
performant
@@ -709,6 +717,7 @@ Qualys
queryable
Quicktime
Rackspace
+railties
Raspbian
rbenv
rbspy
@@ -857,6 +866,8 @@ Slony
SLOs
smartcard
smartcards
+snake_case
+snake_cased
snapshotting
Snowplow
Snyk
diff --git a/doc/administration/geo/replication/version_specific_upgrades.md b/doc/administration/geo/replication/version_specific_upgrades.md
index 9aad5cdeaa7..3de8c97bf31 100644
--- a/doc/administration/geo/replication/version_specific_upgrades.md
+++ b/doc/administration/geo/replication/version_specific_upgrades.md
@@ -144,7 +144,7 @@ GitLab 13.9 through GitLab 14.3 are affected by a bug in which enabling [GitLab
## Upgrading to GitLab 13.9
-### Error during zero-downtime upgrade: "cannot drop column asset_proxy_whitelist"
+### Error during zero-downtime upgrade: `cannot drop column asset_proxy_whitelist`
We've detected an issue [with a column rename](https://gitlab.com/gitlab-org/gitlab/-/issues/324160)
that prevents upgrades to GitLab 13.9.0, 13.9.1, 13.9.2 and 13.9.3 when following the zero-downtime steps. It is necessary
diff --git a/doc/administration/img/impersonated_audit_events_v15_7.png b/doc/administration/img/impersonated_audit_events_v15_7.png
index 3e64af8e230..ef7decd984d 100644
--- a/doc/administration/img/impersonated_audit_events_v15_7.png
+++ b/doc/administration/img/impersonated_audit_events_v15_7.png
Binary files differ
diff --git a/doc/administration/job_artifacts.md b/doc/administration/job_artifacts.md
index 8cac8ea1f77..c5d98f95c68 100644
--- a/doc/administration/job_artifacts.md
+++ b/doc/administration/job_artifacts.md
@@ -235,7 +235,7 @@ by the `gitlab:artifacts:migrate` Rake task.
To migrate back to local storage:
1. Run `gitlab-rake gitlab:artifacts:migrate_to_local`.
-1. Disable object_storage for artifacts in `gitlab.rb`:
+1. Disable object storage for artifacts in `gitlab.rb`:
- Set `gitlab_rails['artifacts_object_store_enabled'] = false`.
- Comment out all other `artifacts_object_store` settings, including the entire
`artifacts_object_store_connection` section, including the closing `}`.
diff --git a/doc/administration/package_information/index.md b/doc/administration/package_information/index.md
index 4758b453135..bfa751a051f 100644
--- a/doc/administration/package_information/index.md
+++ b/doc/administration/package_information/index.md
@@ -16,9 +16,9 @@ The released package versions are in the format `MAJOR.MINOR.PATCH-EDITION.OMNIB
| Component | Meaning | Example |
|---------------------|---------|---------|
-| `MAJOR.MINOR.PATCH` | The GitLab version this corresponds to. | 13.3.0 |
-| `EDITION` | The edition of GitLab this corresponds to. | ee |
-| `OMNIBUS_RELEASE` | The Omnibus GitLab release. Usually, this is 0. This is incremented if we need to build a new package without changing the GitLab version. | 0 |
+| `MAJOR.MINOR.PATCH` | The GitLab version this corresponds to. | `13.3.0` |
+| `EDITION` | The edition of GitLab this corresponds to. | `ee` |
+| `OMNIBUS_RELEASE` | The Omnibus GitLab release. Usually, this is 0. This is incremented if we need to build a new package without changing the GitLab version. | `0` |
## Licenses
diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md
index a25385d3328..9abc3d625c2 100644
--- a/doc/administration/pages/index.md
+++ b/doc/administration/pages/index.md
@@ -275,9 +275,9 @@ control over how the Pages daemon runs and serves content in your environment.
| `max_uri_length` | The maximum length of URIs accepted by GitLab Pages. Set to 0 for unlimited length. [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/659) in GitLab 14.5.
| `metrics_address` | The address to listen on for metrics requests. |
| `redirect_http` | Redirect pages from HTTP to HTTPS, true/false. |
-| `redirects_max_config_size` | The maximum size of the _redirects file, in bytes (default: 65536). |
-| `redirects_max_path_segments` | The maximum number of path segments allowed in _redirects rules URLs (default: 25). |
-| `redirects_max_rule_count` | The maximum number of rules allowed in _redirects (default: 1000). |
+| `redirects_max_config_size` | The maximum size of the `_redirects` file, in bytes (default: 65536). |
+| `redirects_max_path_segments` | The maximum number of path segments allowed in `_redirects` rules URLs (default: 25). |
+| `redirects_max_rule_count` | The maximum number of rules allowed in `_redirects` (default: 1000). |
| `sentry_dsn` | The address for sending Sentry crash reporting to. |
| `sentry_enabled` | Enable reporting and logging with Sentry, true/false. |
| `sentry_environment` | The environment for Sentry crash reporting. |
diff --git a/doc/api/applications.md b/doc/api/applications.md
index f7b646d2351..53ea2f51d1a 100644
--- a/doc/api/applications.md
+++ b/doc/api/applications.md
@@ -103,7 +103,7 @@ Parameters:
| Attribute | Type | Required | Description |
|:----------|:--------|:---------|:----------------------------------------------------|
-| `id` | integer | yes | The ID of the application (not the application_id). |
+| `id` | integer | yes | The ID of the application (not the `application_id`). |
Example request:
diff --git a/doc/api/epic_issues.md b/doc/api/epic_issues.md
index 4bbd0b21136..28c74a0a418 100644
--- a/doc/api/epic_issues.md
+++ b/doc/api/epic_issues.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Epic Issues API **(PREMIUM)**
-Every API call to epic_issues must be authenticated.
+Every API call to the epic issues API endpoint must be authenticated.
If a user is not a member of a group and the group is private, a `GET` request on that group
results in a `404` status code.
diff --git a/doc/api/index.md b/doc/api/index.md
index cc54731de81..c75ccc0020b 100644
--- a/doc/api/index.md
+++ b/doc/api/index.md
@@ -177,7 +177,7 @@ Read more about [GitLab as an OAuth2 provider](oauth2.md).
NOTE:
We recommend OAuth access tokens have an expiration. You can use the `refresh_token` parameter
to refresh tokens. Integrations may need to be updated to use refresh tokens prior to
-expiration, which is based on the [expires_in](https://datatracker.ietf.org/doc/html/rfc6749#appendix-A.14)
+expiration, which is based on the [`expires_in`](https://datatracker.ietf.org/doc/html/rfc6749#appendix-A.14)
property in the token endpoint response. See [OAuth2 token](oauth2.md) documentation
for examples requesting a new access token using a refresh token.
diff --git a/doc/api/integrations.md b/doc/api/integrations.md
index c71f136f132..f6ad095aad6 100644
--- a/doc/api/integrations.md
+++ b/doc/api/integrations.md
@@ -354,7 +354,7 @@ Parameters:
| --------- | ---- | -------- | ----------- |
| `webhook` | string | true | The Unify Circuit webhook. For example, `https://circuit.com/rest/v2/webhooks/incoming/...`. |
| `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines |
-| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected". The default value is "default" |
+| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is "default" |
| `push_events` | boolean | false | Enable notifications for push events |
| `issues_events` | boolean | false | Enable notifications for issue events |
| `confidential_issues_events` | boolean | false | Enable notifications for confidential issue events |
@@ -444,7 +444,7 @@ Parameters:
| --------- | ---- | -------- | ----------- |
| `webhook` | string | true | The Webex Teams webhook. For example, `https://api.ciscospark.com/v1/webhooks/incoming/...`. |
| `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines |
-| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected". The default value is "default" |
+| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is "default" |
| `push_events` | boolean | false | Enable notifications for push events |
| `issues_events` | boolean | false | Enable notifications for issue events |
| `confidential_issues_events` | boolean | false | Enable notifications for confidential issue events |
@@ -601,7 +601,7 @@ Parameters:
| `send_from_committer_email` | boolean | false | Send from committer |
| `push_events` | boolean | false | Enable notifications for push events |
| `tag_push_events` | boolean | false | Enable notifications for tag push events |
-| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected". Notifications are always fired for tag pushes. The default value is "all" |
+| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. Notifications are always fired for tag pushes. The default value is "all" |
### Disable Emails on Push integration
@@ -810,7 +810,7 @@ Parameters:
| `webhook` | string | true | The Hangouts Chat webhook. For example, `https://chat.googleapis.com/v1/spaces...`. |
| `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines |
| `notify_only_default_branch` | boolean | false | DEPRECATED: This parameter has been replaced with `branches_to_be_notified` |
-| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected". The default value is "default" |
+| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is "default" |
| `push_events` | boolean | false | Enable notifications for push events |
| `issues_events` | boolean | false | Enable notifications for issue events |
| `confidential_issues_events` | boolean | false | Enable notifications for confidential issue events |
@@ -1070,7 +1070,7 @@ Parameters:
| --------- | ---- | -------- | ----------- |
| `recipients` | string | yes | Comma-separated list of recipient email addresses |
| `notify_only_broken_pipelines` | boolean | no | Notify only broken pipelines |
-| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected. The default value is "default" |
+| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is "default" |
| `notify_only_default_branch` | boolean | no | Send notifications only for the default branch ([introduced in GitLab 12.0](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/28271)) |
| `pipeline_events` | boolean | false | Enable notifications for pipeline events |
@@ -1258,7 +1258,7 @@ Parameters:
| `channel` | string | false | Default channel to use if others are not configured |
| `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines |
| `notify_only_default_branch` | boolean | false | DEPRECATED: This parameter has been replaced with `branches_to_be_notified` |
-| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected". The default value is "default" |
+| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is "default" |
| `commit_events` | boolean | false | Enable notifications for commit events |
| `confidential_issue_channel` | string | false | The name of the channel to receive confidential issues events notifications |
| `confidential_issues_events` | boolean | false | Enable notifications for confidential issue events |
@@ -1317,7 +1317,7 @@ Parameters:
| `webhook` | string | true | The Microsoft Teams webhook. For example, `https://outlook.office.com/webhook/...` |
| `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines |
| `notify_only_default_branch` | boolean | false | DEPRECATED: This parameter has been replaced with `branches_to_be_notified` |
-| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected". The default value is "default" |
+| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is "default" |
| `push_events` | boolean | false | Enable notifications for push events |
| `issues_events` | boolean | false | Enable notifications for issue events |
| `confidential_issues_events` | boolean | false | Enable notifications for confidential issue events |
@@ -1365,7 +1365,7 @@ Parameters:
| `channel` | string | false | Default channel to use if others are not configured |
| `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines |
| `notify_only_default_branch` | boolean | false | DEPRECATED: This parameter has been replaced with `branches_to_be_notified` |
-| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected". The default value is "default" |
+| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are `all`, `default`, `protected`, and `default_and_protected`. The default value is "default" |
| `push_events` | boolean | false | Enable notifications for push events |
| `issues_events` | boolean | false | Enable notifications for issue events |
| `confidential_issues_events` | boolean | false | Enable notifications for confidential issue events |
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 2800ccfee93..7713f0f441e 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -51,8 +51,8 @@ GET /projects
| `id_after` | integer | **{dotted-circle}** No | Limit results to projects with IDs greater than the specified ID. |
| `id_before` | integer | **{dotted-circle}** No | Limit results to projects with IDs less than the specified ID. |
| `imported` | boolean | **{dotted-circle}** No | Limit results to projects which were imported from external systems by current user. |
-| `last_activity_after` | datetime | **{dotted-circle}** No | Limit results to projects with last_activity after specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`) |
-| `last_activity_before` | datetime | **{dotted-circle}** No | Limit results to projects with last_activity before specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`) |
+| `last_activity_after` | datetime | **{dotted-circle}** No | Limit results to projects with last activity after specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`) |
+| `last_activity_before` | datetime | **{dotted-circle}** No | Limit results to projects with last activity before specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`) |
| `membership` | boolean | **{dotted-circle}** No | Limit by projects that the current user is a member of. |
| `min_access_level` | integer | **{dotted-circle}** No | Limit by current user minimal [role (`access_level`)](members.md#roles). |
| `order_by` | string | **{dotted-circle}** No | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, `last_activity_at`, or `similarity` fields. `repository_size`, `storage_size`, `packages_size` or `wiki_size` fields are only allowed for administrators. `similarity` ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332890) in GitLab 14.1) is only available when searching and is limited to projects that the current user is a member of. Default is `created_at`. |
diff --git a/doc/architecture/blueprints/ci_data_decay/pipeline_partitioning.md b/doc/architecture/blueprints/ci_data_decay/pipeline_partitioning.md
index 8baac2e0c14..261390d1d14 100644
--- a/doc/architecture/blueprints/ci_data_decay/pipeline_partitioning.md
+++ b/doc/architecture/blueprints/ci_data_decay/pipeline_partitioning.md
@@ -332,7 +332,7 @@ a few extra steps:
- add `partition_id` column for the FK references with default value of `100`
since the majority of records should have that value.
- change application logic to cascade the `partition_id` value
-- correct partition_id values for recent records with a post deploy/background
+- correct `partition_id` values for recent records with a post deploy/background
migration, similar to this:
```sql
diff --git a/doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md b/doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md
index 0be565fec1c..3ef98c33035 100644
--- a/doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md
+++ b/doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md
@@ -301,7 +301,7 @@ All work can be found in these merge requests:
- [Draft: PoC - Move GraphQL to the WebEngine](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50180)
- [Draft: PoC - Move Controllers and Grape API:API to the WebEngine](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53720)
- [Draft: PoC - Move only Grape API:API to the WebEngine](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53982)
-- [Measure performance impact for proposed web_engine](https://gitlab.com/gitlab-org/gitlab/-/issues/300548)
+- [Measure performance impact for proposed `web_engine`](https://gitlab.com/gitlab-org/gitlab/-/issues/300548)
What was done?
@@ -328,8 +328,8 @@ What was done?
1. Move gems to the `engines/web_engine/`
- - We moved all GraphQL gems to the actual web_engine Gemfile
- - We moved Grape API gem to the actual web_engine Gemfile
+ - We moved all GraphQL gems to the actual `web_engine` Gemfile
+ - We moved Grape API gem to the actual `web_engine` Gemfile
```ruby
Gem::Specification.new do |spec|
@@ -344,9 +344,9 @@ What was done?
1. Move routes to the `engines/web_engine/config/routes.rb` file
- - We moved GraphQL routes to the web_engine routes.
- - We moved API routes to the web_engine routes.
- - We moved most of the controller routes to the web_engine routes.
+ - We moved GraphQL routes to the `web_engine` routes.
+ - We moved API routes to the `web_engine` routes.
+ - We moved most of the controller routes to the `web_engine` routes.
```ruby
Rails.application.routes.draw do
@@ -367,7 +367,7 @@ What was done?
1. Connect GitLab application with the WebEngine
- In GitLab Gemfile.rb, add web_engine to the engines group
+ In GitLab Gemfile.rb, add `web_engine` to the engines group
```ruby
# Gemfile
@@ -505,7 +505,7 @@ Cons:
[Draft: PoC - Move GraphQL to the WebEngine](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50180)
- The [99% of changes](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50180/diffs?commit_id=49c9881c6696eb620dccac71532a3173f5702ea8) as visible in the above MRs is moving files as-is.
-- The [actual work](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50180/diffs?commit_id=1d9a9edfa29ea6638e7d8a6712ddf09f5be77a44) on fixing cross-dependencies, specs, and configuring web_engine
+- The [actual work](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50180/diffs?commit_id=1d9a9edfa29ea6638e7d8a6712ddf09f5be77a44) on fixing cross-dependencies, specs, and configuring `web_engine`
- We [adapted](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50180/diffs?commit_id=d7f862cc209ce242000b2aec88ff7f4485acdd92) CI to test `engines/web_engine/` as a self-sufficient component of stack
Today, loading GraphQL requires a bunch of [dependencies](https://gitlab.com/gitlab-org/gitlab/-/issues/288044):
@@ -581,7 +581,7 @@ to be created to ensure that we do not have explosion of engines.
- [Draft: PoC - Move GraphQL to the WebEngine](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50180)
- [Draft: PoC - Move Controllers and Grape API:API to the WebEngine](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53720)
- [Draft: PoC - Move only Grape API:API to the WebEngine](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53982)
-- [Measure performance impact for proposed web_engine](https://gitlab.com/gitlab-org/gitlab/-/issues/300548)
+- [Measure performance impact for proposed `web_engine`](https://gitlab.com/gitlab-org/gitlab/-/issues/300548)
- [Create new models / classes within a module / namespace](https://gitlab.com/gitlab-org/gitlab/-/issues/212156)
- [Make teams to be maintainers of their code](https://gitlab.com/gitlab-org/gitlab/-/issues/25872)
- [Use nested structure to organize CI classes](https://gitlab.com/gitlab-org/gitlab/-/issues/209745)
diff --git a/doc/architecture/blueprints/container_registry_metadata_database/index.md b/doc/architecture/blueprints/container_registry_metadata_database/index.md
index 6f70004f299..f3bcf1e4e59 100644
--- a/doc/architecture/blueprints/container_registry_metadata_database/index.md
+++ b/doc/architecture/blueprints/container_registry_metadata_database/index.md
@@ -258,7 +258,7 @@ The expected registry behavior will be covered with integration tests, using a p
If unable to pull a connection from the pool to serve a given request, the registry will timeout and return an HTTP `500 Internal Server Error` error to the client and report the error to Sentry. These issues should trigger a development escalation to investigate why the pool is being exhausted. There might be too much load for the preconfigured pool size, or there might be transactions holding on to connections for too long.
-Prometheus metrics should be used to create alerts to act on a possible saturation before the application starts erroring. Special attention will be paid to these scenarios during the gradual migration of the GitLab.com registry, where we will have limited, gradual, and controlled exposure on the new registry nodes. During that process, we can identify usage patterns, observe metrics, and fine tune both infrastructure and application settings accordingly as the load increases. If needed, a rate limiting algorithm may be applied to limit impact. Decisions will be based on real data to avoid overly restrictive measures and premature optimizations.
+Prometheus metrics should be used to create alerts to act on a possible saturation before the application starts returning errors. Special attention will be paid to these scenarios during the gradual migration of the GitLab.com registry, where we will have limited, gradual, and controlled exposure on the new registry nodes. During that process, we can identify usage patterns, observe metrics, and fine tune both infrastructure and application settings accordingly as the load increases. If needed, a rate limiting algorithm may be applied to limit impact. Decisions will be based on real data to avoid overly restrictive measures and premature optimizations.
The expected registry behavior will be covered with integration tests by manipulating the pool size and spawning multiple concurrent requests against the API, putting pressure on the pool and eventually exhausting its capacity.
@@ -294,7 +294,7 @@ Together, these resources should provide an adequate level of insight into the r
GitLab ships with the GitLab Container Registry by default, but it's also compatible with third-party registries, as long as they comply with the [Docker Distribution V2 Specification](https://docs.docker.com/registry/spec/api/), now superseded by the [Open Container Initiative (OCI) Image Specification](https://github.com/opencontainers/image-spec/blob/master/spec.md).
-So far, we strived to maintain full compatibility with third-party registries when adding new features. For example, in 12.8, we introduced a new [tag delete feature](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23325) to delete a single tag without deleting the underlying manifest. Because this feature is not part of the Docker or OCI specifications, we have kept the previous behavior as a fallback option to maintain compatibility with third-party registries.
+So far, we have tried to maintain full compatibility with third-party registries when adding new features. For example, in 12.8, we introduced a new [tag delete feature](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23325) to delete a single tag without deleting the underlying manifest. Because this feature is not part of the Docker or OCI specifications, we have kept the previous behavior as a fallback option to maintain compatibility with third-party registries.
However, this will likely change in the future. Apart from online garbage collection, and as described in [challenges](#challenges), the metadata database will unblock the implementation of many requested features for the GitLab Container Registry in the mid/long term. Most of these features will only be available for instances using the GitLab Container Registry. They are not part of the Docker Distribution or OCI specifications, neither we will be able to provide a compatible fallback option.
diff --git a/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md b/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md
index a0665e1c054..ceb56b01dcd 100644
--- a/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md
+++ b/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md
@@ -122,7 +122,7 @@ To use GitLab CI/CD with a Bitbucket Cloud repository:
1. In Bitbucket, create a `.gitlab-ci.yml` file to use the script to push
pipeline success and failures to Bitbucket. Similar to the script added above,
- this file is copied to the GitLab repo as part of the mirroring process.
+ this file is copied to the GitLab repository as part of the mirroring process.
```yaml
stages:
diff --git a/doc/ci/environments/index.md b/doc/ci/environments/index.md
index 53c6ccc2f6c..0c412c85e47 100644
--- a/doc/ci/environments/index.md
+++ b/doc/ci/environments/index.md
@@ -345,7 +345,7 @@ and displayed at a post-merge pipeline in [merge request pages](../../user/proje
To activate this tracking, your environment must be configured in the following:
-- [Environment name](../yaml/index.md#environmentname) is not foldered with `/` (that is, top-level/long-lived environments), _OR_
+- [Environment name](../yaml/index.md#environmentname) is not using folders with `/` (that is, top-level/long-lived environments), _OR_
- [Environment tier](#deployment-tier-of-environments) is either `production` or `staging`.
Here are the example setups of [`environment` keyword](../yaml/index.md#environment) in `.gitlab-ci.yml`:
diff --git a/doc/ci/examples/authenticating-with-hashicorp-vault/index.md b/doc/ci/examples/authenticating-with-hashicorp-vault/index.md
index 66369cec3b1..9b80fe22c37 100644
--- a/doc/ci/examples/authenticating-with-hashicorp-vault/index.md
+++ b/doc/ci/examples/authenticating-with-hashicorp-vault/index.md
@@ -90,7 +90,7 @@ The JWT is encoded by using RS256 and signed with a dedicated private key. The e
You can use this JWT and your instance's JWKS endpoint (`https://gitlab.example.com/-/jwks`) to authenticate with a Vault server that is configured to allow the JWT Authentication method for authentication.
-When configuring roles in Vault, you can use [bound_claims](https://developer.hashicorp.com/vault/docs/auth/jwt#bound-claims) to match against the JWT's claims and restrict which secrets each CI job has access to.
+When configuring roles in Vault, you can use [bound claims](https://developer.hashicorp.com/vault/docs/auth/jwt#bound-claims) to match against the JWT claims and restrict which secrets each CI/CD job has access to.
To communicate with Vault, you can use either its CLI client or perform API requests (using `curl` or another client).
@@ -180,7 +180,7 @@ $ vault write auth/jwt/role/myproject-production - <<EOF
EOF
```
-This example uses [bound_claims](https://developer.hashicorp.com/vault/api-docs/auth/jwt#bound_claims) to specify that only a JWT with matching values for the specified claims is allowed to authenticate.
+This example uses [bound claims](https://developer.hashicorp.com/vault/api-docs/auth/jwt#bound_claims) to specify that only a JWT with matching values for the specified claims is allowed to authenticate.
Combined with [protected branches](../../../user/project/protected_branches.md), you can restrict who is able to authenticate and read the secrets.
@@ -225,7 +225,7 @@ $ vault write auth/jwt/config \
bound_issuer="gitlab.example.com"
```
-[bound_issuer](https://developer.hashicorp.com/vault/api-docs/auth/jwt#bound_issuer) specifies that only a JWT with the issuer (that is, the `iss` claim) set to `gitlab.example.com` can use this method to authenticate, and that the JWKS endpoint (`https://gitlab.example.com/-/jwks`) should be used to validate the token.
+[`bound_issuer`](https://developer.hashicorp.com/vault/api-docs/auth/jwt#bound_issuer) specifies that only a JWT with the issuer (that is, the `iss` claim) set to `gitlab.example.com` can use this method to authenticate, and that the JWKS endpoint (`https://gitlab.example.com/-/jwks`) should be used to validate the token.
For the full list of available configuration options, see Vault's [API documentation](https://developer.hashicorp.com/vault/api-docs/auth/jwt#configure).
@@ -256,7 +256,7 @@ NOTE:
If you're using a Vault instance provided by HashiCorp Cloud Platform,
you need to export the `VAULT_NAMESPACE` variable. Its default value is `admin`.
-![`read_secrets` staging](img/vault-read-secrets-staging.png)
+![read secrets staging example](img/vault-read-secrets-staging.png)
The following job is able to authenticate using the `myproject-production` role and read secrets under `/secret/myproject/production/`:
@@ -279,7 +279,7 @@ read_secrets:
- echo $PASSWORD
```
-![`read_secrets` production](img/vault-read-secrets-production.png)
+![read secrets production example](img/vault-read-secrets-production.png)
### Limit token access to Vault secrets
diff --git a/doc/ci/large_repositories/index.md b/doc/ci/large_repositories/index.md
index dcfa1403186..1cc92d91b7a 100644
--- a/doc/ci/large_repositories/index.md
+++ b/doc/ci/large_repositories/index.md
@@ -260,4 +260,4 @@ For very active repositories with a large number of references and files, you ca
seeding the repository data also helps avoid
`429 Too many requests` errors from Cloudflare.
This error can occur if you have many runners behind a single,
- NAT'ed IP address that pulls from GitLab.com.
+ IP address using NAT, that pulls from GitLab.com.
diff --git a/doc/ci/runners/configure_runners.md b/doc/ci/runners/configure_runners.md
index d3ff4051a8e..b61e11dd8bc 100644
--- a/doc/ci/runners/configure_runners.md
+++ b/doc/ci/runners/configure_runners.md
@@ -292,12 +292,12 @@ variables:
A runner can have one of the following statuses.
-| Status | Description |
-|--------|-------------|
-| **online** | The runner has contacted GitLab within the last 2 hours and is available to run jobs. |
-| **offline** | The runner has not contacted GitLab in more than 2 hours and is not available to run jobs. Check the runner to see if you can bring it online. |
-| **stale** | The runner has not contacted GitLab in more than 3 months. If the runner was created more than 3 months ago, but it never contacted the instance, it is also considered **stale**. |
-| **never_contacted** | The runner has never contacted GitLab. To make the runner contact GitLab, run `gitlab-runner run`. |
+| Status | Description |
+|---------|-------------|
+| `online` | The runner has contacted GitLab within the last 2 hours and is available to run jobs. |
+| `offline` | The runner has not contacted GitLab in more than 2 hours and is not available to run jobs. Check the runner to see if you can bring it online. |
+| `stale` | The runner has not contacted GitLab in more than 3 months. If the runner was created more than 3 months ago, but it never contacted the instance, it is also considered **stale**. |
+| `never_contacted` | The runner has never contacted GitLab. To make the runner contact GitLab, run `gitlab-runner run`. |
## Configure runner behavior with variables
diff --git a/doc/ci/secrets/index.md b/doc/ci/secrets/index.md
index a5082af89bc..bfc53210348 100644
--- a/doc/ci/secrets/index.md
+++ b/doc/ci/secrets/index.md
@@ -143,7 +143,7 @@ different policies together. If authentication is successful, these policies are
attached to the resulting Vault token.
[Bound claims](https://developer.hashicorp.com/vault/docs/auth/jwt#bound-claims) are predefined
-values that are matched to the JWT's claims. With bounded claims, you can restrict access
+values that are matched to the JWT claims. With bounded claims, you can restrict access
to specific GitLab users, specific projects, or even jobs running for specific Git
references. You can have as many bounded claims you need, but they must *all* match
for authentication to be successful.
diff --git a/doc/development/cicd/pipeline_wizard.md b/doc/development/cicd/pipeline_wizard.md
index eb6d1c60bb1..213a9fe1762 100644
--- a/doc/development/cicd/pipeline_wizard.md
+++ b/doc/development/cicd/pipeline_wizard.md
@@ -127,7 +127,7 @@ is planned to add the ability to create a MR from here.
### Props
-- `template` (required): The template content as an unparsed String. See
+- `template` (required): The template content as an un-parsed string. See
[Template file location](#template-file-location) for more information.
- `project-path` (required): The full path of the project the final file
should be committed to
diff --git a/doc/development/contributing/style_guides.md b/doc/development/contributing/style_guides.md
index fe1aa8449c2..0a030d1f3bc 100644
--- a/doc/development/contributing/style_guides.md
+++ b/doc/development/contributing/style_guides.md
@@ -47,7 +47,7 @@ We were using Overcommit prior to Lefthook, so you may want to uninstall it firs
bundle exec lefthook run pre-push
```
-This should return the lefthook version and the list of executable commands with output.
+This should return the Lefthook version and the list of executable commands with output.
### Lefthook configuration
diff --git a/doc/development/database/creating_enums.md b/doc/development/database/creating_enums.md
index 73c3f546728..e2ae36f7481 100644
--- a/doc/development/database/creating_enums.md
+++ b/doc/development/database/creating_enums.md
@@ -79,7 +79,7 @@ This works as-is, however, it has a couple of downside that:
- When it happens, we have to ship a database migration to fix the data integrity,
which might be impossible if you cannot recover the original value.
-Also, you might observe a workaround for this concern by setting an offset in EE's values.
+Also, you might observe a workaround for this concern by setting an offset in the `EE` module's values.
For example, this example sets `1000` as the offset:
```ruby
diff --git a/doc/development/database/efficient_in_operator_queries.md b/doc/development/database/efficient_in_operator_queries.md
index 8badc4fb9d3..78b310ae708 100644
--- a/doc/development/database/efficient_in_operator_queries.md
+++ b/doc/development/database/efficient_in_operator_queries.md
@@ -126,7 +126,7 @@ For very large groups the database queries can easily time out, causing HTTP 500
## Optimizing ordered `IN` queries
-In the talk ["How to teach an elephant to dance rock'n'roll"](https://www.youtube.com/watch?v=Ha38lcjVyhQ),
+In the talk ["How to teach an elephant to dance rock and roll"](https://www.youtube.com/watch?v=Ha38lcjVyhQ),
Maxim Boguk demonstrated a technique to optimize a special class of ordered `IN` queries,
such as our ordered group-level queries.
diff --git a/doc/development/database/query_recorder.md b/doc/development/database/query_recorder.md
index f1540e7e2ae..84bd0fc938f 100644
--- a/doc/development/database/query_recorder.md
+++ b/doc/development/database/query_recorder.md
@@ -47,7 +47,7 @@ the longest common prefix, grouping similar queries together.
In some cases, N+1 specs have been written to include three requests: first one to
warm the cache, second one to establish a control, third one to validate that
-ther are no N+1 queries. Rather than make an extra request to warm the cache, prefer two requests
+there are no N+1 queries. Rather than make an extra request to warm the cache, prefer two requests
(control and test) and configure your test to ignore [cached queries](#cached-queries) in N+1 specs.
## Cached queries
diff --git a/doc/development/documentation/styleguide/index.md b/doc/development/documentation/styleguide/index.md
index cd87704dda3..342d6b7845f 100644
--- a/doc/development/documentation/styleguide/index.md
+++ b/doc/development/documentation/styleguide/index.md
@@ -147,7 +147,7 @@ help benefit translation. For example, we:
- [since and because](word_list.md#since)
- [once and after](word_list.md#once)
- [it](word_list.md#it)
-- Avoid [ing](word_list.md#-ing-words) words.
+- Avoid [-ing](word_list.md#-ing-words) words.
[The GitLab voice](#the-gitlab-voice) dictates that we write clearly and directly,
and with translation in mind. [The word list](word_list.md) and our Vale rules
@@ -717,7 +717,7 @@ Put the entire link on a single line so that [linters](../testing.md) can find i
### Links in separate repositories
To link to a page in a different repository, use an absolute URL.
-For example, to link from a page in the GitLab repo to the Charts repo,
+For example, to link from a page in the GitLab repository to the Charts repository,
use a URL like `https://docs.gitlab.com/charts/`.
### Anchor links
diff --git a/doc/development/ee_features.md b/doc/development/ee_features.md
index 14df73b8779..5e236c3e322 100644
--- a/doc/development/ee_features.md
+++ b/doc/development/ee_features.md
@@ -94,6 +94,25 @@ setting the [`FOSS_ONLY` environment variable](https://gitlab.com/gitlab-org/git
to something that evaluates as `true`. The same works for running tests
(for example `FOSS_ONLY=1 yarn jest`).
+### Simulate a CE instance with a licensed GDK
+
+To simulate a CE instance without deleting the license in a GDK:
+
+1. Create an `env.runit` file in the root of your GDK with the line:
+
+ ```shell
+ export FOSS_ONLY=1
+ ```
+
+1. Then restart the GDK:
+
+ ```shell
+ gdk restart rails && gdk restart webpack
+ ```
+
+Remove the line in `env.runit` if you want to revert back to an EE
+installation, and repeat step 2.
+
#### Run feature specs as CE
When running [feature specs](testing_guide/best_practices.md#system--feature-tests)
diff --git a/doc/development/elasticsearch.md b/doc/development/elasticsearch.md
index cef42c56bb0..88a417b4745 100644
--- a/doc/development/elasticsearch.md
+++ b/doc/development/elasticsearch.md
@@ -69,7 +69,7 @@ The `whitespace` tokenizer was selected to have more control over how tokens are
Please see the `code` filter for an explanation on how tokens are split.
NOTE:
-The [Elasticsearch code_analyzer doesn't account for all code cases](../integration/advanced_search/elasticsearch_troubleshooting.md#elasticsearch-code_analyzer-doesnt-account-for-all-code-cases).
+The [Elasticsearch `code_analyzer` doesn't account for all code cases](../integration/advanced_search/elasticsearch_troubleshooting.md#elasticsearch-code_analyzer-doesnt-account-for-all-code-cases).
#### `code_search_analyzer`
diff --git a/doc/development/fe_guide/dark_mode.md b/doc/development/fe_guide/dark_mode.md
index d687d9740c9..55181edd64c 100644
--- a/doc/development/fe_guide/dark_mode.md
+++ b/doc/development/fe_guide/dark_mode.md
@@ -19,9 +19,9 @@ Note the following:
- We define two types of variables in `_dark.scss`:
- SCSS variables are used in framework, components, and utility classes.
- CSS variables are used for any colors within the `app/assets/stylesheets/page_bundles` directory.
-- `app/views/layouts/_head.html.haml` then loads application or application_dark based on the user's theme preference.
+- `app/views/layouts/_head.html.haml` then loads `application` or `application_dark` based on the user's theme preference.
-As we do not want to generate separate `_dark.css` variants of every page_bundle file,
+As we do not want to generate separate `_dark.css` variants of every `page_bundle` file,
we use CSS variables with SCSS variables as fallbacks. This is because when we generate the `page_bundles`
CSS, we get the variable values from `_variables.scss`, so any SCSS variables have light mode values.
diff --git a/doc/development/fe_guide/haml.md b/doc/development/fe_guide/haml.md
index d76d718e8e5..9dc5b265783 100644
--- a/doc/development/fe_guide/haml.md
+++ b/doc/development/fe_guide/haml.md
@@ -81,11 +81,7 @@ When using the GitLab UI form builder, the following components are available fo
NOTE:
Currently only the listed components are available but more components are planned.
-<!-- vale gitlab.Spelling = NO -->
-
-#### gitlab_ui_checkbox_component
-
-<!-- vale gitlab.Spelling = YES -->
+#### `gitlab_ui_checkbox_component`
[GitLab UI Docs](https://gitlab-org.gitlab.io/gitlab-ui/?path=/story/base-form-form-checkbox--default)
@@ -110,11 +106,7 @@ This component supports [ViewComponent slots](https://viewcomponent.org/guide/sl
| `label` | Checkbox label content. This slot can be used instead of the `label` argument. |
| `help_text` | Help text content displayed below the checkbox. This slot can be used instead of the `help_text` argument. |
-<!-- vale gitlab.Spelling = NO -->
-
-#### gitlab_ui_radio_component
-
-<!-- vale gitlab.Spelling = YES -->
+#### `gitlab_ui_radio_component`
[GitLab UI Docs](https://gitlab-org.gitlab.io/gitlab-ui/?path=/story/base-form-form-radio--default)
diff --git a/doc/development/fe_guide/view_component.md b/doc/development/fe_guide/view_component.md
index b61c23cadef..90bb75514d8 100644
--- a/doc/development/fe_guide/view_component.md
+++ b/doc/development/fe_guide/view_component.md
@@ -180,7 +180,7 @@ The `Pajamas::CheckboxComponent` follows the [Pajamas Checkbox](https://design.g
NOTE:
`Pajamas::CheckboxComponent` is used internally by the [GitLab UI form builder](haml.md#use-the-gitlab-ui-form-builder) and requires an instance of [ActionView::Helpers::FormBuilder](https://api.rubyonrails.org/v6.1.0/classes/ActionView/Helpers/FormBuilder.html) to be passed as the `form` argument.
-It is preferred to use the [gitlab_ui_checkbox_component](haml.md#gitlab_ui_checkbox_component) method to render this ViewComponent.
+It is preferred to use the [`gitlab_ui_checkbox_component`](haml.md#gitlab_ui_checkbox_component) method to render this ViewComponent.
To use a checkbox without an instance of [ActionView::Helpers::FormBuilder](https://api.rubyonrails.org/v6.1.0/classes/ActionView/Helpers/FormBuilder.html) use [CheckboxTagComponent](#checkbox-tag).
For the full list of options, see its
diff --git a/doc/development/fe_guide/vue3_migration.md b/doc/development/fe_guide/vue3_migration.md
index aae7674d190..b9e819a95bd 100644
--- a/doc/development/fe_guide/vue3_migration.md
+++ b/doc/development/fe_guide/vue3_migration.md
@@ -182,13 +182,13 @@ In the step-by-step guide, we will be migrating [VueApollo Demo](https://gitlab.
#### Initial state
-Right after cloning, you could run [VueApollo Demo](https://gitlab.com/gitlab-org/frontend/vue3-migration-vue-apollo/-/tree/main/src/vue3compat) with Vue.js 2 using `yarn serve` or with Vue.js 3 (compat build) using `yarn serve:vue3`. However latter immediately crashes:
+Right after cloning, you could run [VueApollo Demo](https://gitlab.com/gitlab-org/frontend/vue3-migration-vue-apollo/-/tree/main/src/vue3compat) with Vue.js 2 using `yarn serve` or with Vue.js 3 (`compat` build) using `yarn serve:vue3`. However latter immediately crashes:
```javascript
Uncaught TypeError: Cannot read properties of undefined (reading 'loading')
```
-VueApollo v3 (used for Vue.js 2) fails to initialize in Vue.js compat
+VueApollo v3 (used for Vue.js 2) fails to initialize in Vue.js `compat`
NOTE:
While stubbing `Vue.version` will solve VueApollo-related issues in the demo project, it will still lose reactivity on specific scenarios, so an upgrade is still needed
diff --git a/doc/development/file_storage.md b/doc/development/file_storage.md
index 11acb8a2161..c346d55f639 100644
--- a/doc/development/file_storage.md
+++ b/doc/development/file_storage.md
@@ -36,7 +36,7 @@ There are many places where file uploading is used, according to contexts:
GitLab started saving everything on local disk. While directory location changed from previous versions,
they are still not 100% standardized. You can see them below:
-| Description | In DB? | Relative path (from CarrierWave.root) | Uploader class | model_type |
+| Description | In DB? | Relative path (from CarrierWave.root) | Uploader class | Model type |
| ------------------------------------- | ------ | ----------------------------------------------------------- | ---------------------- | ---------- |
| Instance logo | yes | `uploads/-/system/appearance/logo/:id/:filename` | `AttachmentUploader` | Appearance |
| Header logo | yes | `uploads/-/system/appearance/header_logo/:id/:filename` | `AttachmentUploader` | Appearance |
diff --git a/doc/development/geo.md b/doc/development/geo.md
index f147574eaf5..76c75cb1c6a 100644
--- a/doc/development/geo.md
+++ b/doc/development/geo.md
@@ -200,7 +200,7 @@ sequenceDiagram
S->>TDB: Insert to `job_artifact_registry`
```
-- [Sidekiq-cron](https://github.com/ondrejbartas/sidekiq-cron) enqueues a `Geo::Secondary::RegistryConsistencyWorker` job every minute. As long as it is actively doing work (creating and deleting rows), this job immediately reenqueues itself. This job uses an exclusive lease to prevent multiple instances of itself from running simultaneously.
+- [Sidekiq-cron](https://github.com/ondrejbartas/sidekiq-cron) enqueues a `Geo::Secondary::RegistryConsistencyWorker` job every minute. As long as it is actively doing work (creating and deleting rows), this job immediately re-enqueues itself. This job uses an exclusive lease to prevent multiple instances of itself from running simultaneously.
- [Sidekiq](architecture.md#sidekiq) picks up `Geo::Secondary::RegistryConsistencyWorker` job
- Sidekiq queries `ci_job_artifacts` table for up to 10000 rows
- Sidekiq queries `job_artifact_registry` table for up to 10000 rows
diff --git a/doc/development/licensing.md b/doc/development/licensing.md
index d7dfdb7357d..cb703e98264 100644
--- a/doc/development/licensing.md
+++ b/doc/development/licensing.md
@@ -10,7 +10,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
## Automated Testing
-In order to comply with the terms the libraries we use are licensed under, we have to make sure to check new gems for compatible licenses whenever they're added. To automate this process, we use the [license_finder](https://github.com/pivotal/LicenseFinder) gem by Pivotal. It runs every time a new commit is pushed and verifies that all gems and node modules in the bundle use a license that doesn't conflict with the licensing of either GitLab Community Edition or GitLab Enterprise Edition.
+To comply with the terms the libraries we use are licensed under, we have to make sure to check new gems for compatible licenses whenever they're added. To automate this process, we use the [License Finder](https://github.com/pivotal/LicenseFinder) gem by Pivotal. It runs every time a new commit is pushed and verifies that all gems and node modules in the bundle use a license that doesn't conflict with the licensing of either GitLab Community Edition or GitLab Enterprise Edition.
There are some limitations with the automated testing, however. CSS, JavaScript, or Ruby libraries which are not included by way of Bundler, npm, or Yarn (for instance those manually copied into our source tree in the `vendor` directory), must be verified manually and independently. Take care whenever one such library is used, as automated tests don't catch problematic licenses from them.
diff --git a/doc/development/merge_request_performance_guidelines.md b/doc/development/merge_request_performance_guidelines.md
index 76bb2e84a08..fd78d02202f 100644
--- a/doc/development/merge_request_performance_guidelines.md
+++ b/doc/development/merge_request_performance_guidelines.md
@@ -525,7 +525,7 @@ end
The usage of shared temporary storage is required if your intent
is to persistent file for a disk-based storage, and not Object Storage.
-[Workhorse direct_upload](uploads/index.md#direct-upload) when accepting file
+[Workhorse direct upload](uploads/index.md#direct-upload) when accepting file
can write it to shared storage, and later GitLab Rails can perform a move operation.
The move operation on the same destination is instantaneous.
The system instead of performing `copy` operation just re-attaches file into a new place.
@@ -549,7 +549,7 @@ that implements a seamless support for Shared and Object Storage-based persisten
#### Data access
Each feature that accepts data uploads or allows to download them needs to use
-[Workhorse direct_upload](uploads/index.md#direct-upload). It means that uploads needs to be
+[Workhorse direct upload](uploads/index.md#direct-upload). It means that uploads needs to be
saved directly to Object Storage by Workhorse, and all downloads needs to be served
by Workhorse.
@@ -561,5 +561,5 @@ can time out, which is especially problematic for slow clients. If clients take
to upload/download the processing slot might be killed due to request processing
timeout (usually between 30s-60s).
-For the above reasons it is required that [Workhorse direct_upload](uploads/index.md#direct-upload) is implemented
+For the above reasons it is required that [Workhorse direct upload](uploads/index.md#direct-upload) is implemented
for all file uploads and downloads.
diff --git a/doc/development/migration_style_guide.md b/doc/development/migration_style_guide.md
index a482b16e9cb..e5ffae7eddc 100644
--- a/doc/development/migration_style_guide.md
+++ b/doc/development/migration_style_guide.md
@@ -1221,7 +1221,7 @@ Be aware of the limitations [when using models in migrations](#using-models-in-m
In most circumstances, prefer migrating data in **batches** when modifying data in the database.
-We introduced a new helper [each_batch_range](https://gitlab.com/gitlab-org/gitlab/-/blob/cd3e0a5cddcb464cb9b8c6e3275839cf57dfa6e2/lib/gitlab/database/dynamic_model_helpers.rb#L28-32) which facilitates the process of iterating over a collection in a performant way. The default size of the batch is defined in the `BATCH_SIZE` constant.
+We introduced a new helper [`each_batch_range`](https://gitlab.com/gitlab-org/gitlab/-/blob/cd3e0a5cddcb464cb9b8c6e3275839cf57dfa6e2/lib/gitlab/database/dynamic_model_helpers.rb#L28-32) which facilitates the process of iterating over a collection in a performant way. The default size of the batch is defined in the `BATCH_SIZE` constant.
See the following example to get an idea.
diff --git a/doc/development/packages/dependency_proxy.md b/doc/development/packages/dependency_proxy.md
index 1386889a43f..cc8b202e556 100644
--- a/doc/development/packages/dependency_proxy.md
+++ b/doc/development/packages/dependency_proxy.md
@@ -117,7 +117,7 @@ Manifests are more complicated, partially due to [rate limiting on DockerHub](ht
A manifest is essentially a recipe for creating an image. It has a list of blobs to create a certain image. So
`alpine:latest` has a manifest associated with it that specifies the blobs needed to create the `alpine:latest`
image. The interesting part is that `alpine:latest` can change over time, so we can't just cache the manifest and
-assume it is OK to use forever. Instead, we must check the digest of the manifest, which is an Etag. This gets
+assume it is OK to use forever. Instead, we must check the digest of the manifest, which is an ETag. This gets
interesting because the requests for manifests often don't include the digest. So how do we know if the manifest
we have cached is still the most up-to-date `alpine:latest`? DockerHub allows free HEAD requests that don't count
toward their rate limit. The HEAD request returns the manifest digest so we can tell whether or not the one we
diff --git a/doc/development/performance.md b/doc/development/performance.md
index 0d8f31424c3..127cade9fee 100644
--- a/doc/development/performance.md
+++ b/doc/development/performance.md
@@ -312,7 +312,7 @@ To export the flame graph to an SVG file, use [Brendan Gregg's FlameGraph tool](
stackprof --stackcollapse /tmp/group_member_policy_spec.rb.dump | flamegraph.pl > flamegraph.svg
```
-It's also possible to view flame graphs through [speedscope](https://github.com/jlfwong/speedscope).
+It's also possible to view flame graphs through [Speedscope](https://github.com/jlfwong/speedscope).
You can do this when using the [performance bar](profiling.md#speedscope-flamegraphs)
and when [profiling code blocks](https://github.com/jlfwong/speedscope/wiki/Importing-from-stackprof-(ruby)).
This option isn't supported by `bin/rspec-stackprof`.
diff --git a/doc/development/pipelines/internals.md b/doc/development/pipelines/internals.md
index 47e737df2a0..71492ed9f5d 100644
--- a/doc/development/pipelines/internals.md
+++ b/doc/development/pipelines/internals.md
@@ -165,9 +165,9 @@ and included in `rules` definitions via [YAML anchors](../../ci/yaml/yaml_optimi
| `if:` conditions | Description | Notes |
|------------------|-------------|-------|
-| `if-not-canonical-namespace` | Matches if the project isn't in the canonical (`gitlab-org/`) or security (`gitlab-org/security`) namespace. | Use to create a job for forks (by using `when: on_success|manual`), or **not** create a job for forks (by using `when: never`). |
-| `if-not-ee` | Matches if the project isn't EE (that is, project name isn't `gitlab` or `gitlab-ee`). | Use to create a job only in the FOSS project (by using `when: on_success|manual`), or **not** create a job if the project is EE (by using `when: never`). |
-| `if-not-foss` | Matches if the project isn't FOSS (that is, project name isn't `gitlab-foss`, `gitlab-ce`, or `gitlabhq`). | Use to create a job only in the EE project (by using `when: on_success|manual`), or **not** create a job if the project is FOSS (by using `when: never`). |
+| `if-not-canonical-namespace` | Matches if the project isn't in the canonical (`gitlab-org/`) or security (`gitlab-org/security`) namespace. | Use to create a job for forks (by using `when: on_success` or `when: manual`), or **not** create a job for forks (by using `when: never`). |
+| `if-not-ee` | Matches if the project isn't EE (that is, project name isn't `gitlab` or `gitlab-ee`). | Use to create a job only in the FOSS project (by using `when: on_success` or `when: manual`), or **not** create a job if the project is EE (by using `when: never`). |
+| `if-not-foss` | Matches if the project isn't FOSS (that is, project name isn't `gitlab-foss`, `gitlab-ce`, or `gitlabhq`). | Use to create a job only in the EE project (by using `when: on_success` or `when: manual`), or **not** create a job if the project is FOSS (by using `when: never`). |
| `if-default-refs` | Matches if the pipeline is for `master`, `main`, `/^[\d-]+-stable(-ee)?$/` (stable branches), `/^\d+-\d+-auto-deploy-\d+$/` (auto-deploy branches), `/^security\//` (security branches), merge requests, and tags. | Note that jobs aren't created for branches with this default configuration. |
| `if-master-refs` | Matches if the current branch is `master` or `main`. | |
| `if-master-push` | Matches if the current branch is `master` or `main` and pipeline source is `push`. | |
diff --git a/doc/development/product_qualified_lead_guide/index.md b/doc/development/product_qualified_lead_guide/index.md
index f8cd7fd48b9..1ad4f622829 100644
--- a/doc/development/product_qualified_lead_guide/index.md
+++ b/doc/development/product_qualified_lead_guide/index.md
@@ -95,16 +95,16 @@ The `ctaTracking` parameters follow [the `data-track` attributes](../snowplow/im
When embedding a new hand raise form, use a unique `glmContent` or `glm_content` field that is different to any existing values.
-We currently use the following `glm content` values:
-
-| glm_content value | Notes |
-| ------ | ------ |
-| discover-group-security | This value is used in the group security feature discovery page. |
-| discover-group-security-pqltest | This value is used in the group security feature discovery page [experiment with 3 CTAs](https://gitlab.com/gitlab-org/gitlab/-/issues/349799). |
-| discover-project-security | This value is used in the project security feature discovery page. |
-| discover-project-security-pqltest | This value is used in the project security feature discovery page [experiment with 3 CTAs](https://gitlab.com/gitlab-org/gitlab/-/issues/349799). |
-| group-billing | This value is used in the group billing page. |
-| trial-status-show-group | This value is used in the top left nav when a namespace has an active trial. |
+We currently use the following `glm_content` values:
+
+| `glm_content` value | Notes |
+|-------------------------------------|-------|
+| `discover-group-security` | This value is used in the group security feature discovery page. |
+| `discover-group-security-pqltest` | This value is used in the group security feature discovery page [experiment with 3 CTAs](https://gitlab.com/gitlab-org/gitlab/-/issues/349799). |
+| `discover-project-security` | This value is used in the project security feature discovery page. |
+| `discover-project-security-pqltest` | This value is used in the project security feature discovery page [experiment with 3 CTAs](https://gitlab.com/gitlab-org/gitlab/-/issues/349799). |
+| `group-billing` | This value is used in the group billing page. |
+| `trial-status-show-group` | This value is used in the top left nav when a namespace has an active trial. |
### Test the component
diff --git a/doc/development/profiling.md b/doc/development/profiling.md
index d2baf720b30..715ffc969fa 100644
--- a/doc/development/profiling.md
+++ b/doc/development/profiling.md
@@ -21,7 +21,7 @@ The first argument to the profiler is either a full URL
leading slash.
By default the report dump will be stored in a temporary file, which can be
-interacted with using the [stackprof API](#reading-a-gitlabprofiler-report).
+interacted with using the [Stackprof API](#reading-a-gitlabprofiler-report).
When using the script, command-line documentation is available by passing no
arguments.
@@ -62,7 +62,7 @@ Pass in a `profiler_options` hash to configure the output file (`out`) of the sa
Gitlab::Profiler.profile('/gitlab-org/gitlab-test', user: User.first, profiler_options: { out: 'tmp/profile.dump' })
```
-## Reading a GitLab::Profiler report
+## Reading a `GitLab::Profiler` report
You can get a summary of where time was spent by running Stackprof against the sampling data. For example:
diff --git a/doc/development/redis/new_redis_instance.md b/doc/development/redis/new_redis_instance.md
index d9d4bb6a9f8..0a030a0877f 100644
--- a/doc/development/redis/new_redis_instance.md
+++ b/doc/development/redis/new_redis_instance.md
@@ -181,7 +181,7 @@ and the [old (fallback-instance)](#fallback-instance).
If we fail to fetch data from the new instance, we will fallback and read from the old Redis instance.
We can monitor logs for `Gitlab::Redis::MultiStore::ReadFromPrimaryError`, and also the Prometheus counter `gitlab_redis_multi_store_read_fallback_total`.
-For pipelined commands (`pipelined` and `multi`), we execute the entire operation in both stores and then compare the results. If they differ, we emit a
+For `pipelined` commands (`pipelined` and `multi`), we execute the entire operation in both stores and then compare the results. If they differ, we emit a
`Gitlab::Redis::MultiStore:PipelinedDiffError` error, and track it in the `gitlab_redis_multi_store_pipelined_diff_error_total` Prometheus counter.
Once we stop seeing those errors, this means that we are no longer relying on the data stored on the old Redis store.
@@ -218,7 +218,7 @@ MultiStore implements read and write Redis commands separately.
- `flushdb`
- `rpush`
-##### Pipelined commands
+##### `pipelined` commands
**NOTE:** The Ruby block passed to these commands will be executed twice, once per each store.
Thus, excluding the Redis operations performed, the block should be idempotent.
@@ -238,16 +238,16 @@ a developer will need to add an implementation for missing Redis commands before
| error | message |
|---------------------------------------------------|---------------------------------------------------------------------------------------------|
| `Gitlab::Redis::MultiStore::ReadFromPrimaryError` | Value not found on the Redis primary store. Read from the Redis secondary store successful. |
-| `Gitlab::Redis::MultiStore::PipelinedDiffError` | Pipelined command executed on both stores successfully but results differ between them. |
+| `Gitlab::Redis::MultiStore::PipelinedDiffError` | `pipelined` command executed on both stores successfully but results differ between them. |
| `Gitlab::Redis::MultiStore::MethodMissingError` | Method missing. Falling back to execute method on the Redis secondary store. |
##### Metrics
-| metrics name | type | labels | description |
-|-------------------------------------------------------|--------------------|------------------------|--------------------------------------------------------|
-| `gitlab_redis_multi_store_read_fallback_total` | Prometheus Counter | command, instance_name | Client side Redis MultiStore reading fallback total |
-| `gitlab_redis_multi_store_pipelined_diff_error_total` | Prometheus Counter | command, instance_name | Redis MultiStore pipelined command diff between stores |
-| `gitlab_redis_multi_store_method_missing_total` | Prometheus Counter | command, instance_name | Client side Redis MultiStore method missing total |
+| Metrics name | Type | Labels | Description |
+|-------------------------------------------------------|--------------------|----------------------------|----------------------------------------------------------|
+| `gitlab_redis_multi_store_read_fallback_total` | Prometheus Counter | `command`, `instance_name` | Client side Redis MultiStore reading fallback total |
+| `gitlab_redis_multi_store_pipelined_diff_error_total` | Prometheus Counter | `command`, `instance_name` | Redis MultiStore `pipelined` command diff between stores |
+| `gitlab_redis_multi_store_method_missing_total` | Prometheus Counter | `command`, `instance_name` | Client side Redis MultiStore method missing total |
## Step 4: clean up after the migration
diff --git a/doc/development/sec/analyzer_development_guide.md b/doc/development/sec/analyzer_development_guide.md
index af3a6f2b7d7..4fb32785b9f 100644
--- a/doc/development/sec/analyzer_development_guide.md
+++ b/doc/development/sec/analyzer_development_guide.md
@@ -21,7 +21,7 @@ There are a number of shared Go modules shared across analyzers for common behav
## How to use the analyzers
Analyzers are shipped as Docker images. For example, to run the
-[semgrep](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep) Docker image to scan the working directory:
+[Semgrep](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep) Docker image to scan the working directory:
1. `cd` into the directory of the source code you want to scan.
1. Run `docker login registry.gitlab.com` and provide username plus
diff --git a/doc/development/service_ping/implement.md b/doc/development/service_ping/implement.md
index 5a564b2d83e..70da97502bb 100644
--- a/doc/development/service_ping/implement.md
+++ b/doc/development/service_ping/implement.md
@@ -181,7 +181,7 @@ The highest encountered error rate is 4.9%.
When correctly used, the `estimate_batch_distinct_count` method enables efficient counting over
columns that contain non-unique values, which cannot be assured by other counters.
-##### estimate_batch_distinct_count method
+##### `estimate_batch_distinct_count` method
Method:
@@ -316,7 +316,7 @@ HyperLogLog (HLL) is a probabilistic algorithm and its **results always includes
used HLL implementation is "approximated with a standard error of 0.81%".
NOTE:
- A user's consent for usage_stats (`User.single_user&.requires_usage_stats_consent?`) is not checked during the data tracking stage due to performance reasons. Keys corresponding to those counters are present in Redis even if `usage_stats_consent` is still required. However, no metric is collected from Redis and reported back to GitLab as long as `usage_stats_consent` is required.
+ A user's consent for `usage_stats` (`User.single_user&.requires_usage_stats_consent?`) is not checked during the data tracking stage due to performance reasons. Keys corresponding to those counters are present in Redis even if `usage_stats_consent` is still required. However, no metric is collected from Redis and reported back to GitLab as long as `usage_stats_consent` is required.
With `Gitlab::UsageDataCounters::HLLRedisCounter` we have available data structures used to count unique values.
@@ -509,7 +509,7 @@ We have the following recommendations for [adding new events](#add-new-events):
Events are tracked behind optional [feature flags](../feature_flags/index.md) due to concerns for Redis performance and scalability.
-For a full list of events and corresponding feature flags see, [known_events](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/) files.
+For a full list of events and corresponding feature flags, see the [`known_events/`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/) files.
To enable or disable tracking for specific event in <https://gitlab.com> or <https://about.staging.gitlab.com>, run commands such as the following to
[enable or disable the corresponding feature](../feature_flags/index.md).
@@ -870,7 +870,7 @@ these steps:
Only metrics calculated with [Estimated Batch Counters](#estimated-batch-counters)
can be persisted for database sourced aggregated metrics. To persist a metric,
inject a Ruby block into the
-[estimate_batch_distinct_count](#estimate_batch_distinct_count-method) method.
+[`estimate_batch_distinct_count`](#estimate_batch_distinct_count-method) method.
This block should invoke the
`Gitlab::Usage::Metrics::Aggregates::Sources::PostgresHll.save_aggregated_metrics`
[method](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage/metrics/aggregates/sources/postgres_hll.rb#L21),
diff --git a/doc/development/sidekiq/idempotent_jobs.md b/doc/development/sidekiq/idempotent_jobs.md
index 1487677ed75..1c4f4ba44a8 100644
--- a/doc/development/sidekiq/idempotent_jobs.md
+++ b/doc/development/sidekiq/idempotent_jobs.md
@@ -156,7 +156,7 @@ end
## Setting the deduplication time-to-live (TTL)
-Deduplication depends on an idempotency key that is stored in Redis. This is normally
+Deduplication depends on an idempotent key that is stored in Redis. This is normally
cleared by the configured deduplication strategy.
However, the key can remain until its TTL in certain cases like:
diff --git a/doc/development/snowplow/schemas.md b/doc/development/snowplow/schemas.md
index 5a6cdea9fee..da58cd5f2e5 100644
--- a/doc/development/snowplow/schemas.md
+++ b/doc/development/snowplow/schemas.md
@@ -68,8 +68,8 @@ Page titles are hardcoded as `GitLab` for the same reason.
| `doc_charset` | **{dotted-circle}** | string | Web page's character encoding |
| `doc_height` | **{dotted-circle}** | string | Web page height |
| `doc_width` | **{dotted-circle}** | string | Web page width |
-| `domain_sessionid` | **{dotted-circle}** | string | Unique identifier (UUID) for this visit of this user_id to this domain |
-| `domain_sessionidx` | **{dotted-circle}** | integer | Index of number of visits that this user_id has made to this domain (The first visit is `1`) |
+| `domain_sessionid` | **{dotted-circle}** | string | Unique identifier (UUID) for this visit of this `user_id` to this domain |
+| `domain_sessionidx` | **{dotted-circle}** | integer | Index of number of visits that this `user_id` has made to this domain (The first visit is `1`) |
| `domain_userid` | **{dotted-circle}** | string | Unique identifier for a user, based on a first party cookie (so domain specific) |
| `dvce_created_tstamp` | **{dotted-circle}** | timestamp | Timestamp when event occurred, as recorded by client device |
| `dvce_ismobile` | **{dotted-circle}** | boolean | Indicates whether device is mobile |
diff --git a/doc/development/snowplow/troubleshooting.md b/doc/development/snowplow/troubleshooting.md
index 306040f8c9c..47df3e43d57 100644
--- a/doc/development/snowplow/troubleshooting.md
+++ b/doc/development/snowplow/troubleshooting.md
@@ -35,7 +35,7 @@ Drop occurring at application layer can be symptom of some issue, but it might b
or even a result of a public holiday in some regions of the world with a larger user-base. To verify if there is an underlying problem to solve, you can check following things:
1. Check `about.gitlab.com` website traffic on [Google Analytics](https://analytics.google.com/analytics/web/) to verify if some public holiday might impact overall use of GitLab system
- 1. You may require to open an access request for Google Analytics access first eg: [access request internal issue](https://gitlab.com/gitlab-com/team-member-epics/access-requests/-/issues/1772)
+ 1. You may require to open an access request for Google Analytics access first, for example: [access request internal issue](https://gitlab.com/gitlab-com/team-member-epics/access-requests/-/issues/1772)
1. Plot `select date(dvce_created_tstamp) , event , count(*) from legacy.snowplow_unnested_events_90 where dvce_created_tstamp > '2021-06-15' and dvce_created_tstamp < '2021-07-10' group by 1 , 2 order by 1 , 2` in SiSense to see what type of events was responsible for drop
1. Plot `select date(dvce_created_tstamp) ,se_category , count(*) from legacy.snowplow_unnested_events_90 where dvce_created_tstamp > '2021-06-15' and dvce_created_tstamp < '2021-07-31' and event = 'struct' group by 1 , 2 order by 1, 2` what events recorded the biggest drops in suspected category
1. Check if there was any MR merged that might cause reduction in reported events, pay an attention to ~"product intelligence" and ~"growth experiment" labeled MRs
diff --git a/doc/development/testing_guide/best_practices.md b/doc/development/testing_guide/best_practices.md
index 771de6c8015..15307dfe06c 100644
--- a/doc/development/testing_guide/best_practices.md
+++ b/doc/development/testing_guide/best_practices.md
@@ -1440,7 +1440,7 @@ or [cause the universe to implode](../contributing/verify/index.md#do-not-cause-
### Factories
-GitLab uses [factory_bot](https://github.com/thoughtbot/factory_bot) as a test fixture replacement.
+GitLab uses [`factory_bot`](https://github.com/thoughtbot/factory_bot) as a test fixture replacement.
- Factory definitions live in `spec/factories/`, named using the pluralization
of their corresponding model (`User` factories are defined in `users.rb`).
diff --git a/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md b/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md
index 801de87721e..c1389b3ac0e 100644
--- a/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md
+++ b/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md
@@ -15,7 +15,7 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec
|-----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `:elasticsearch` | The test requires an Elasticsearch service. It is used by the [instance-level scenario](https://gitlab.com/gitlab-org/gitlab-qa#definitions) [`Test::Integration::Elasticsearch`](https://gitlab.com/gitlab-org/gitlab/-/blob/72b62b51bdf513e2936301cb6c7c91ec27c35b4d/qa/qa/ee/scenario/test/integration/elasticsearch.rb) to include only tests that require Elasticsearch. |
| `:except` | The test is to be run in their typical execution contexts _except_ as specified. See [test execution context selection](execution_context_selection.md) for more information. |
-| `:feature_flag` | The test uses a feature flag and therefore requires an administrator account to run. When `scope` is set to `:global`, the test will be skipped on all live .com environments. Otherwise, it will be skipped only on Canary, Production, and Preprod. See [testing with feature flags](../../../development/testing_guide/end_to_end/feature_flags.md) for more details. |
+| `:feature_flag` | The test uses a feature flag and therefore requires an administrator account to run. When `scope` is set to `:global`, the test will be skipped on all live .com environments. Otherwise, it will be skipped only on Canary, Production, and Pre-production. See [testing with feature flags](../../../development/testing_guide/end_to_end/feature_flags.md) for more details. |
| `:framework` | The test makes sanity assertions around the QA framework itself |
| `:geo` | The test requires two GitLab Geo instances - a primary and a secondary - to be spun up. |
| `:gitaly_cluster` | The test runs against a GitLab instance where repositories are stored on redundant Gitaly nodes behind a Praefect node. All nodes are [separate containers](../../../administration/gitaly/praefect.md#requirements). Tests that use this tag have a longer setup time since there are three additional containers that need to be started. |
diff --git a/doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md b/doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md
index 81e1c7d5dc0..4a947e59d5f 100644
--- a/doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md
+++ b/doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md
@@ -15,8 +15,8 @@ The project also has instructions for forking and building the images automatica
Some extra environment variables for the location of the forked repository are also needed.
-- `QA_THIRD_PARTY_DOCKER_REGISTRY` (the container registry where the repository/images are hosted, eg `registry.gitlab.com`)
-- `QA_THIRD_PARTY_DOCKER_REPOSITORY` (the base repository path where the images are hosted, eg `registry.gitlab.com/<project path>`)
+- `QA_THIRD_PARTY_DOCKER_REGISTRY` (the container registry where the repository/images are hosted, for example `registry.gitlab.com`)
+- `QA_THIRD_PARTY_DOCKER_REPOSITORY` (the base repository path where the images are hosted, for example `registry.gitlab.com/<project path>`)
- `QA_THIRD_PARTY_DOCKER_USER` (a username that has access to the container registry for this repository)
- `QA_THIRD_PARTY_DOCKER_PASSWORD` (a password/token for the username to authenticate with)
diff --git a/doc/operations/incident_management/incidents.md b/doc/operations/incident_management/incidents.md
index 67a0dba1e1b..de9b7d63369 100644
--- a/doc/operations/incident_management/incidents.md
+++ b/doc/operations/incident_management/incidents.md
@@ -312,13 +312,6 @@ In GitLab 15.1 and earlier, the escalation policy for [incidents created from al
reflects the alert's escalation policy and cannot be changed. In [GitLab 15.2 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/356057),
the incident escalation policy is independent and can be changed.
-## Manage incidents from Slack
-
-Slack slash commands allow you to control GitLab and view GitLab content without leaving Slack.
-
-Learn how to [set up Slack slash commands](../../user/project/integrations/slack_slash_commands.md)
-and how to [use the available slash commands](../../integration/slash_commands.md).
-
## Associate Zoom calls
GitLab enables you to [associate a Zoom meeting with an issue](../../user/project/issues/associate_zoom_meeting.md)
@@ -363,3 +356,7 @@ With at least the Maintainer role, you can enable
When GitLab receives a **Recovery Alert**, it closes the associated incident.
This action is recorded as a system message on the incident indicating that it
was closed automatically by the GitLab Alert bot.
+
+## Related topics
+
+- Create incidents and receive incident notifications [directly from Slack](slack.md).
diff --git a/doc/operations/incident_management/integrations.md b/doc/operations/incident_management/integrations.md
index a54556bd3a2..d0d4ee6e498 100644
--- a/doc/operations/incident_management/integrations.md
+++ b/doc/operations/incident_management/integrations.md
@@ -164,7 +164,7 @@ curl --request POST \
The authorization key can be used as the `password`. The `username` is left blank:
- username: `<blank>`
-- password: authorization_key
+- password: `<authorization_key>`
```shell
curl --request POST \
diff --git a/doc/operations/incident_management/paging.md b/doc/operations/incident_management/paging.md
index dcb17048d35..9ce87d03686 100644
--- a/doc/operations/incident_management/paging.md
+++ b/doc/operations/incident_management/paging.md
@@ -14,12 +14,11 @@ notifications using the methods described on this page.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216326) in GitLab 13.1.
-Responders can be paged via Slack using the
-[Slack Notifications Service](../../user/project/integrations/slack.md), which you
-can configure for new alerts and new incidents. After configuring, responders
-receive a **single** page via Slack. To set up Slack notifications on your mobile
-device, make sure to enable notifications for the Slack app on your phone so
-you never miss a page.
+The GitLab for Slack app can be used to receive important incident notifications.
+
+When [the GitLab for Slack app is configured](slack.md), incident responders are notified in Slack
+every time a new incident is declared. To ensure you don't miss any important incident notifications
+on your mobile device, enable notifications for Slack on your phone.
## Email notifications for alerts
diff --git a/doc/operations/incident_management/slack.md b/doc/operations/incident_management/slack.md
new file mode 100644
index 00000000000..37cfb790d70
--- /dev/null
+++ b/doc/operations/incident_management/slack.md
@@ -0,0 +1,117 @@
+---
+stage: Monitor
+group: Respond
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
+---
+
+# Incident management for Slack **(FREE SAAS)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/344856) in GitLab 15.7 [with a flag](../../administration/feature_flags.md) named `incident_declare_slash_command`. 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](../../administration/feature_flags.md) named `incident_declare_slash_command`.
+On GitLab.com, this feature is not available.
+The feature is not ready for production use.
+
+Many teams receive alerts and collaborate in real time during incidents in Slack.
+Use the GitLab for Slack app to:
+
+- Create GitLab incidents from Slack.
+- Receive incident notifications.
+<!-- The below content is commented out until these features are implemented in https://gitlab.com/groups/gitlab-org/-/epics/8545 -->
+<!-- - Send important updates between Slack and GitLab incidents. -->
+
+Incident management for Slack is only available for GitLab.com. Some of the functionality
+described might be available for
+[the self-managed Slack app](../../user/project/integrations/slack_slash_commands.md).
+
+To stay up to date, follow [epic 1211](https://gitlab.com/groups/gitlab-org/-/epics/1211).
+
+## Manage an incident from Slack
+
+Prerequisites:
+
+1. Install the [GitLab for Slack app](../../user/project/integrations/gitlab_slack_application.md).
+ This way, you can use slash commands in Slack to create and update GitLab incidents.
+1. Enable [Slack notifications](../../user/project/integrations/slack.md). Be sure to enable
+ notifications for `Issue` events, and to define a Slack channel to receive the relevant notifications.
+1. Authorize GitLab to take actions on behalf of your Slack user.
+ Each user must do this before they can use any of the incident slash commands.
+
+ To start the authorization flow, try executing a non-incident [Slack slash command](../../integration/slash_commands.md),
+ like `/gitlab <project-alias> issue show <id>`.
+ The `<project-alias>` you select must be a project that has the GitLab for Slack app set up.
+ For more context, visit [issue 377548](https://gitlab.com/gitlab-org/gitlab/-/issues/377548).
+
+<!-- The below content is commented out until these features are implemented in https://gitlab.com/groups/gitlab-org/-/epics/8545 -->
+<!--
+To manage incidents, use the following slash commands in Slack:
+
+| Command | Description |
+| ---------------------------------- | ------------------------------------------- |
+| `/gitlab incident declare` | Creates an incident in GitLab. |
+| `/gitlab incident comment <text>` | Adds a comment on a GitLab incident. |
+| `/gitlab incident timeline <text>` | Adds a timeline event to a GitLab incident. |
+| `/gitlab incident close` | Closes an incident in GitLab. |
+-->
+
+After the GitLab for Slack app is configured, you can also use any of the existing [Slack slash commands](../../user/project/integrations/slack_slash_commands.md).
+
+## Declare an incident
+
+To declare a GitLab incident from Slack:
+
+1. In Slack, in any channel or DM, enter the `/gitlab incident declare` slash command.
+1. From the modal, select the relevant incident details, including:
+
+ - The incident title and description.
+ - The project where the incident should be created.
+ - The severity of the incident.
+
+ If there is an existing [incident template](incidents.md#create-incidents-automatically) for your
+ project, that template is automatically applied to the description text box. The template is applied
+ only if the description text box is empty.
+
+ You can also include GitLab [quick actions](../../user/project/quick_actions.md) in the description text box.
+ For example, entering `/link https://example.slack.com/archives/123456789 Dedicated Slack channel`
+ adds a dedicated Slack channel to the incident you create. For a complete list of
+ quick actions for incidents, see [Use GitLab quick actions](#use-gitlab-quick-actions).
+1. Optional. Add a link to an existing Zoom meeting.
+1. Select **Create**.
+
+If the incident is successfully created, Slack shows a confirmation notification.
+
+### Use GitLab quick actions
+
+Use [quick actions](../../user/project/quick_actions.md) in the description text box when creating
+a GitLab incident from Slack. The following quick actions might be most relevant to you:
+
+| Command | Description |
+| ------------------------ | ----------------------------------------- |
+| `/assign @user1 @user2` | Adds an assignee to the GitLab incident. |
+| `/label ~label1 ~label2` | Adds labels to the GitLab incident. |
+| `/link <URL> <text>` | Adds a link to a dedicated Slack channel, runbook, or any relevant resource to the `Related resources` section of an incident. |
+| `/zoom <URL>` | Adds a Zoom meeting link to the incident. |
+
+<!-- The below content is commented out until these features are implemented in https://gitlab.com/groups/gitlab-org/-/epics/8545 -->
+<!-- ### Comment on a GitLab incident
+
+To comment on a GitLab incident from Slack, enter the `/gitlab incident comment <text>` slash command.
+Slack shows a prompt asking you to confirm which incident you'd like to post your comment to.
+
+### Add a timeline event
+
+To add a [timeline event](incident_timeline_events.md) to a GitLab incident from Slack, enter the
+`/gitlab incident timeline <text>` slash command.
+Slack shows a prompt asking you to confirm which incident you'd like to add your timeline event to.
+
+### Close an incident
+
+To close a GitLab incident from Slack when it is resolved, enter the `/gitlab incident close`
+slash command.
+Slack shows a prompt asking you to confirm which incident you'd like to close. -->
+
+## Send GitLab incident notifications to Slack
+
+If you have [enabled notifications](#manage-an-incident-from-slack) for issues, you should receive
+notifications to the selected Slack channel every time an incident is opened, closed, or updated.
diff --git a/doc/operations/metrics/dashboards/panel_types.md b/doc/operations/metrics/dashboards/panel_types.md
index 71a7dff3b46..177a55fb85b 100644
--- a/doc/operations/metrics/dashboards/panel_types.md
+++ b/doc/operations/metrics/dashboards/panel_types.md
@@ -201,10 +201,10 @@ panel_groups:
Note the following properties:
| Property | Type | Required | Description |
-| ------ | ------ | ------ | ------ |
-| type | string | yes | Type of panel to be rendered. For single stat panel types, set to `single-stat` |
-| field | string | no | Panels display the value of a metric. For a panel to display the value of a label instead, put the name of the label in this key. |
-| query | string | yes | For single stat panel types, you must use an [instant query](https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries) |
+| ------- | ------ | ------ | ------ |
+| `type` | string | yes | Type of panel to be rendered. For single stat panel types, set to `single-stat` |
+| `field` | string | no | Panels display the value of a metric. For a panel to display the value of a label instead, put the name of the label in this key. |
+| `query` | string | yes | For single stat panel types, you must use an [instant query](https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries). |
![single stat panel type](img/prometheus_dashboard_single_stat_panel_type.png)
@@ -263,15 +263,15 @@ panel_groups:
Note the following properties:
-| Property | Type | Required | Description |
-| ------ | ------ | ------ | ------ |
-| type | string | yes | Type of panel to be rendered. For gauge panel types, set to `gauge`. |
-| min_value | number | no, defaults to `0` | The minimum value of the gauge chart axis. If either of `min_value` or `max_value` are not set, they both get their default values. |
-| max_value | number | no, defaults to `100` | The maximum value of the gauge chart axis. If either of `min_value` or `max_value` are not set, they both get their default values. |
-| split | number | no, defaults to `10` | The amount of split segments on the gauge chart axis. |
-| thresholds | object | no | Thresholds configuration for the gauge chart axis. |
-| format | string | no, defaults to `engineering` | Unit format used. See the [full list of units](yaml_number_format.md). |
-| query | string | yes | For gauge panel types, you must use an [instant query](https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries). |
+| Property | Type | Required | Description |
+| ------------ | ------ | ------ | ------ |
+| `type` | string | yes | Type of panel to be rendered. For gauge panel types, set to `gauge`. |
+| `min_value` | number | no, defaults to `0` | The minimum value of the gauge chart axis. If either of `min_value` or `max_value` are not set, they both get their default values. |
+| `max_value` | number | no, defaults to `100` | The maximum value of the gauge chart axis. If either of `min_value` or `max_value` are not set, they both get their default values. |
+| `split` | number | no, defaults to `10` | The amount of split segments on the gauge chart axis. |
+| `thresholds` | object | no | Thresholds configuration for the gauge chart axis. |
+| `format` | string | no, defaults to `engineering` | Unit format used. See the [full list of units](yaml_number_format.md). |
+| `query` | string | yes | For gauge panel types, you must use an [instant query](https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries). |
### Thresholds properties
@@ -314,4 +314,4 @@ Note the following properties:
WARNING:
When a query returns too many data points, the heatmap data bucket dimensions tend downwards to 0, making the chart's data invisible, as shown in the image below. To fix this problem, limit the amount of data returned by changing the time range filter on the metrics dashboard UI, or adding the **step** property to your dashboard's YAML file.
-![heatmap chart_too_much_data](img/heatmap_chart_too_much_data_v_13_2.png)
+![heatmap chart with too much data](img/heatmap_chart_too_much_data_v_13_2.png)
diff --git a/doc/operations/metrics/dashboards/variables.md b/doc/operations/metrics/dashboards/variables.md
index 5cd4dcdfa17..2881c084115 100644
--- a/doc/operations/metrics/dashboards/variables.md
+++ b/doc/operations/metrics/dashboards/variables.md
@@ -38,7 +38,7 @@ must be lowercase. The supported variables are:
- `ci_environment_name`
- `__range`
-### environment_filter
+### `environment_filter`
`environment_filter` is automatically expanded to `container_name!="POD",environment="ENVIRONMENT_NAME"`
where `ENVIRONMENT_NAME` is the name of the current environment.
@@ -46,7 +46,7 @@ where `ENVIRONMENT_NAME` is the name of the current environment.
For example, a Prometheus query like `container_memory_usage_bytes{ {{environment_filter}} }`
becomes `container_memory_usage_bytes{ container_name!="POD",environment="production" }`.
-### __range
+### `__range`
The `__range` variable is useful in Prometheus
[range vector selectors](https://prometheus.io/docs/prometheus/latest/querying/basics/#range-vector-selectors).
diff --git a/doc/operations/metrics/dashboards/yaml.md b/doc/operations/metrics/dashboards/yaml.md
index 399a8ecb615..68eddc6f087 100644
--- a/doc/operations/metrics/dashboards/yaml.md
+++ b/doc/operations/metrics/dashboards/yaml.md
@@ -156,7 +156,7 @@ To confirm your dashboard definition contains valid YAML syntax:
Files with valid syntax display **Metrics Dashboard YAML definition is valid**,
and files with invalid syntax display **Metrics Dashboard YAML definition is invalid**.
-![Metrics Dashboard_YAML_syntax_validation](img/prometheus_dashboard_yaml_validation_v13_1.png)
+![Metrics dashboard YAML syntax validation](img/prometheus_dashboard_yaml_validation_v13_1.png)
When **Metrics Dashboard YAML definition is invalid** at least one of the following messages is displayed:
diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md
index 2ac79a913f3..de69e6f2c27 100644
--- a/doc/raketasks/backup_restore.md
+++ b/doc/raketasks/backup_restore.md
@@ -887,7 +887,7 @@ Truncate the filenames in the `uploads` table:
- `current_filename`: a filename that is currently more than 246 characters long.
- `new_filename`: a filename that has been truncated to 246 characters maximum.
- - `new_path`: new path considering the new_filename (truncated).
+ - `new_path`: new path considering the `new_filename` (truncated).
Once you validate the batch results, you must change the batch size (`row_id`) using the following sequence of numbers (10000 to 20000). Repeat this process until you reach the last record in the `uploads` table.
diff --git a/doc/subscriptions/img/add-license.png b/doc/subscriptions/img/add-license.png
index 3efb318971c..157f0921796 100644
--- a/doc/subscriptions/img/add-license.png
+++ b/doc/subscriptions/img/add-license.png
Binary files differ
diff --git a/doc/topics/awesome_co.md b/doc/topics/awesome_co.md
index 49e39542b2b..fc5f79b4d18 100644
--- a/doc/topics/awesome_co.md
+++ b/doc/topics/awesome_co.md
@@ -71,7 +71,7 @@ AwesomeCo seeding uses FactoryBot definitions from `spec/factories` which ...
1. Are always up-to-date
1. Execute on the lowest-level (`ActiveRecord`) possible to create data as quickly as possible
-> _from the [FactoryBot README](https://github.com/thoughtbot/factory_bot#readme_) : factory_bot is a fixtures replacement with a straightforward definition syntax, support for multiple build
+> From the [FactoryBot README](https://github.com/thoughtbot/factory_bot#readme_) : `factory_bot` is a fixtures replacement with a straightforward definition syntax, support for multiple build
> strategies (saved instances, unsaved instances, attribute hashes, and stubbed objects), and support for multiple factories for the same class, including factory
> inheritance
diff --git a/doc/update/index.md b/doc/update/index.md
index 33545c05d89..a90323d13bf 100644
--- a/doc/update/index.md
+++ b/doc/update/index.md
@@ -477,10 +477,26 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap
To upgrade to this version, no records with a `NULL` `work_item_type_id` should exist on the `issues` table.
There are multiple `BackfillWorkItemTypeIdForIssues` background migrations that will be finalized with
the `EnsureWorkItemTypeBackfillMigrationFinished` post-deploy migration.
-- GitLab 15.7.0 introduced a [batched background migration](#batched-background-migrations) to
+- GitLab 15.4.0 introduced a [batched background migration](#batched-background-migrations) to
[backfill `namespace_id` values on issues table](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91921). This
migration might take multiple hours or days to complete on larger GitLab instances. Please make sure the migration
has completed successfully before upgrading to 15.7.0.
+- A database constraint is added, specifying that the `namespace_id` column on the issues
+ table has no `NULL` values.
+
+ - If the `namespace_id` batched background migration from 15.4 failed (see above) then the 15.7 upgrade
+ fails with a database migration error.
+
+ - On GitLab instances with large issues tables, validating this constraint causes the upgrade to take
+ longer than usual. All database changes need to complete within a one-hour limit:
+
+ ```plaintext
+ FATAL: Mixlib::ShellOut::CommandTimeout: rails_migration[gitlab-rails]
+ [..]
+ Mixlib::ShellOut::CommandTimeout: Command timed out after 3600s:
+ ```
+
+ A workaround exists to [complete the data change and the upgrade manually](package/index.md#mixlibshelloutcommandtimeout-rails_migrationgitlab-rails--command-timed-out-after-3600s).
- The default Sidekiq `max_concurrency` has been changed to 20. This is now
consistent in our documentation and product defaults.
@@ -530,6 +546,10 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap
In a highly available or GitLab Geo environment, secrets need to be the same on all nodes.
If you're manually syncing the secrets file across nodes, or manually specifying secrets in
`/etc/gitlab/gitlab.rb`, make sure `/etc/gitlab/gitlab-secrets.json` is the same on all nodes.
+- GitLab 15.4.0 introduced a [batched background migration](#batched-background-migrations) to
+ [backfill `namespace_id` values on issues table](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91921). This
+ migration might take multiple hours or days to complete on larger GitLab instances. Please make sure the migration
+ has completed successfully before upgrading to 15.7.0 or later.
### 15.3.3
diff --git a/doc/user/application_security/dast/checks/16.3.md b/doc/user/application_security/dast/checks/16.3.md
index d9e6f6f8d92..d1799baa517 100644
--- a/doc/user/application_security/dast/checks/16.3.md
+++ b/doc/user/application_security/dast/checks/16.3.md
@@ -32,4 +32,4 @@ information from the `X-Powered-By` header.
## Links
- [CWE](https://cwe.mitre.org/data/definitions/16.html)
-- [PHP expose_php](https://www.php.net/manual/en/ini.core.php#ini.expose-php)
+- [PHP `expose_php`](https://www.php.net/manual/en/ini.core.php#ini.expose-php)
diff --git a/doc/user/compliance/license_compliance/index.md b/doc/user/compliance/license_compliance/index.md
index fb5ce37c563..ca079e9e1af 100644
--- a/doc/user/compliance/license_compliance/index.md
+++ b/doc/user/compliance/license_compliance/index.md
@@ -177,7 +177,7 @@ directory of your project.
Depending on your language, you may need to specify the path to the individual
projects of a monorepo using the `LICENSE_FINDER_CLI_OPTS` variable. Passing in
the project paths can significantly speed up builds over using the `--recursive`
-license_finder option.
+License Finder option.
```yaml
include:
diff --git a/doc/user/infrastructure/iac/terraform_template_recipes.md b/doc/user/infrastructure/iac/terraform_template_recipes.md
index 99c0a442177..a86ab35e9c6 100644
--- a/doc/user/infrastructure/iac/terraform_template_recipes.md
+++ b/doc/user/infrastructure/iac/terraform_template_recipes.md
@@ -10,7 +10,7 @@ You can customize your Terraform integration by adding the recipes on
this page to your pipeline.
If you'd like to share your own Terraform configuration, consider
-[contributing a recipe](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/infrastructure/iac/tf_template_recipes.md)
+[contributing a recipe](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/infrastructure/iac/terraform_template_recipes.md)
to this page.
## Enable a `terraform destroy` job
diff --git a/doc/user/packages/helm_repository/index.md b/doc/user/packages/helm_repository/index.md
index bba68494c2d..785ef344c8e 100644
--- a/doc/user/packages/helm_repository/index.md
+++ b/doc/user/packages/helm_repository/index.md
@@ -72,7 +72,7 @@ Once built, a chart can be uploaded to the desired channel with `curl` or `helm
### Release channels
You can publish Helm charts to channels in GitLab. Channels are a method you can use to differentiate Helm chart repositories.
-For example, you can use `stable` and `devel` as channels to allow users to add the `stable` repo while `devel` charts are isolated.
+For example, you can use `stable` and `devel` as channels to allow users to add the `stable` repository while `devel` charts are isolated.
## Use CI/CD to publish a Helm package
diff --git a/doc/user/packages/terraform_module_registry/index.md b/doc/user/packages/terraform_module_registry/index.md
index d3e67175ca2..9b09d846034 100644
--- a/doc/user/packages/terraform_module_registry/index.md
+++ b/doc/user/packages/terraform_module_registry/index.md
@@ -134,7 +134,7 @@ upload:
- if: $CI_COMMIT_TAG
```
-To trigger this upload job, add a Git tag to your commit. Ensure the tag follows the [Semantic Versioning Specification](https://semver.org/) that Terraform requires. The `rules:if: $CI_COMMIT_TAG` ensures that only tagged commits to your repo trigger the module upload job.
+To trigger this upload job, add a Git tag to your commit. Ensure the tag follows the [Semantic Versioning Specification](https://semver.org/) that Terraform requires. The `rules:if: $CI_COMMIT_TAG` ensures that only tagged commits to your repository trigger the module upload job.
For other ways to control jobs in your CI/CD pipeline, refer to the [`.gitlab-ci.yml`](../../../ci/yaml/index.md) keyword reference.
## Example projects
diff --git a/doc/user/project/import/bitbucket.md b/doc/user/project/import/bitbucket.md
index 3f1a2dcfe2b..98b46650b42 100644
--- a/doc/user/project/import/bitbucket.md
+++ b/doc/user/project/import/bitbucket.md
@@ -104,7 +104,7 @@ current Bitbucket public name, and reconnect if there's a mismatch:
1. [Use the API to get the currently authenticated user](../../../api/users.md#for-normal-users-1).
-1. In the API's response, the `identities` attribute contains the Bitbucket account that exists in
+1. In the API response, the `identities` attribute contains the Bitbucket account that exists in
the GitLab database. If the `extern_uid` doesn't match the current Bitbucket public name, the
user should reconnect their Bitbucket account in the [GitLab profile service sign-in](https://gitlab.com/-/profile/account).
diff --git a/doc/user/project/import/github.md b/doc/user/project/import/github.md
index 6b34908c20c..f5d9d4cf5f1 100644
--- a/doc/user/project/import/github.md
+++ b/doc/user/project/import/github.md
@@ -279,7 +279,7 @@ Feature.disable(:github_importer_lower_per_page_limit, group)
## Import from GitHub Enterprise on an internal network
-If your GitHub Enterprise instance is on a internal network that is unaccessible to the internet, you can use a reverse proxy
+If your GitHub Enterprise instance is on a internal network that is inaccessible to the internet, you can use a reverse proxy
to allow GitLab.com to access the instance.
The proxy needs to:
diff --git a/doc/user/project/integrations/mlflow_client.md b/doc/user/project/integrations/mlflow_client.md
index e32e91c54ac..bd14021ab1c 100644
--- a/doc/user/project/integrations/mlflow_client.md
+++ b/doc/user/project/integrations/mlflow_client.md
@@ -50,7 +50,7 @@ that can be explored by selecting an experiment.
- The API GitLab supports is the one defined at MLFlow version 1.28.0.
- API endpoints not listed above are not supported.
- During creation of experiments and runs, tags are ExperimentTags and RunTags are stored, even though they are not displayed.
-- MLFLow Model Registry is not supported.
+- MLFlow Model Registry is not supported.
## Supported methods and caveats
@@ -59,7 +59,7 @@ tested. More information can be found in the [MLFlow Documentation](https://www.
### `set_experiment()`
-Accepts both experiment_name and experiment_id
+Accepts both `experiment_name` and `experiment_id`
### `start_run()`
diff --git a/doc/user/project/merge_requests/changes.md b/doc/user/project/merge_requests/changes.md
index 6e8b0cb1a75..f6e02dc0dfe 100644
--- a/doc/user/project/merge_requests/changes.md
+++ b/doc/user/project/merge_requests/changes.md
@@ -136,15 +136,10 @@ Files marked as viewed are not shown to you again unless either:
- New changes are made to its content.
- You clear the **Viewed** checkbox.
-## Show merge request conflicts in diff **(FREE SELF)**
+## Show merge request conflicts in diff
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/232484) in GitLab 13.5 [with a flag](../../../administration/feature_flags.md) named `display_merge_conflicts_in_diff`. 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](../../../administration/feature_flags.md)
-named `display_merge_conflicts_in_diff`. On GitLab.com, this feature is not available.
-The feature is not ready for production use.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/232484) in GitLab 13.5 [with a flag](../../../administration/feature_flags.md) named `display_merge_conflicts_in_diff`. Disabled by default.
+> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/276918) in GitLab 15.7.
To avoid displaying the changes that are already on target branch in the diff,
we compare the merge request's source branch with HEAD of the target branch.
diff --git a/doc/user/project/merge_requests/reviews/data_usage.md b/doc/user/project/merge_requests/reviews/data_usage.md
index a73780004d2..f17015aef4e 100644
--- a/doc/user/project/merge_requests/reviews/data_usage.md
+++ b/doc/user/project/merge_requests/reviews/data_usage.md
@@ -27,7 +27,7 @@ This feature is designed as a progressive enhancement to the existing GitLab Rev
## Model Accuracy
-Organizations use many different processes for code review. Some focus on senior engineers reviewing junior engineer's code, others have hierarchical organizational structure based reviews. Suggested Reviewers is focused on contextual reviewers based on historical merge request activity by users. While we will continue evolving the underlying ML model to better serve various code review use cases and processes Suggested Reviewers does not replace the usage of other code review features like Code Owners and [Approval Rules](../approvals/rules.md). Reviewer selection is highly subjective therefore, we do not expect Suggested Reviewers to provide perfect suggestions everytime.
+Organizations use many different processes for code review. Some focus on senior engineers reviewing junior engineer's code, others have hierarchical organizational structure based reviews. Suggested Reviewers is focused on contextual reviewers based on historical merge request activity by users. While we will continue evolving the underlying ML model to better serve various code review use cases and processes Suggested Reviewers does not replace the usage of other code review features like Code Owners and [Approval Rules](../approvals/rules.md). Reviewer selection is highly subjective therefore, we do not expect Suggested Reviewers to provide perfect suggestions every time.
Through analysis of beta customer usage, we find that the Suggested Reviewers ML model provides suggestions that are adopted in 60% of cases. We will be introducing a feedback mechanism into the Suggested Reviewers feature in the future to allow users to flag bad reviewer suggestions to help improve the model. Additionally we will be offering an opt-in feature in the future which will allow the model to use your project's data for training the underlying model.
diff --git a/doc/user/project/merge_requests/reviews/index.md b/doc/user/project/merge_requests/reviews/index.md
index 3a1e0099f0f..9a75c038dbc 100644
--- a/doc/user/project/merge_requests/reviews/index.md
+++ b/doc/user/project/merge_requests/reviews/index.md
@@ -77,6 +77,7 @@ To download the changes included in a merge request as a diff:
1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests**.
+1. Select your merge request.
1. On the top right, select **Code > Plain diff**.
If you know the URL of the merge request, you can also download the diff from
@@ -99,6 +100,7 @@ To download the changes included in a merge request as a patch file:
1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests**.
+1. Select your merge request.
1. On the top right, select **Code > Email patches**.
If you know the URL of the merge request, you can also download the patch from
diff --git a/doc/user/project/ml/experiment_tracking/img/candidate_v15_7.png b/doc/user/project/ml/experiment_tracking/img/candidate_v15_7.png
index c7a49ad7608..fb2e2e706d6 100644
--- a/doc/user/project/ml/experiment_tracking/img/candidate_v15_7.png
+++ b/doc/user/project/ml/experiment_tracking/img/candidate_v15_7.png
Binary files differ
diff --git a/doc/user/project/ml/experiment_tracking/img/candidates_v15_7.png b/doc/user/project/ml/experiment_tracking/img/candidates_v15_7.png
index fed749cbee3..58dfe94a108 100644
--- a/doc/user/project/ml/experiment_tracking/img/candidates_v15_7.png
+++ b/doc/user/project/ml/experiment_tracking/img/candidates_v15_7.png
Binary files differ
diff --git a/doc/user/project/ml/experiment_tracking/img/experiments_v15_7.png b/doc/user/project/ml/experiment_tracking/img/experiments_v15_7.png
index f2a9d79e47b..a7d4a3e559f 100644
--- a/doc/user/project/ml/experiment_tracking/img/experiments_v15_7.png
+++ b/doc/user/project/ml/experiment_tracking/img/experiments_v15_7.png
Binary files differ
diff --git a/doc/user/project/wiki/index.md b/doc/user/project/wiki/index.md
index eedc44be3f9..86272d96eb0 100644
--- a/doc/user/project/wiki/index.md
+++ b/doc/user/project/wiki/index.md
@@ -14,7 +14,7 @@ to keep it in the same project as your code, you can use the wiki GitLab provide
in each GitLab project. Every wiki is a separate Git repository, so you can create
wiki pages in the web interface, or [locally using Git](#create-or-edit-wiki-pages-locally).
-GitLab wikis support Markdown, RDoc, AsciiDoc, and Org for content.
+GitLab wikis support Markdown, Rdoc, AsciiDoc, and Org for content.
Wiki pages written in Markdown support all [Markdown features](../../markdown.md),
and also provide some [wiki-specific behavior](../../markdown.md#wiki-specific-markdown)
for links.
diff --git a/doc/user/search/index.md b/doc/user/search/index.md
index e27ce075e0a..93797656a71 100644
--- a/doc/user/search/index.md
+++ b/doc/user/search/index.md
@@ -58,7 +58,7 @@ You must type at least two characters.
After the results are displayed, you can modify the search, select a different type of data to
search, or choose a specific group or project.
-![basic_search_results](img/basic_search_results_v15_1.png)
+![basic search results](img/basic_search_results_v15_1.png)
## Search in code
diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb
index e419a025508..f7a39db7249 100644
--- a/lib/api/award_emoji.rb
+++ b/lib/api/award_emoji.rb
@@ -80,7 +80,7 @@ module API
delete "#{endpoint}/:award_id", feature_category: awardable_params[:feature_category] do
award = awardable.award_emoji.find(params[:award_id])
- unauthorized! unless award.user == current_user || current_user&.admin?
+ unauthorized! unless award.user == current_user || current_user&.can_admin_all_resources?
destroy_conditionally!(award)
end
diff --git a/lib/api/ci/runners.rb b/lib/api/ci/runners.rb
index 988c3f4f566..4a6c58b4987 100644
--- a/lib/api/ci/runners.rb
+++ b/lib/api/ci/runners.rb
@@ -58,19 +58,19 @@ module API
end
def authenticate_show_runner!(runner)
- return if runner.instance_type? || current_user.admin?
+ return if runner.instance_type? || current_user.can_read_all_resources?
forbidden!("No access granted") unless can?(current_user, :read_runner, runner)
end
def authenticate_update_runner!(runner)
- return if current_user.admin?
+ return if current_user.can_admin_all_resources?
forbidden!("No access granted") unless can?(current_user, :update_runner, runner)
end
def authenticate_delete_runner!(runner)
- return if current_user.admin?
+ return if current_user.can_admin_all_resources?
forbidden!("Runner associated with more than one project") if runner.runner_projects.count > 1
forbidden!("No access granted") unless can?(current_user, :delete_runner, runner)
@@ -79,14 +79,14 @@ module API
def authenticate_enable_runner!(runner)
forbidden!("Runner is a group runner") if runner.group_type?
- return if current_user.admin?
+ return if current_user.can_admin_all_resources?
forbidden!("Runner is locked") if runner.locked?
forbidden!("No access granted") unless can?(current_user, :assign_runner, runner)
end
def authenticate_list_runners_jobs!(runner)
- return if current_user.admin?
+ return if current_user.can_read_all_resources?
forbidden!("No access granted") unless can?(current_user, :read_builds, runner)
end
diff --git a/lib/api/entities/ci/runner_details.rb b/lib/api/entities/ci/runner_details.rb
index 9b1decca274..8aa134dc669 100644
--- a/lib/api/entities/ci/runner_details.rb
+++ b/lib/api/entities/ci/runner_details.rb
@@ -14,7 +14,7 @@ module API
# rubocop: disable CodeReuse/ActiveRecord
expose :projects, with: Entities::BasicProjectDetails do |runner, options|
- if options[:current_user].admin? # rubocop: disable Cop/UserAdmin
+ if options[:current_user].can_read_all_resources?
runner.projects
else
options[:current_user].authorized_projects.where(id: runner.runner_projects.pluck(:project_id))
@@ -23,7 +23,7 @@ module API
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
expose :groups, with: Entities::BasicGroupDetails do |runner, options|
- if options[:current_user].admin? # rubocop: disable Cop/UserAdmin
+ if options[:current_user].can_read_all_resources?
runner.groups
else
options[:current_user].authorized_groups.where(id: runner.runner_namespaces.pluck(:namespace_id))
diff --git a/lib/api/groups.rb b/lib/api/groups.rb
index f9842c01db2..23db10dbdbf 100644
--- a/lib/api/groups.rb
+++ b/lib/api/groups.rb
@@ -100,7 +100,7 @@ module API
options = {
with: serializer,
current_user: current_user,
- statistics: params[:statistics] && current_user&.admin?
+ statistics: params[:statistics] && current_user&.can_read_all_resources?
}
groups = groups.with_statistics if options[:statistics]
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 75e7612bd5b..86763b2cd67 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -301,7 +301,7 @@ module API
def authenticated_as_admin!
authenticate!
- forbidden! unless current_user.admin?
+ forbidden! unless current_user.can_admin_all_resources?
end
def authorize!(action, subject = :global, reason = nil)
@@ -710,7 +710,7 @@ module API
unauthorized! unless initial_current_user
- unless initial_current_user.admin?
+ unless initial_current_user.can_admin_all_resources?
forbidden!('Must be admin to use sudo')
end
diff --git a/lib/api/users.rb b/lib/api/users.rb
index c26c515f1d8..d2d45c94291 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -133,7 +133,7 @@ module API
get feature_category: :users, urgency: :low do
authenticated_as_admin! if params[:extern_uid].present? && params[:provider].present?
- unless current_user&.admin?
+ unless current_user&.can_read_all_resources?
params.except!(:created_after, :created_before, :order_by, :sort, :two_factor, :without_projects)
end
@@ -151,7 +151,7 @@ module API
users = UsersFinder.new(current_user, params).execute
users = reorder_users(users)
- entity = current_user&.admin? ? Entities::UserWithAdmin : Entities::UserBasic
+ entity = current_user&.can_read_all_resources? ? Entities::UserWithAdmin : Entities::UserBasic
if entity == Entities::UserWithAdmin
users = users.preload(:identities, :u2f_registrations, :webauthn_registrations, :namespace, :followers, :followees, :user_preference)
@@ -177,7 +177,7 @@ module API
get ":id", feature_category: :users, urgency: :low do
forbidden!('Not authorized!') unless current_user
- unless current_user.admin?
+ unless current_user.can_read_all_resources?
check_rate_limit!(:users_get_by_id,
scope: current_user,
users_allowlist: Gitlab::CurrentSettings.current_application_settings.users_get_by_id_limit_allowlist
@@ -188,7 +188,7 @@ module API
not_found!('User') unless user && can?(current_user, :read_user, user)
- opts = { with: current_user.admin? ? Entities::UserDetailsWithAdmin : Entities::User, current_user: current_user }
+ opts = { with: current_user.can_read_all_resources? ? Entities::UserDetailsWithAdmin : Entities::User, current_user: current_user }
user, opts = with_custom_attributes(user, opts)
present user, opts
@@ -373,7 +373,8 @@ module API
user = User.find_by_id(params[:id])
not_found!('User') unless user
- forbidden!('Two-factor authentication for admins cannot be disabled via the API. Use the Rails console') if user.admin?
+ # We're disabling Cop/UserAdmin because it checks if the given user (not the current user) is an admin.
+ forbidden!('Two-factor authentication for admins cannot be disabled via the API. Use the Rails console') if user.admin? # rubocop:disable Cop/UserAdmin
result = TwoFactor::DestroyService.new(current_user, user: user).execute
@@ -1008,7 +1009,8 @@ module API
end
get feature_category: :users, urgency: :low do
entity =
- if current_user.admin?
+ # We're disabling Cop/UserAdmin because it checks if the given user is an admin.
+ if current_user.admin? # rubocop:disable Cop/UserAdmin
Entities::UserWithAdmin
else
Entities::UserPublic
diff --git a/lib/api/v3/github.rb b/lib/api/v3/github.rb
index e4a26838746..db71e823b1d 100644
--- a/lib/api/v3/github.rb
+++ b/lib/api/v3/github.rb
@@ -78,13 +78,13 @@ module API
# rubocop: enable CodeReuse/ActiveRecord
def authorized_merge_requests
- MergeRequestsFinder.new(current_user, authorized_only: !current_user.admin?)
+ MergeRequestsFinder.new(current_user, authorized_only: !current_user.can_read_all_resources?)
.execute.with_jira_integration_associations
end
def authorized_merge_requests_for_project(project)
MergeRequestsFinder
- .new(current_user, authorized_only: !current_user.admin?, project_id: project.id)
+ .new(current_user, authorized_only: !current_user.can_read_all_resources?, project_id: project.id)
.execute.with_jira_integration_associations
end
diff --git a/lib/gitlab/github_gists_import/importer/gist_importer.rb b/lib/gitlab/github_gists_import/importer/gist_importer.rb
new file mode 100644
index 00000000000..a5e87d3cf7d
--- /dev/null
+++ b/lib/gitlab/github_gists_import/importer/gist_importer.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module GithubGistsImport
+ module Importer
+ class GistImporter
+ attr_reader :gist, :user
+
+ FileCountLimitError = Class.new(StandardError)
+
+ # gist - An instance of `Gitlab::GithubGistsImport::Representation::Gist`.
+ def initialize(gist, user_id)
+ @gist = gist
+ @user = User.find(user_id)
+ end
+
+ def execute
+ snippet = build_snippet
+ import_repository(snippet) if snippet.save!
+
+ return ServiceResponse.success unless max_snippet_files_count_exceeded?(snippet)
+
+ fail_and_track(snippet)
+ end
+
+ private
+
+ def build_snippet
+ attrs = {
+ title: gist.truncated_title,
+ visibility_level: gist.visibility_level,
+ content: gist.first_file[:file_content],
+ file_name: gist.first_file[:file_name],
+ author: user,
+ created_at: gist.created_at,
+ updated_at: gist.updated_at
+ }
+
+ PersonalSnippet.new(attrs)
+ end
+
+ def import_repository(snippet)
+ resolved_address = get_resolved_address
+
+ snippet.create_repository
+ snippet.repository.fetch_as_mirror(gist.git_pull_url, forced: true, resolved_address: resolved_address)
+ rescue StandardError
+ remove_snippet_and_repository(snippet)
+
+ raise
+ end
+
+ def get_resolved_address
+ validated_pull_url, host = Gitlab::UrlBlocker.validate!(gist.git_pull_url,
+ schemes: Project::VALID_IMPORT_PROTOCOLS,
+ ports: Project::VALID_IMPORT_PORTS,
+ allow_localhost: allow_local_requests?,
+ allow_local_network: allow_local_requests?)
+
+ host.present? ? validated_pull_url.host.to_s : ''
+ end
+
+ def max_snippet_files_count_exceeded?(snippet)
+ snippet.all_files.size > Snippet.max_file_limit
+ end
+
+ def remove_snippet_and_repository(snippet)
+ snippet.repository.remove if snippet.repository_exists?
+ snippet.destroy
+ end
+
+ def allow_local_requests?
+ Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services?
+ end
+
+ def fail_and_track(snippet)
+ remove_snippet_and_repository(snippet)
+
+ ServiceResponse.error(message: 'Snippet max file count exceeded').track_exception(as: FileCountLimitError)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/github_gists_import/representation/gist.rb b/lib/gitlab/github_gists_import/representation/gist.rb
new file mode 100644
index 00000000000..0d309a98f38
--- /dev/null
+++ b/lib/gitlab/github_gists_import/representation/gist.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module GithubGistsImport
+ module Representation
+ class Gist
+ include Gitlab::GithubImport::Representation::ToHash
+ include Gitlab::GithubImport::Representation::ExposeAttribute
+
+ attr_reader :attributes
+
+ expose_attribute :id, :description, :is_public, :created_at, :updated_at, :files, :git_pull_url
+
+ # Builds a gist from a GitHub API response.
+ #
+ # gist - An instance of `Hash` containing the gist
+ # details.
+ def self.from_api_response(gist, additional_data = {})
+ hash = {
+ id: gist[:id],
+ description: gist[:description],
+ is_public: gist[:public],
+ files: gist[:files],
+ git_pull_url: gist[:git_pull_url],
+ created_at: gist[:created_at],
+ updated_at: gist[:updated_at]
+ }
+
+ new(hash)
+ end
+
+ # Builds a new gist using a Hash that was built from a JSON payload.
+ def self.from_json_hash(raw_hash)
+ new(Gitlab::GithubImport::Representation.symbolize_hash(raw_hash))
+ end
+
+ # attributes - A hash containing the raw gist details. The keys of this
+ # Hash (and any nested hashes) must be symbols.
+ def initialize(attributes)
+ @attributes = attributes
+ end
+
+ # Gist description can be an empty string, so we returning nil to use first file
+ # name as a title in such case on snippet creation
+ # Gist description has a limit of 256, while the snippet's title can be up to 255
+ def truncated_title
+ title = description.presence || first_file[:file_name]
+
+ title.truncate(255)
+ end
+
+ def visibility_level
+ is_public ? Gitlab::VisibilityLevel::PUBLIC : Gitlab::VisibilityLevel::PRIVATE
+ end
+
+ def first_file
+ _key, value = files.first
+
+ {
+ file_name: value[:filename],
+ file_content: Gitlab::HTTP.try_get(value[:raw_url])&.body
+ }
+ end
+
+ def github_identifiers
+ { id: id }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/memory/watchdog/configurator.rb b/lib/gitlab/memory/watchdog/configurator.rb
index 880f9800d96..2848d6c36e9 100644
--- a/lib/gitlab/memory/watchdog/configurator.rb
+++ b/lib/gitlab/memory/watchdog/configurator.rb
@@ -30,7 +30,7 @@ module Gitlab
config.write_heap_dumps = write_heap_dumps?
config.sleep_time_seconds = sidekiq_sleep_time
config.monitors(&configure_monitors_for_sidekiq)
- config.event_reporter = EventReporter.new(logger: ::Sidekiq.logger)
+ config.event_reporter = SidekiqEventReporter.new
end
end
diff --git a/lib/gitlab/memory/watchdog/sidekiq_event_reporter.rb b/lib/gitlab/memory/watchdog/sidekiq_event_reporter.rb
new file mode 100644
index 00000000000..db94edd0992
--- /dev/null
+++ b/lib/gitlab/memory/watchdog/sidekiq_event_reporter.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Memory
+ class Watchdog
+ class SidekiqEventReporter
+ include ::Gitlab::Utils::StrongMemoize
+
+ delegate :threshold_violated, :started, :stopped, :logger, to: :event_reporter
+
+ def initialize(logger: ::Sidekiq.logger)
+ @event_reporter = EventReporter.new(logger: logger)
+ init_prometheus_metrics
+ end
+
+ def strikes_exceeded(monitor_name, labels = {})
+ running_jobs = fetch_running_jobs
+ labels[:running_jobs] = running_jobs
+ increment_worker_counters(running_jobs)
+
+ event_reporter.strikes_exceeded(monitor_name, labels)
+ end
+
+ private
+
+ attr_reader :event_reporter
+
+ def fetch_running_jobs
+ running_jobs = []
+ Gitlab::SidekiqDaemon::Monitor.instance.with_running_jobs do |jobs|
+ running_jobs = jobs.map do |jid, job|
+ {
+ jid: jid,
+ worker_class: job[:worker_class].name
+ }
+ end
+ end
+ running_jobs
+ end
+
+ def increment_worker_counters(running_jobs)
+ running_jobs.each do |job|
+ @sidekiq_watchdog_running_jobs_counter.increment({ worker_class: job[:worker_class] })
+ end
+ end
+
+ def init_prometheus_metrics
+ @sidekiq_watchdog_running_jobs_counter = ::Gitlab::Metrics.counter(
+ :sidekiq_watchdog_running_jobs_total,
+ 'Current running jobs when limit was reached'
+ )
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/sidekiq_daemon/monitor.rb b/lib/gitlab/sidekiq_daemon/monitor.rb
index 655e95c82d3..2079683a2c1 100644
--- a/lib/gitlab/sidekiq_daemon/monitor.rb
+++ b/lib/gitlab/sidekiq_daemon/monitor.rb
@@ -65,6 +65,12 @@ module Gitlab
end
end
+ def with_running_jobs
+ @jobs_mutex.synchronize do
+ yield @jobs.dup
+ end
+ end
+
private
def run_thread
diff --git a/lib/version_check.rb b/lib/version_check.rb
index 35014f3ddf0..eddcddbeb49 100644
--- a/lib/version_check.rb
+++ b/lib/version_check.rb
@@ -69,13 +69,17 @@ class VersionCheck
case response&.code
when 200
- response.body
+ Gitlab::Json.parse(response.body)
+ else
+ { error: 'version check failed', status: response&.code }
end
end
def response
with_reactive_cache do |data|
- Gitlab::Json.parse(data) if data
+ raise InvalidateReactiveCache if data[:error]
+
+ data
end
end
end
diff --git a/qa/qa/page/file/edit.rb b/qa/qa/page/file/edit.rb
index b9b676ee3c4..e66019279ce 100644
--- a/qa/qa/page/file/edit.rb
+++ b/qa/qa/page/file/edit.rb
@@ -8,8 +8,8 @@ module QA
include Shared::CommitButton
include Shared::Editor
- view 'app/assets/javascripts/editor/components/source_editor_toolbar_button.vue' do
- element :editor_toolbar_button
+ view 'app/assets/javascripts/editor/extensions/source_editor_markdown_livepreview_ext.js' do
+ element :editor_toolbar_button, "qaSelector: 'editor_toolbar_button'" # rubocop:disable QA/ElementWithPattern
end
def has_markdown_preview?(component, content)
diff --git a/scripts/review_apps/review-apps.sh b/scripts/review_apps/review-apps.sh
index 44dc2fdbc3d..48344dc3afe 100755
--- a/scripts/review_apps/review-apps.sh
+++ b/scripts/review_apps/review-apps.sh
@@ -375,12 +375,15 @@ function display_deployment_debug() {
echoinfo "[debugging data] k8s resources:"
kubectl get svc,pods,jobs -o wide --namespace "${namespace}"
- echoinfo "[debugging data] k8s events in namespace:"
- kubectl get events --sort-by='.metadata.creationTimestamp' --namespace "${namespace}"
+ echoinfo "[debugging data] PostgreSQL logs:"
+ kubectl logs -l app=postgresql --all-containers --namespace "${namespace}"
+
+ echoinfo "[debugging data] DB migrations logs:"
+ kubectl logs -l app=migrations --all-containers --namespace "${namespace}"
echoinfo "[debugging data] Webservice logs:"
kubectl logs -l app=webservice --all-containers --namespace "${namespace}"
- echoinfo "[debugging data] PostgreSQL logs:"
- kubectl logs -l app=postgresql --all-containers --namespace "${namespace}"
+ echoinfo "[debugging data] k8s events in namespace:"
+ kubectl get events --sort-by='.metadata.creationTimestamp' --namespace "${namespace}"
}
diff --git a/spec/features/incidents/incident_details_spec.rb b/spec/features/incidents/incident_details_spec.rb
index 7c24943eb6f..e1167285464 100644
--- a/spec/features/incidents/incident_details_spec.rb
+++ b/spec/features/incidents/incident_details_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Incident details', :js do
+RSpec.describe 'Incident details', :js, feature_category: :incident_management do
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user) }
let_it_be(:incident) { create(:incident, project: project, author: developer, description: 'description') }
diff --git a/spec/features/milestones/user_creates_milestone_spec.rb b/spec/features/milestones/user_creates_milestone_spec.rb
index 1ab231632fb..b750f035e36 100644
--- a/spec/features/milestones/user_creates_milestone_spec.rb
+++ b/spec/features/milestones/user_creates_milestone_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe "User creates milestone", :js do
+RSpec.describe "User creates milestone", :js, feature_category: :team_planning do
let_it_be(:developer) { create(:user) }
let_it_be(:inherited_guest) { create(:user) }
let_it_be(:inherited_developer) { create(:user) }
diff --git a/spec/frontend/editor/components/source_editor_toolbar_button_spec.js b/spec/frontend/editor/components/source_editor_toolbar_button_spec.js
index ded31bb62dc..f62061f6eaf 100644
--- a/spec/frontend/editor/components/source_editor_toolbar_button_spec.js
+++ b/spec/frontend/editor/components/source_editor_toolbar_button_spec.js
@@ -54,6 +54,25 @@ describe('Source Editor Toolbar button', () => {
});
});
+ describe('data attributes', () => {
+ it.each`
+ description | data | expectedDataset
+ ${'does not set any attribute'} | ${undefined} | ${{}}
+ ${'does not set any attribute'} | ${[]} | ${{}}
+ ${'does not set any attribute'} | ${['foo']} | ${{}}
+ ${'does not set any attribute'} | ${'bar'} | ${{}}
+ ${'does set single attribute correctly'} | ${{ qaSelector: 'foo' }} | ${{ qaSelector: 'foo' }}
+ ${'does set multiple attributes correctly'} | ${{ qaSelector: 'foo', youCanSeeMe: true }} | ${{ qaSelector: 'foo', youCanSeeMe: 'true' }}
+ `('$description when data="$data"', ({ data, expectedDataset }) => {
+ createComponent({
+ button: {
+ data,
+ },
+ });
+ expect(findButton().element.dataset).toEqual(expect.objectContaining(expectedDataset));
+ });
+ });
+
describe('click handler', () => {
let clickEvent;
diff --git a/spec/lib/gitlab/github_gists_import/importer/gist_importer_spec.rb b/spec/lib/gitlab/github_gists_import/importer/gist_importer_spec.rb
new file mode 100644
index 00000000000..69a4d646562
--- /dev/null
+++ b/spec/lib/gitlab/github_gists_import/importer/gist_importer_spec.rb
@@ -0,0 +1,128 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::GithubGistsImport::Importer::GistImporter, feature_category: :importer do
+ subject { described_class.new(gist_object, user.id).execute }
+
+ let_it_be(:user) { create(:user) }
+ let(:created_at) { Time.utc(2022, 1, 9, 12, 15) }
+ let(:updated_at) { Time.utc(2022, 5, 9, 12, 17) }
+ let(:gist_file) { { file_name: '_Summary.md', file_content: 'File content' } }
+ let(:url) { 'https://host.com/gistid.git' }
+ let(:gist_object) do
+ instance_double('Gitlab::GithubGistsImport::Representation::Gist',
+ truncated_title: 'My Gist',
+ visibility_level: 0,
+ files: { '_Summary.md': gist_file },
+ first_file: gist_file,
+ git_pull_url: url,
+ created_at: created_at,
+ updated_at: updated_at
+ )
+ end
+
+ let(:expected_snippet_attrs) do
+ {
+ title: 'My Gist',
+ visibility_level: 0,
+ content: 'File content',
+ file_name: '_Summary.md',
+ author_id: user.id,
+ created_at: gist_object.created_at,
+ updated_at: gist_object.updated_at
+ }.stringify_keys
+ end
+
+ describe '#execute' do
+ context 'when success' do
+ it 'creates expected snippet and snippet repository' do
+ expect_next_instance_of(Repository) do |repository|
+ expect(repository).to receive(:fetch_as_mirror)
+ end
+
+ expect { subject }.to change { user.snippets.count }.by(1)
+ expect(user.snippets[0].attributes).to include expected_snippet_attrs
+ end
+ end
+
+ context 'when file size limit exeeded' do
+ before do
+ files = [].tap { |array| 11.times { |n| array << ["file#{n}.txt", {}] } }.to_h
+
+ allow(gist_object).to receive(:files).and_return(files)
+ allow_next_instance_of(Repository) do |repository|
+ allow(repository).to receive(:fetch_as_mirror)
+ allow(repository).to receive(:empty?).and_return(false)
+ allow(repository).to receive(:ls_files).and_return(files.keys)
+ end
+ end
+
+ it 'returns error' do
+ result = subject
+
+ expect(user.snippets.count).to eq(0)
+ expect(result.error?).to eq(true)
+ expect(result.errors).to match_array(['Snippet max file count exceeded'])
+ end
+ end
+
+ context 'when invalid attributes' do
+ let(:gist_file) { { file_name: '_Summary.md', file_content: nil } }
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(ActiveRecord::RecordInvalid, "Validation failed: Content can't be blank")
+ end
+ end
+
+ context 'when repository cloning fails' do
+ it 'returns error' do
+ expect_next_instance_of(Repository) do |repository|
+ expect(repository).to receive(:fetch_as_mirror).and_raise(Gitlab::Shell::Error)
+ expect(repository).to receive(:remove)
+ end
+
+ expect { subject }.to raise_error(Gitlab::Shell::Error)
+ expect(user.snippets.count).to eq(0)
+ end
+ end
+
+ context 'when url is invalid' do
+ let(:url) { 'invalid' }
+
+ context 'when local network is allowed' do
+ before do
+ allow(::Gitlab::CurrentSettings)
+ .to receive(:allow_local_requests_from_web_hooks_and_services?).and_return(true)
+ end
+
+ it 'raises error' do
+ expect(Gitlab::UrlBlocker)
+ .to receive(:validate!)
+ .with(url, ports: [80, 443], schemes: %w[http https git],
+ allow_localhost: true, allow_local_network: true)
+ .and_raise(Gitlab::UrlBlocker::BlockedUrlError)
+
+ expect { subject }.to raise_error(Gitlab::UrlBlocker::BlockedUrlError)
+ end
+ end
+
+ context 'when local network is not allowed' do
+ before do
+ allow(::Gitlab::CurrentSettings)
+ .to receive(:allow_local_requests_from_web_hooks_and_services?).and_return(false)
+ end
+
+ it 'raises error' do
+ expect(Gitlab::UrlBlocker)
+ .to receive(:validate!)
+ .with(url, ports: [80, 443], schemes: %w[http https git],
+ allow_localhost: false, allow_local_network: false)
+ .and_raise(Gitlab::UrlBlocker::BlockedUrlError)
+
+ expect { subject }.to raise_error(Gitlab::UrlBlocker::BlockedUrlError)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/github_gists_import/representation/gist_spec.rb b/spec/lib/gitlab/github_gists_import/representation/gist_spec.rb
new file mode 100644
index 00000000000..f36fbc637d0
--- /dev/null
+++ b/spec/lib/gitlab/github_gists_import/representation/gist_spec.rb
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::GithubGistsImport::Representation::Gist do
+ shared_examples 'a Gist' do
+ it 'returns an instance of Gist' do
+ expect(gist).to be_an_instance_of(described_class)
+ end
+
+ context 'with Gist' do
+ it 'includes gist attributes' do
+ expect(gist).to have_attributes(
+ id: '1',
+ description: 'Gist title',
+ is_public: true,
+ files: { '_Summary.md': { filename: '_Summary.md', raw_url: 'https://some_url' } },
+ git_pull_url: 'https://gist.github.com/gistid.git'
+ )
+ end
+ end
+ end
+
+ describe '.from_api_response' do
+ let(:response) do
+ {
+ id: '1',
+ description: 'Gist title',
+ public: true,
+ created_at: '2022-04-26 18:30:53 UTC',
+ updated_at: '2022-04-26 18:30:53 UTC',
+ files: { '_Summary.md': { filename: '_Summary.md', raw_url: 'https://some_url' } },
+ git_pull_url: 'https://gist.github.com/gistid.git'
+ }
+ end
+
+ it_behaves_like 'a Gist' do
+ let(:gist) { described_class.from_api_response(response) }
+ end
+ end
+
+ describe '.from_json_hash' do
+ it_behaves_like 'a Gist' do
+ let(:hash) do
+ {
+ 'id' => '1',
+ 'description' => 'Gist title',
+ 'is_public' => true,
+ 'files' => { '_Summary.md': { filename: '_Summary.md', raw_url: 'https://some_url' } },
+ 'git_pull_url' => 'https://gist.github.com/gistid.git'
+ }
+ end
+
+ let(:gist) { described_class.from_json_hash(hash) }
+ end
+ end
+
+ describe '#truncated_title' do
+ it 'truncates the title to 255 characters' do
+ object = described_class.new(description: 'm' * 300)
+
+ expect(object.truncated_title.length).to eq(255)
+ end
+
+ it 'does not truncate the title if it is shorter than 255 characters' do
+ object = described_class.new(description: 'foo')
+
+ expect(object.truncated_title).to eq('foo')
+ end
+ end
+
+ describe '#github_identifiers' do
+ it 'returns a hash with needed identifiers' do
+ github_identifiers = { id: 1 }
+ gist = described_class.new(github_identifiers.merge(something_else: '_something_else_'))
+
+ expect(gist.github_identifiers).to eq(github_identifiers)
+ end
+ end
+
+ describe '#visibility_level' do
+ it 'returns 20 when public' do
+ visibility = { is_public: true }
+ gist = described_class.new(visibility.merge(something_else: '_something_else_'))
+
+ expect(gist.visibility_level).to eq(20)
+ end
+
+ it 'returns 0 when private' do
+ visibility = { is_public: false }
+ gist = described_class.new(visibility.merge(something_else: '_something_else_'))
+
+ expect(gist.visibility_level).to eq(0)
+ end
+ end
+
+ describe '#first_file' do
+ let(:http_response) { instance_double('HTTParty::Response', body: 'File content') }
+
+ before do
+ allow(Gitlab::HTTP).to receive(:try_get).and_return(http_response)
+ end
+
+ it 'returns a hash with needed identifiers' do
+ files = { files: { '_Summary.md': { filename: '_Summary.md', raw_url: 'https://some_url' } } }
+ gist = described_class.new(files.merge(something_else: '_something_else_'))
+
+ expect(gist.first_file).to eq(file_name: '_Summary.md', file_content: 'File content')
+ end
+ end
+end
diff --git a/spec/lib/gitlab/memory/watchdog/configurator_spec.rb b/spec/lib/gitlab/memory/watchdog/configurator_spec.rb
index 892bad603a8..72661829bab 100644
--- a/spec/lib/gitlab/memory/watchdog/configurator_spec.rb
+++ b/spec/lib/gitlab/memory/watchdog/configurator_spec.rb
@@ -243,7 +243,7 @@ RSpec.describe Gitlab::Memory::Watchdog::Configurator do
it_behaves_like 'as configurator',
Gitlab::Memory::Watchdog::TermProcessHandler,
- Gitlab::Memory::Watchdog::EventReporter,
+ Gitlab::Memory::Watchdog::SidekiqEventReporter,
'SIDEKIQ_MEMORY_KILLER_CHECK_INTERVAL',
described_class::DEFAULT_SIDEKIQ_SLEEP_INTERVAL_S
diff --git a/spec/lib/gitlab/memory/watchdog/sidekiq_event_reporter_spec.rb b/spec/lib/gitlab/memory/watchdog/sidekiq_event_reporter_spec.rb
new file mode 100644
index 00000000000..b6be4c59a0e
--- /dev/null
+++ b/spec/lib/gitlab/memory/watchdog/sidekiq_event_reporter_spec.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Memory::Watchdog::SidekiqEventReporter, feature_category: :application_performance do
+ let(:counter) { instance_double(::Prometheus::Client::Counter) }
+
+ before do
+ allow(Gitlab::Metrics).to receive(:counter).and_return(counter)
+ allow(counter).to receive(:increment)
+ end
+
+ describe 'delegations' do
+ it { is_expected.to delegate_method(:started).to(:event_reporter) }
+ it { is_expected.to delegate_method(:stopped).to(:event_reporter) }
+ it { is_expected.to delegate_method(:threshold_violated).to(:event_reporter) }
+ it { is_expected.to delegate_method(:logger).to(:event_reporter) }
+ end
+
+ describe '#strikes_exceeded' do
+ let(:sidekiq_event_reporter) { described_class.new(logger: logger) }
+ let(:sidekiq_watchdog_running_jobs_counter) { instance_double(::Prometheus::Client::Counter) }
+ let(:logger) { instance_double(::Logger) }
+ let(:queue) { 'default' }
+ let(:jid) { SecureRandom.hex }
+ let(:running_jobs) { { jid => { worker_class: DummyWorker } } }
+ let(:worker) do
+ Class.new do
+ def self.name
+ 'DummyWorker'
+ end
+ end
+ end
+
+ before do
+ stub_const("DummyWorker", worker)
+ allow(::Gitlab::Metrics).to receive(:counter)
+ .with(:sidekiq_watchdog_running_jobs_total, anything)
+ .and_return(sidekiq_watchdog_running_jobs_counter)
+ allow(sidekiq_watchdog_running_jobs_counter).to receive(:increment)
+ allow(logger).to receive(:warn)
+
+ allow(Gitlab::SidekiqDaemon::Monitor.instance).to receive(:with_running_jobs).and_yield(running_jobs)
+ end
+
+ it 'delegates #strikes_exceeded with correct arguments' do
+ is_expected.to delegate_method(:strikes_exceeded).to(:event_reporter)
+ .with_arguments(
+ :monitor_name,
+ {
+ message: 'dummy_text',
+ running_jobs: running_jobs
+ }
+ )
+ end
+
+ it 'increment running jobs counter' do
+ expect(sidekiq_watchdog_running_jobs_counter).to receive(:increment)
+ .with({ worker_class: "DummyWorker" })
+
+ sidekiq_event_reporter.strikes_exceeded(:monitor_name, { message: 'dummy_text' })
+ end
+ end
+end
diff --git a/spec/lib/gitlab/merge_requests/message_generator_spec.rb b/spec/lib/gitlab/merge_requests/message_generator_spec.rb
index fbdd6a1e56d..59aaffc4377 100644
--- a/spec/lib/gitlab/merge_requests/message_generator_spec.rb
+++ b/spec/lib/gitlab/merge_requests/message_generator_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::MergeRequests::MessageGenerator do
+RSpec.describe Gitlab::MergeRequests::MessageGenerator, feature_category: :code_review do
let(:merge_commit_template) { nil }
let(:squash_commit_template) { nil }
let(:project) do
diff --git a/spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb b/spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb
index f93c0e28fc0..9f49605be8a 100644
--- a/spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb
+++ b/spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb
@@ -37,6 +37,17 @@ RSpec.describe Gitlab::SidekiqDaemon::Monitor do
end
end
+ describe '#with_running_jobs' do
+ it 'yields with correct jobs' do
+ jid = SecureRandom.hex
+ running_jobs = { jid => hash_including(worker_class: 'worker_class') }
+
+ monitor.within_job('worker_class', jid, 'queue') do
+ expect { |b| monitor.with_running_jobs(&b) }.to yield_with_args(running_jobs)
+ end
+ end
+ end
+
describe '#run_thread when notification channel not enabled' do
subject { monitor.send(:run_thread) }
diff --git a/spec/lib/version_check_spec.rb b/spec/lib/version_check_spec.rb
index 1803dd66ba7..f14b38c55dd 100644
--- a/spec/lib/version_check_spec.rb
+++ b/spec/lib/version_check_spec.rb
@@ -2,7 +2,9 @@
require 'spec_helper'
-RSpec.describe VersionCheck do
+RSpec.describe VersionCheck, :use_clean_rails_memory_store_caching do
+ include ReactiveCachingHelpers
+
describe '.url' do
it 'returns the correct URL' do
expect(described_class.url).to match(%r{\A#{Regexp.escape(described_class.host)}/check\.json\?gitlab_info=\w+})
@@ -30,7 +32,7 @@ RSpec.describe VersionCheck do
end
it 'returns the response object' do
- expect(described_class.new.calculate_reactive_cache).to eq("{ \"status\": \"success\" }")
+ expect(described_class.new.calculate_reactive_cache).to eq({ "status" => "success" })
end
end
@@ -39,38 +41,31 @@ RSpec.describe VersionCheck do
stub_request(:get, described_class.url).to_return(status: 500, body: nil, headers: {})
end
- it 'returns nil' do
- expect(described_class.new.calculate_reactive_cache).to be(nil)
+ it 'returns an error hash' do
+ expect(described_class.new.calculate_reactive_cache).to eq({ error: 'version check failed', status: 500 })
end
end
end
describe '#response' do
context 'cache returns value' do
- let(:response) { { "severity" => "success" }.to_json }
-
- before do
- allow_next_instance_of(described_class) do |instance|
- allow(instance).to receive(:with_reactive_cache).and_return(response)
- end
- end
-
it 'returns the response object' do
- expect(described_class.new.response).to be(response)
+ version_check = described_class.new
+ data = { status: 'success' }
+ stub_reactive_cache(version_check, data)
+
+ expect(version_check.response).to eq(data)
end
end
- context 'cache returns nil' do
- let(:response) { nil }
-
- before do
- allow_next_instance_of(described_class) do |instance|
- allow(instance).to receive(:with_reactive_cache).and_return(response)
- end
- end
+ context 'cache returns error' do
+ it 'returns nil and invalidates the reactive cache' do
+ version_check = described_class.new
+ stub_reactive_cache(version_check, error: 'version check failed')
- it 'returns nil' do
- expect(described_class.new.response).to be(nil)
+ expect(version_check).to receive(:refresh_reactive_cache!).and_call_original
+ expect(version_check.response).to be_nil
+ expect(read_reactive_cache(version_check)).to be_nil
end
end
end
diff --git a/spec/models/ci/build_need_spec.rb b/spec/models/ci/build_need_spec.rb
index c2cf9027055..aa1c57d1788 100644
--- a/spec/models/ci/build_need_spec.rb
+++ b/spec/models/ci/build_need_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Ci::BuildNeed, model: true do
+RSpec.describe Ci::BuildNeed, model: true, feature_category: :continuous_integration do
let(:build_need) { build(:ci_build_need) }
it { is_expected.to belong_to(:build).class_name('Ci::Processable') }
@@ -35,4 +35,62 @@ RSpec.describe Ci::BuildNeed, model: true do
end
end
end
+
+ describe 'partitioning' do
+ context 'with build' do
+ let(:build) { FactoryBot.build(:ci_build, partition_id: ci_testing_partition_id) }
+ let(:build_need) { FactoryBot.build(:ci_build_need, build: build) }
+
+ it 'sets partition_id to the current partition value' do
+ expect { build_need.valid? }.to change { build_need.partition_id }.to(ci_testing_partition_id)
+ end
+
+ context 'when it is already set' do
+ let(:build_need) { FactoryBot.build(:ci_build_need, partition_id: 125) }
+
+ it 'does not change the partition_id value' do
+ expect { build_need.valid? }.not_to change { build_need.partition_id }
+ end
+ end
+ end
+
+ context 'without build' do
+ let(:build_need) { FactoryBot.build(:ci_build_need, build: nil) }
+
+ it { is_expected.to validate_presence_of(:partition_id) }
+
+ it 'does not change the partition_id value' do
+ expect { build_need.valid? }.not_to change { build_need.partition_id }
+ end
+ end
+
+ context 'when using bulk_insert' do
+ include Ci::PartitioningHelpers
+
+ let(:new_pipeline) { create(:ci_pipeline) }
+ let(:ci_build) { build(:ci_build, pipeline: new_pipeline) }
+
+ before do
+ stub_current_partition_id
+ end
+
+ it 'creates build needs successfully', :aggregate_failures do
+ ci_build.needs_attributes = [
+ { name: "build", artifacts: true },
+ { name: "build2", artifacts: true },
+ { name: "build3", artifacts: true }
+ ]
+
+ expect(described_class).to receive(:bulk_insert!).and_call_original
+
+ BulkInsertableAssociations.with_bulk_insert do
+ ci_build.save!
+ end
+
+ expect(described_class.count).to eq(3)
+ expect(described_class.first.partition_id).to eq(ci_testing_partition_id)
+ expect(described_class.second.partition_id).to eq(ci_testing_partition_id)
+ end
+ end
+ end
end
diff --git a/spec/models/ci/processable_spec.rb b/spec/models/ci/processable_spec.rb
index e62e5f84a6d..2ff29bf207e 100644
--- a/spec/models/ci/processable_spec.rb
+++ b/spec/models/ci/processable_spec.rb
@@ -423,8 +423,8 @@ RSpec.describe Ci::Processable do
it 'returns all needs attributes' do
is_expected.to contain_exactly(
- { 'artifacts' => true, 'name' => 'test1', 'optional' => false },
- { 'artifacts' => true, 'name' => 'test2', 'optional' => false }
+ { 'artifacts' => true, 'name' => 'test1', 'optional' => false, 'partition_id' => build.partition_id },
+ { 'artifacts' => true, 'name' => 'test2', 'optional' => false, 'partition_id' => build.partition_id }
)
end
end
diff --git a/spec/requests/api/helpers_spec.rb b/spec/requests/api/helpers_spec.rb
index e29e5c31a34..38275ce0057 100644
--- a/spec/requests/api/helpers_spec.rb
+++ b/spec/requests/api/helpers_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require 'raven/transports/dummy'
require_relative '../../../config/initializers/sentry'
-RSpec.describe API::Helpers do
+RSpec.describe API::Helpers, :enable_admin_mode, feature_category: :authentication_and_authorization do
include API::APIGuard::HelperMethods
include described_class
include TermsHelper
diff --git a/spec/requests/api/project_attributes.yml b/spec/requests/api/project_attributes.yml
index da478a3547e..c0e64b51853 100644
--- a/spec/requests/api/project_attributes.yml
+++ b/spec/requests/api/project_attributes.yml
@@ -164,6 +164,7 @@ project_setting:
- suggested_reviewers_enabled
- jitsu_key
- mirror_branch_regex
+ - allow_pipeline_trigger_approve_deployment
build_service_desk_setting: # service_desk_setting
unexposed_attributes:
diff --git a/spec/services/ci/create_pipeline_service/partitioning_spec.rb b/spec/services/ci/create_pipeline_service/partitioning_spec.rb
index f34d103d965..a87135cefdd 100644
--- a/spec/services/ci/create_pipeline_service/partitioning_spec.rb
+++ b/spec/services/ci/create_pipeline_service/partitioning_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectness, :aggregate_failures,
-:ci_partitionable do
+:ci_partitionable, feature_category: :continuous_integration do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { project.first_owner }
@@ -15,8 +15,13 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes
- test
- deploy
+ needs:build:
+ stage: build
+ script: echo "needs..."
+
build:
stage: build
+ needs: ["needs:build"]
script: make build
test:
@@ -95,6 +100,12 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes
expect(pipeline.variables.size).to eq(2)
expect(variables_partition_ids).to eq([current_partition_id])
end
+
+ it 'assigns partition_id to needs' do
+ needs = find_need('build')
+
+ expect(needs.partition_id).to eq(current_partition_id)
+ end
end
context 'with parent child pipelines' do
@@ -144,4 +155,12 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes
.find { |job| job.name == name }
.metadata
end
+
+ def find_need(name)
+ pipeline
+ .processables
+ .find { |job| job.name == name }
+ .needs
+ .first
+ end
end
diff --git a/spec/support/models/ci/partitioning_testing/cascade_check.rb b/spec/support/models/ci/partitioning_testing/cascade_check.rb
index f553a47ef4f..bcfc9675476 100644
--- a/spec/support/models/ci/partitioning_testing/cascade_check.rb
+++ b/spec/support/models/ci/partitioning_testing/cascade_check.rb
@@ -15,6 +15,13 @@ module PartitioningTesting
raise "partition_id was expected to equal #{partition_scope_value} but it was #{partition_id}."
end
+
+ class_methods do
+ # Allowing partition callback to be used with BulkInsertSafe
+ def _bulk_insert_callback_allowed?(name, args)
+ super || args.first == :after && args.second == :check_partition_cascade_value
+ end
+ end
end
end
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index 1cee67f68ab..70772fd8b52 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -286,6 +286,7 @@ RSpec.describe 'Every Sidekiq worker' do
'Gitlab::GithubImport::Stage::ImportPullRequestsReviewsWorker' => 5,
'Gitlab::GithubImport::Stage::ImportPullRequestsWorker' => 5,
'Gitlab::GithubImport::Stage::ImportRepositoryWorker' => 5,
+ 'Gitlab::GithubGistsImport::ImportGistWorker' => 5,
'Gitlab::JiraImport::AdvanceStageWorker' => 5,
'Gitlab::JiraImport::ImportIssueWorker' => 5,
'Gitlab::JiraImport::Stage::FinishImportWorker' => 5,
diff --git a/spec/workers/gitlab/github_gists_import/import_gist_worker_spec.rb b/spec/workers/gitlab/github_gists_import/import_gist_worker_spec.rb
new file mode 100644
index 00000000000..dfc5084bb10
--- /dev/null
+++ b/spec/workers/gitlab/github_gists_import/import_gist_worker_spec.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::GithubGistsImport::ImportGistWorker, feature_category: :importer do
+ subject { described_class.new }
+
+ let_it_be(:user) { create(:user) }
+ let(:token) { 'token' }
+ let(:gist_hash) do
+ {
+ id: '055b70',
+ git_pull_url: 'https://gist.github.com/foo/bar.git',
+ files: {
+ 'random.txt': {
+ filename: 'random.txt',
+ type: 'text/plain',
+ language: 'Text',
+ raw_url: 'https://gist.githubusercontent.com/user_name/055b70/raw/66a7be0d/random.txt',
+ size: 166903
+ }
+ },
+ is_public: false,
+ created_at: '2022-09-06T11:38:18Z',
+ updated_at: '2022-09-06T11:38:18Z',
+ description: 'random text'
+ }
+ end
+
+ let(:importer) { instance_double('Gitlab::GithubGistsImport::Importer::GistImporter') }
+ let(:importer_result) { instance_double('ServiceResponse', success?: true) }
+ let(:gist_object) do
+ instance_double('Gitlab::GithubGistsImport::Representation::Gist',
+ gist_hash.merge(github_identifiers: { id: '055b70' }, truncated_title: 'random text', visibility_level: 0))
+ end
+
+ let(:log_attributes) do
+ {
+ 'user_id' => user.id,
+ 'github_identifiers' => { 'id': gist_object.id },
+ 'class' => 'Gitlab::GithubGistsImport::ImportGistWorker',
+ 'correlation_id' => 'new-correlation-id',
+ 'jid' => nil,
+ 'job_status' => 'running',
+ 'queue' => 'github_gists_importer:github_gists_import_import_gist'
+ }
+ end
+
+ describe '#perform' do
+ before do
+ allow(Gitlab::GithubGistsImport::Representation::Gist)
+ .to receive(:from_json_hash)
+ .with(gist_hash)
+ .and_return(gist_object)
+
+ allow(Gitlab::GithubGistsImport::Importer::GistImporter)
+ .to receive(:new)
+ .with(gist_object, user.id)
+ .and_return(importer)
+
+ allow(Gitlab::ApplicationContext).to receive(:current).and_return('correlation_id' => 'new-correlation-id')
+ allow(described_class).to receive(:queue).and_return('github_gists_importer:github_gists_import_import_gist')
+ end
+
+ context 'when success' do
+ it 'imports gist' do
+ expect(Gitlab::GithubImport::Logger)
+ .to receive(:info)
+ .with(log_attributes.merge('message' => 'start importer'))
+ expect(importer).to receive(:execute).and_return(importer_result)
+ expect(Gitlab::JobWaiter).to receive(:notify).with('some_key', subject.jid)
+ expect(Gitlab::GithubImport::Logger)
+ .to receive(:info)
+ .with(log_attributes.merge('message' => 'importer finished'))
+
+ subject.perform(user.id, gist_hash, 'some_key')
+ end
+ end
+
+ context 'when importer raised an error' do
+ it 'raises an error' do
+ exception = StandardError.new('_some_error_')
+
+ expect(importer).to receive(:execute).and_raise(exception)
+ expect(Gitlab::GithubImport::Logger)
+ .to receive(:error)
+ .with(log_attributes.merge('message' => 'importer failed', 'error.message' => '_some_error_'))
+ expect(Gitlab::ErrorTracking).to receive(:track_exception)
+
+ expect { subject.perform(user.id, gist_hash, 'some_key') }.to raise_error(StandardError)
+ end
+ end
+ end
+end