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>2024-01-10 09:17:26 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2024-01-10 09:17:26 +0300
commit4dfcbb2696bce1a94c0b0fbd7f9e0cef1015f3d2 (patch)
tree50071c95706017018bed80ac5053a03e3695839f
parentfea86fb8bf2339727de5e91ccf17ab105e993dca (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/tracking/constants.js2
-rw-r--r--app/assets/javascripts/tracking/internal_events.js8
-rw-r--r--app/helpers/sessions_helper.rb7
-rw-r--r--app/models/deployment.rb1
-rw-r--r--app/services/projects/destroy_service.rb7
-rw-r--r--db/migrate/20240103200822_replace_fk_on_approval_merge_request_rules_scan_result_policy_id.rb27
-rw-r--r--db/migrate/20240103202629_validate_fk_on_approval_merge_request_rules_scan_result_policy_id.rb16
-rw-r--r--db/migrate/20240103203314_remove_old_fk_on_approval_merge_request_rules_scan_result_policy_id.rb29
-rw-r--r--db/schema_migrations/202401032008221
-rw-r--r--db/schema_migrations/202401032026291
-rw-r--r--db/schema_migrations/202401032033141
-rw-r--r--db/structure.sql6
-rw-r--r--doc/administration/job_artifacts_troubleshooting.md34
-rw-r--r--doc/ci/secrets/gcp_secret_manager.md92
-rw-r--r--doc/ci/secrets/index.md6
-rw-r--r--doc/ci/yaml/index.md28
-rw-r--r--doc/development/internal_analytics/index.md1
-rw-r--r--locale/gitlab.pot6
-rw-r--r--spec/features/search/user_searches_for_code_spec.rb14
-rw-r--r--spec/features/search/user_searches_for_comments_spec.rb8
-rw-r--r--spec/features/search/user_searches_for_commits_spec.rb8
-rw-r--r--spec/features/search/user_searches_for_issues_spec.rb8
-rw-r--r--spec/features/search/user_searches_for_merge_requests_spec.rb8
-rw-r--r--spec/features/search/user_searches_for_milestones_spec.rb8
-rw-r--r--spec/features/search/user_searches_for_projects_spec.rb8
-rw-r--r--spec/features/search/user_searches_for_users_spec.rb8
-rw-r--r--spec/features/search/user_searches_for_wiki_pages_spec.rb8
-rw-r--r--spec/frontend/comment_templates/components/form_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/markdown/comment_templates_dropdown_spec.js6
-rw-r--r--spec/helpers/sessions_helper_spec.rb36
-rw-r--r--spec/models/deployment_spec.rb2
-rw-r--r--spec/services/projects/destroy_service_spec.rb8
32 files changed, 326 insertions, 79 deletions
diff --git a/app/assets/javascripts/tracking/constants.js b/app/assets/javascripts/tracking/constants.js
index bc416b20e80..06d324a970f 100644
--- a/app/assets/javascripts/tracking/constants.js
+++ b/app/assets/javascripts/tracking/constants.js
@@ -31,8 +31,6 @@ export const REFERRER_TTL = 24 * 60 * 60 * 1000;
export const GOOGLE_ANALYTICS_ID_COOKIE_NAME = '_ga';
-export const GITLAB_INTERNAL_EVENT_CATEGORY = 'InternalEventTracking';
-
export const SERVICE_PING_SCHEMA = 'iglu:com.gitlab/gitlab_service_ping/jsonschema/1-0-1';
export const SERVICE_PING_SECURITY_CONFIGURATION_THREAT_MANAGEMENT_VISIT =
diff --git a/app/assets/javascripts/tracking/internal_events.js b/app/assets/javascripts/tracking/internal_events.js
index a6d14bfbfd8..7da6da16d6f 100644
--- a/app/assets/javascripts/tracking/internal_events.js
+++ b/app/assets/javascripts/tracking/internal_events.js
@@ -1,11 +1,7 @@
import API from '~/api';
import Tracking from './tracking';
-import {
- GITLAB_INTERNAL_EVENT_CATEGORY,
- LOAD_INTERNAL_EVENTS_SELECTOR,
- SERVICE_PING_SCHEMA,
-} from './constants';
+import { LOAD_INTERNAL_EVENTS_SELECTOR, SERVICE_PING_SCHEMA } from './constants';
import { Tracker } from './tracker';
import { InternalEventHandler, createInternalEventPayload } from './utils';
@@ -16,7 +12,7 @@ const InternalEvents = {
*/
trackEvent(event) {
API.trackInternalEvent(event);
- Tracking.event(GITLAB_INTERNAL_EVENT_CATEGORY, event, {
+ Tracking.event(undefined, event, {
context: {
schema: SERVICE_PING_SCHEMA,
data: {
diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb
index e93f95beb4f..7dccaa6cd73 100644
--- a/app/helpers/sessions_helper.rb
+++ b/app/helpers/sessions_helper.rb
@@ -3,13 +3,6 @@
module SessionsHelper
include Gitlab::Utils::StrongMemoize
- def recently_confirmed_com?
- strong_memoize(:recently_confirmed_com) do
- ::Gitlab.com? &&
- !!flash[:notice]&.include?(t(:confirmed, scope: [:devise, :confirmations]))
- end
- end
-
def unconfirmed_email?
flash[:alert] == t(:unconfirmed, scope: [:devise, :failure])
end
diff --git a/app/models/deployment.rb b/app/models/deployment.rb
index 36f4a0ef426..66456413a98 100644
--- a/app/models/deployment.rb
+++ b/app/models/deployment.rb
@@ -9,6 +9,7 @@ class Deployment < ApplicationRecord
include Gitlab::Utils::StrongMemoize
include FastDestroyAll
include IgnorableColumns
+ include EachBatch
StatusUpdateError = Class.new(StandardError)
StatusSyncError = Class.new(StandardError)
diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb
index 7ba5b6119b9..033d90abc7a 100644
--- a/app/services/projects/destroy_service.rb
+++ b/app/services/projects/destroy_service.rb
@@ -159,6 +159,7 @@ module Projects
destroy_web_hooks!
destroy_project_bots!
destroy_ci_records!
+ destroy_deployments!
destroy_mr_diff_relations!
destroy_merge_request_diffs!
@@ -253,6 +254,12 @@ module Projects
)
end
+ def destroy_deployments!
+ project.deployments.each_batch(of: BATCH_SIZE) do |deployments|
+ deployments.fast_destroy_all
+ end
+ end
+
# The project can have multiple webhooks with hundreds of thousands of web_hook_logs.
# By default, they are removed with "DELETE CASCADE" option defined via foreign_key.
# But such queries can exceed the statement_timeout limit and fail to delete the project.
diff --git a/db/migrate/20240103200822_replace_fk_on_approval_merge_request_rules_scan_result_policy_id.rb b/db/migrate/20240103200822_replace_fk_on_approval_merge_request_rules_scan_result_policy_id.rb
new file mode 100644
index 00000000000..431183e7212
--- /dev/null
+++ b/db/migrate/20240103200822_replace_fk_on_approval_merge_request_rules_scan_result_policy_id.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class ReplaceFkOnApprovalMergeRequestRulesScanResultPolicyId < Gitlab::Database::Migration[2.2]
+ disable_ddl_transaction!
+ milestone '16.8'
+
+ NEW_CONSTRAINT_NAME = 'fk_approval_merge_request_rules_on_scan_result_policy_id'
+
+ def up
+ add_concurrent_foreign_key(
+ :approval_merge_request_rules,
+ :scan_result_policies,
+ column: :scan_result_policy_id,
+ on_delete: :nullify,
+ validate: false,
+ name: NEW_CONSTRAINT_NAME)
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key_if_exists(:approval_merge_request_rules,
+ column: :scan_result_policy_id,
+ on_delete: :nullify,
+ name: NEW_CONSTRAINT_NAME)
+ end
+ end
+end
diff --git a/db/migrate/20240103202629_validate_fk_on_approval_merge_request_rules_scan_result_policy_id.rb b/db/migrate/20240103202629_validate_fk_on_approval_merge_request_rules_scan_result_policy_id.rb
new file mode 100644
index 00000000000..fee02ce91de
--- /dev/null
+++ b/db/migrate/20240103202629_validate_fk_on_approval_merge_request_rules_scan_result_policy_id.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class ValidateFkOnApprovalMergeRequestRulesScanResultPolicyId < Gitlab::Database::Migration[2.2]
+ milestone '16.8'
+
+ NEW_CONSTRAINT_NAME = 'fk_approval_merge_request_rules_on_scan_result_policy_id'
+
+ # foreign key added in db/migrate/20240103200822_replace_fk_on_approval_merge_request_rules_scan_result_policy_id.rb
+ def up
+ validate_foreign_key(:approval_merge_request_rules, :scan_result_policy_id, name: NEW_CONSTRAINT_NAME)
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/migrate/20240103203314_remove_old_fk_on_approval_merge_request_rules_scan_result_policy_id.rb b/db/migrate/20240103203314_remove_old_fk_on_approval_merge_request_rules_scan_result_policy_id.rb
new file mode 100644
index 00000000000..7758b230242
--- /dev/null
+++ b/db/migrate/20240103203314_remove_old_fk_on_approval_merge_request_rules_scan_result_policy_id.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class RemoveOldFkOnApprovalMergeRequestRulesScanResultPolicyId < Gitlab::Database::Migration[2.2]
+ disable_ddl_transaction!
+ milestone '16.8'
+
+ OLD_CONSTRAINT_NAME = 'fk_f726c79756'
+
+ # new foreign key added in
+ # db/migrate/20240103200822_replace_fk_on_approval_merge_request_rules_scan_result_policy_id.rb
+ # and validated in db/migrate/20240103202629_validate_fk_on_approval_merge_request_rules_scan_result_policy_id.rb
+ def up
+ remove_foreign_key_if_exists(
+ :approval_merge_request_rules,
+ column: :scan_result_policy_id,
+ on_delete: :cascade,
+ name: OLD_CONSTRAINT_NAME)
+ end
+
+ def down
+ add_concurrent_foreign_key(
+ :approval_merge_request_rules,
+ :scan_result_policies,
+ column: :scan_result_policy_id,
+ on_delete: :cascade,
+ validate: false,
+ name: OLD_CONSTRAINT_NAME)
+ end
+end
diff --git a/db/schema_migrations/20240103200822 b/db/schema_migrations/20240103200822
new file mode 100644
index 00000000000..896e75a009b
--- /dev/null
+++ b/db/schema_migrations/20240103200822
@@ -0,0 +1 @@
+7b4f74933360df0a49d44f0738922b0929b62f23aa60a36a5ae24c88a2857638 \ No newline at end of file
diff --git a/db/schema_migrations/20240103202629 b/db/schema_migrations/20240103202629
new file mode 100644
index 00000000000..c2151c9fcd5
--- /dev/null
+++ b/db/schema_migrations/20240103202629
@@ -0,0 +1 @@
+f5c40748ac911a2ee151a36b1a15d8080c4948e0439d25b791db2bb0ae57f7d9 \ No newline at end of file
diff --git a/db/schema_migrations/20240103203314 b/db/schema_migrations/20240103203314
new file mode 100644
index 00000000000..ebb3382d1a9
--- /dev/null
+++ b/db/schema_migrations/20240103203314
@@ -0,0 +1 @@
+9a638b98580e144b7a3e7ad6fc0833531ff63fbd94476310604f1581c8625200 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 0a048082a93..8c77da4afc5 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -38723,6 +38723,9 @@ ALTER TABLE ONLY dast_profile_schedules
ALTER TABLE ONLY analytics_cycle_analytics_group_stages
ADD CONSTRAINT fk_analytics_cycle_analytics_group_stages_group_value_stream_id FOREIGN KEY (group_value_stream_id) REFERENCES analytics_cycle_analytics_group_value_streams(id) ON DELETE CASCADE;
+ALTER TABLE ONLY approval_merge_request_rules
+ ADD CONSTRAINT fk_approval_merge_request_rules_on_scan_result_policy_id FOREIGN KEY (scan_result_policy_id) REFERENCES scan_result_policies(id) ON DELETE SET NULL;
+
ALTER TABLE ONLY fork_network_members
ADD CONSTRAINT fk_b01280dae4 FOREIGN KEY (forked_from_project_id) REFERENCES projects(id) ON DELETE SET NULL;
@@ -39098,9 +39101,6 @@ ALTER TABLE ONLY boards_epic_list_user_preferences
ALTER TABLE ONLY user_project_callouts
ADD CONSTRAINT fk_f62dd11a33 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
-ALTER TABLE ONLY approval_merge_request_rules
- ADD CONSTRAINT fk_f726c79756 FOREIGN KEY (scan_result_policy_id) REFERENCES scan_result_policies(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY workspaces
ADD CONSTRAINT fk_f78aeddc77 FOREIGN KEY (cluster_agent_id) REFERENCES cluster_agents(id) ON DELETE CASCADE;
diff --git a/doc/administration/job_artifacts_troubleshooting.md b/doc/administration/job_artifacts_troubleshooting.md
index 138803a2675..b8605ff94bf 100644
--- a/doc/administration/job_artifacts_troubleshooting.md
+++ b/doc/administration/job_artifacts_troubleshooting.md
@@ -24,7 +24,7 @@ reasons are:
[Rake task for _orphaned_ artifact files](../raketasks/cleanup.md#remove-orphan-artifact-files)
to remove these. This script should always find work to do, as it also removes empty directories (see above).
- [Artifact housekeeping was changed significantly](#housekeeping-disabled-in-gitlab-146-to-152),
- and you might need to enable a feature flag to used the updated system.
+ and you might need to enable a feature flag to use the updated system.
- The [keep latest artifacts from most recent success jobs](../ci/jobs/job_artifacts.md#keep-artifacts-from-most-recent-successful-jobs)
feature is enabled.
@@ -220,7 +220,7 @@ end
### List projects by total size of job artifacts stored
List the top 20 projects, sorted by the total size of job artifacts stored, by
-running the following code in the Rails console (`sudo gitlab-rails console`):
+running the following code in the [Rails console](operations/rails_console.md):
```ruby
include ActionView::Helpers::NumberHelper
@@ -235,7 +235,7 @@ number you want.
### List largest artifacts in a single project
List the 50 largest job artifacts in a single project by running the following
-code in the Rails console (`sudo gitlab-rails console`):
+code in the [Rails console](operations/rails_console.md):
```ruby
include ActionView::Helpers::NumberHelper
@@ -273,7 +273,7 @@ WARNING:
These commands remove data permanently from database and storage. Before running them, we highly recommend seeking guidance from a Support Engineer, or running them in a test environment with a backup of the instance ready to be restored, just in case.
If you need to manually remove job artifacts associated with multiple jobs while
-**retaining their job logs**, this can be done from the Rails console (`sudo gitlab-rails console`):
+**retaining their job logs**, this can be done from the [Rails console](operations/rails_console.md):
1. Select jobs to be deleted:
@@ -297,7 +297,7 @@ If you need to manually remove job artifacts associated with multiple jobs while
["keep"](../ci/jobs/job_artifacts.md#download-job-artifacts).
```ruby
- builds_to_clear = builds_with_artifacts.where("finished_at < ?", 1.week.ago)
+ builds_to_clear = builds_with_artifacts.where("finished_at < ?", 1.year.ago)
builds_to_clear.find_each do |build|
Ci::JobArtifacts::DeleteService.new(build).execute
build.update!(artifacts_expire_at: Time.now)
@@ -307,19 +307,16 @@ If you need to manually remove job artifacts associated with multiple jobs while
In [GitLab 15.3 and earlier](https://gitlab.com/gitlab-org/gitlab/-/issues/372537), use the following instead:
```ruby
- builds_to_clear = builds_with_artifacts.where("finished_at < ?", 1.week.ago)
+ builds_to_clear = builds_with_artifacts.where("finished_at < ?", 1.year.ago)
builds_to_clear.find_each do |build|
build.artifacts_expire_at = Time.now
build.erase_erasable_artifacts!
end
```
- `1.week.ago` is a Rails `ActiveSupport::Duration` method which calculates a new
- date or time in the past. Other valid examples are:
-
- - `7.days.ago`
- - `3.months.ago`
- - `1.year.ago`
+ `1.year.ago` is a Rails [`ActiveSupport::Duration`](https://api.rubyonrails.org/classes/ActiveSupport/Duration.html) method.
+ Start with a long duration to reduce the risk of accidentally deleting artifacts that are still in use.
+ Rerun the deletion with shorter durations as needed, for example `3.months.ago`, `2.weeks.ago`, or `7.days.ago`.
`erase_erasable_artifacts!` is a synchronous method, and upon execution the artifacts are immediately removed;
they are not scheduled by a background queue.
@@ -330,7 +327,7 @@ WARNING:
These commands remove data permanently from both the database and from disk. Before running them, we highly recommend seeking guidance from a Support Engineer, or running them in a test environment with a backup of the instance ready to be restored, just in case.
If you need to manually remove **all** job artifacts associated with multiple jobs,
-**including job logs**, this can be done from the Rails console (`sudo gitlab-rails console`):
+**including job logs**, this can be done from the [Rails console](operations/rails_console.md):
1. Select the jobs to be deleted:
@@ -371,7 +368,7 @@ If you need to manually remove **all** job artifacts associated with multiple jo
1. Erase the job artifacts and logs older than a specific date:
```ruby
- builds_to_clear = builds_with_artifacts.where("finished_at < ?", 1.week.ago)
+ builds_to_clear = builds_with_artifacts.where("finished_at < ?", 1.year.ago)
builds_to_clear.find_each do |build|
print "Ci::Build ID #{build.id}... "
@@ -387,12 +384,9 @@ If you need to manually remove **all** job artifacts associated with multiple jo
In [GitLab 15.3 and earlier](https://gitlab.com/gitlab-org/gitlab/-/issues/369132), replace
`Ci::BuildEraseService.new(build, admin_user).execute` with `build.erase(erased_by: admin_user)`.
- `1.week.ago` is a Rails `ActiveSupport::Duration` method which calculates a new
- date or time in the past. Other valid examples are:
-
- - `7.days.ago`
- - `3.months.ago`
- - `1.year.ago`
+ `1.year.ago` is a Rails [`ActiveSupport::Duration`](https://api.rubyonrails.org/classes/ActiveSupport/Duration.html) method.
+ Start with a long duration to reduce the risk of accidentally deleting artifacts that are still in use.
+ Rerun the deletion with shorter durations as needed, for example `3.months.ago`, `2.weeks.ago`, or `7.days.ago`.
## Job artifact upload fails with error 500
diff --git a/doc/ci/secrets/gcp_secret_manager.md b/doc/ci/secrets/gcp_secret_manager.md
new file mode 100644
index 00000000000..ad2a2a269eb
--- /dev/null
+++ b/doc/ci/secrets/gcp_secret_manager.md
@@ -0,0 +1,92 @@
+---
+stage: Verify
+group: Pipeline Security
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
+---
+
+# Use GCP Secret Manager secrets in GitLab CI/CD **(PREMIUM ALL)**
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/11739) in GitLab and GitLab Runner 16.8.
+
+You can use secrets stored in the [Google Cloud (GCP) Secret Manager](https://cloud.google.com/security/products/secret-manager)
+in your GitLab CI/CD pipelines.
+
+The flow for using GitLab with GCP Secret Manager
+is summarized by this diagram:
+
+1. GitLab issues ID token to CI/CD job.
+1. The runner authenticates to GCP using an ID token.
+1. GCP verifies the ID token with GitLab.
+1. GCP issues a short-lived access token.
+1. The runner accesses the secret data using the access token.
+1. GCP checks IAM permission on the access token's principal.
+1. GCP returns the secret data to Runner.
+
+To use GitLab with GCP Secret Manager, you must:
+
+- Have secrets stored in [GCP Secret Manager](https://cloud.google.com/security/products/secret-manager).
+- Configure [GCP Workload Identity Federation](#configure-gcp-iam-workload-identify-federation-wif) to include GitLab as an identity provider.
+- Configure [GCP IAM](#grant-access-to-gcp-iam-principal) permissions to grant access to GCP Secret Manager.
+- Configure [GitLab CI/CD with GCP Secret Manager](#configure-gitlab-cicd-to-use-gcp-secret-manager-secrets).
+
+## Configure GCP IAM Workload Identify Federation (WIF)
+
+GCP IAM WIF must be configured to recognize ID tokens issued by GitLab and assign an appropriate principal to them.
+The principal is used to authorize access to the Secret Manager resources:
+
+1. In GCP Console, go to **IAM & Admin > Workload Identity Federation**.
+1. Select **CREATE POOL** and create a new identity pool with a unique name, for example `gitlab-pool`.
+1. Select **ADD PROVIDER** to add a new OIDC Provider to the Identity Pool with a unique name, for example `gitlab-provider`.
+ 1. Set **Issuer (URL)** to the GitLab URL, for example `https://gitlab.com`.
+ 1. Select **Default audience**, or select **Allowed audiences** for a custom audience, which is used in the `aud` for the GitLab CI/CD ID token.
+1. Under **Attribute Mapping**, configure provider attributes, which are mappings between the [OIDC claims](id_token_authentication.md#token-payload)
+ (referred to as "assertion") and Google attributes. These mappings can be used to set fine grained access control.
+ For example, to grant a GitLab project access to Secret Manager secrets, select **ADD MAPPING** and create a mapping of
+ `attribute.gitlab_project_id` to `assertion.project_id`.
+
+## Grant access to GCP IAM principal
+
+After setting up WIF, you must grant the WIF principal access to the secrets in Secret Manager.
+
+1. In GCP Console, go to **IAM & Admin > IAM**.
+1. Select **GRANT ACCESS** to grant access to the principal set created through the WIF provider. For example,
+ to grant IAM access to the principal matching the project with ID `123`, add
+ a new principal like: `principalSet://iam.googleapis.com/projects/[PROJECT_NUMBER]/locations/global/workloadIdentityPools/[POOL_ID]/attribute.gitlab_project_id/[PROJECT_ID]`.
+1. Assign the role **Secret Manager Secret Accessor**.
+1. (Optional) Select **IAM condition (Optional)** to add an IAM condition.
+ Under **Condition Builder**, you can add conditions. For example, you could add two `AND` conditions:
+ - First condition:
+ - **Condition type**: `Type`
+ - **Operator**: `is`
+ - **Resource type**: `secretmanager.googleapis.com/SecretVersion`
+ - Second condition:
+ - **Condition type**: `Name`
+ - **Operator**: `Starts with`
+ - **Value**: The pattern of secrets that you want to grant access to.
+
+You can add additional IAM conditions for fine-grained access controls, including
+accessing secrets with names starting with the project name.
+
+## Configure GitLab CI/CD to use GCP Secret Manager secrets
+
+You can use secrets stored in GCP Secret Manager in CI/CD jobs by defining them with the `gcp_secret_manager` keyword:
+
+```yaml
+job_using_gcp_sm:
+ id_tokens:
+ GCP_ID_TOKEN:
+ # `aud` must match the audience defined in the WIF Identity Pool.
+ aud: https://iam.googleapis.com/projects/1234/locations/global/workloadIdentityPools/gitlab-pool/providers/gitlab-provider
+ secrets:
+ DATABASE_PASSWORD:
+ gcp_secret_manager:
+ name: my-project-secret # This is the name of the secret defined in GCP Secret Manager
+ version: 1 # optional: default to `latest`.
+ token: $GCP_ID_TOKEN
+```
+
+You must also [add these CI/CD variables](../variables/index.md#for-a-project) to provide details about your GCP Secret Manager:
+
+- `GCP_PROJECT_NUMBER`: The GCP [Project Number](https://cloud.google.com/resource-manager/docs/creating-managing-projects)
+- `GCP_WORKLOAD_IDENTITY_FEDERATION_POOL_ID`: The WIF Pool ID (e.g `gitlab-pool`)
+- `GCP_WORKLOAD_IDENTITY_FEDERATION_PROVIDER_ID`: The WIF Provider ID (e.g `gitlab-provider`)
diff --git a/doc/ci/secrets/index.md b/doc/ci/secrets/index.md
index e452b26d8a9..96b9709bdef 100644
--- a/doc/ci/secrets/index.md
+++ b/doc/ci/secrets/index.md
@@ -18,6 +18,12 @@ Unlike CI/CD variables, which are always presented to a job, secrets must be exp
required by a job. Read [GitLab CI/CD pipeline configuration reference](../yaml/index.md#secrets)
for more information about the syntax.
+GitLab provides support for the following secret management providers:
+
+1. [Vault by HashiCorp](#use-vault-secrets-in-a-ci-job)
+1. [Google Cloud Secret Manager](gcp_secret_manager.md)
+1. [Azure Key Vault](azure_key_vault.md)
+
GitLab has selected [Vault by HashiCorp](https://www.vaultproject.io) as the
first supported provider, and [KV-V2](https://developer.hashicorp.com/vault/docs/secrets/kv/kv-v2)
as the first supported secrets engine.
diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md
index 35b35567d8f..27f6113345f 100644
--- a/doc/ci/yaml/index.md
+++ b/doc/ci/yaml/index.md
@@ -4253,6 +4253,34 @@ job:
vault: production/db/password@ops # Translates to secret: `ops/data/production/db`, field: `password`
```
+#### `secrets:gcp_secret_manager`
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/11739) in GitLab 16.8 and GitLab Runner 16.8.
+
+Use `secrets:gcp_secret_manager` to specify secrets provided by [GCP Secret Manager](https://cloud.google.com/security/products/secret-manager).
+
+**Keyword type**: Job keyword. You can use it only as part of a job.
+
+**Possible inputs**:
+
+- `name`: Name of the secret.
+- `version`: Version of the secret.
+
+**Example of `secrets:gcp_secret_manager`**:
+
+```yaml
+job:
+ secrets:
+ DATABASE_PASSWORD:
+ gcp_secret_manager:
+ name: 'test'
+ version: 2
+```
+
+**Related topics**:
+
+- [Use GCP Secret Manager secrets in GitLab CI/CD](../secrets/gcp_secret_manager.md).
+
#### `secrets:azure_key_vault`
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/271271) in GitLab 16.3 and GitLab Runner 16.3.
diff --git a/doc/development/internal_analytics/index.md b/doc/development/internal_analytics/index.md
index b5403f56600..0875ea7afad 100644
--- a/doc/development/internal_analytics/index.md
+++ b/doc/development/internal_analytics/index.md
@@ -95,7 +95,6 @@ SELECT
COUNT(*) as event_occurences
FROM common_mart.mart_behavior_structured_event
WHERE event_action = 'feature_used'
-AND event_category = 'InternalEventTracking'
AND behavior_date > '2023-08-01' --restricted minimum date for performance
AND app_id='gitlab' -- use gitlab for production events and gitlab-staging for events from staging
GROUP BY 1 ORDER BY 1 desc
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 55739eae24b..c2da2cf6deb 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -1934,6 +1934,12 @@ msgstr ""
msgid "AIAgents|Create agent"
msgstr ""
+msgid "AIAgents|New AI Agent"
+msgstr ""
+
+msgid "AIAgents|New agent"
+msgstr ""
+
msgid "AIPoweredSM|AI-powered features"
msgstr ""
diff --git a/spec/features/search/user_searches_for_code_spec.rb b/spec/features/search/user_searches_for_code_spec.rb
index 9329b1f2a5e..f893bf9b608 100644
--- a/spec/features/search/user_searches_for_code_spec.rb
+++ b/spec/features/search/user_searches_for_code_spec.rb
@@ -74,6 +74,20 @@ RSpec.describe 'User searches for code', :js, :disable_rate_limiter, feature_cat
it_behaves_like 'code highlight' do
subject { page }
end
+
+ context 'no search term' do
+ before do
+ submit_dashboard_search('dashboard_search')
+ # fill_in('dashboard_search', with: '')
+ # find('.gl-search-box-by-click-search-button').click
+ end
+
+ it 'shows scopes' do
+ page.within('[data-testid="search-filter"]') do
+ expect(page).to have_selector('[data-testid="nav-item"]', minimum: 5)
+ end
+ end
+ end
end
it 'search multiple words with refs switching' do
diff --git a/spec/features/search/user_searches_for_comments_spec.rb b/spec/features/search/user_searches_for_comments_spec.rb
index f7af1797c71..92e9174295b 100644
--- a/spec/features/search/user_searches_for_comments_spec.rb
+++ b/spec/features/search/user_searches_for_comments_spec.rb
@@ -33,6 +33,14 @@ RSpec.describe 'User searches for comments', :js, :disable_rate_limiter, feature
end
end
+ it 'shows scopes when there is no search term' do
+ submit_dashboard_search('')
+
+ within_testid('search-filter') do
+ expect(page).to have_selector('[data-testid="nav-item"]', minimum: 5)
+ end
+ end
+
context 'when a comment is in a snippet' do
let(:snippet) { create(:project_snippet, :private, project: project, author: user, title: 'Some title') }
let(:comment) { create(:note, noteable: snippet, author: user, note: 'Supercalifragilisticexpialidocious', project: project) }
diff --git a/spec/features/search/user_searches_for_commits_spec.rb b/spec/features/search/user_searches_for_commits_spec.rb
index 724daf9277d..2510a7f9b20 100644
--- a/spec/features/search/user_searches_for_commits_spec.rb
+++ b/spec/features/search/user_searches_for_commits_spec.rb
@@ -19,6 +19,14 @@ RSpec.describe 'User searches for commits', :js, :clean_gitlab_redis_rate_limiti
let(:additional_params) { { project_id: project.id } }
end
+ it 'shows scopes when there is no search term' do
+ submit_dashboard_search('')
+
+ within_testid('search-filter') do
+ expect(page).to have_selector('[data-testid="nav-item"]', minimum: 5)
+ end
+ end
+
context 'when searching by SHA' do
it 'finds a commit and redirects to its page' do
submit_search(sha)
diff --git a/spec/features/search/user_searches_for_issues_spec.rb b/spec/features/search/user_searches_for_issues_spec.rb
index caddf8b698e..610b9e2f09d 100644
--- a/spec/features/search/user_searches_for_issues_spec.rb
+++ b/spec/features/search/user_searches_for_issues_spec.rb
@@ -103,6 +103,14 @@ RSpec.describe 'User searches for issues', :js, :clean_gitlab_redis_rate_limitin
end
end
end
+
+ it 'shows scopes when there is no search term' do
+ search_for_issue('')
+
+ page.within('[data-testid="search-filter"]') do
+ expect(page).to have_selector('[data-testid="nav-item"]', minimum: 5)
+ end
+ end
end
context 'when signed out' do
diff --git a/spec/features/search/user_searches_for_merge_requests_spec.rb b/spec/features/search/user_searches_for_merge_requests_spec.rb
index 7819e036f21..faefa55586d 100644
--- a/spec/features/search/user_searches_for_merge_requests_spec.rb
+++ b/spec/features/search/user_searches_for_merge_requests_spec.rb
@@ -23,6 +23,14 @@ RSpec.describe 'User searches for merge requests', :js, :clean_gitlab_redis_rate
include_examples 'top right search form'
include_examples 'search timeouts', 'merge_requests'
+ it 'shows scopes when there is no search term' do
+ submit_dashboard_search('')
+
+ page.within('[data-testid="search-filter"]') do
+ expect(page).to have_selector('[data-testid="nav-item"]', minimum: 5)
+ end
+ end
+
it 'finds a merge request' do
search_for_mr(merge_request1.title)
diff --git a/spec/features/search/user_searches_for_milestones_spec.rb b/spec/features/search/user_searches_for_milestones_spec.rb
index 334fe6f0170..2700785ac1a 100644
--- a/spec/features/search/user_searches_for_milestones_spec.rb
+++ b/spec/features/search/user_searches_for_milestones_spec.rb
@@ -20,6 +20,14 @@ RSpec.describe 'User searches for milestones', :js, :clean_gitlab_redis_rate_lim
include_examples 'top right search form'
include_examples 'search timeouts', 'milestones'
+ it 'shows scopes when there is no search term' do
+ submit_dashboard_search('')
+
+ page.within('[data-testid="search-filter"]') do
+ expect(page).to have_selector('[data-testid="nav-item"]', minimum: 5)
+ end
+ end
+
it 'finds a milestone' do
submit_dashboard_search(milestone1.title)
select_search_scope('Milestones')
diff --git a/spec/features/search/user_searches_for_projects_spec.rb b/spec/features/search/user_searches_for_projects_spec.rb
index ee5a3ec9806..8d94ed2a08e 100644
--- a/spec/features/search/user_searches_for_projects_spec.rb
+++ b/spec/features/search/user_searches_for_projects_spec.rb
@@ -14,6 +14,14 @@ RSpec.describe 'User searches for projects', :js, :disable_rate_limiter, feature
include_examples 'top right search form'
include_examples 'search timeouts', 'projects'
+ it 'shows scopes when there is no search term' do
+ submit_dashboard_search('')
+
+ within_testid('search-filter') do
+ expect(page).to have_selector('[data-testid="nav-item"]', minimum: 5)
+ end
+ end
+
it 'finds a project' do
visit(search_path)
submit_dashboard_search(project.name[0..3])
diff --git a/spec/features/search/user_searches_for_users_spec.rb b/spec/features/search/user_searches_for_users_spec.rb
index e0a07c5103d..2628b329d96 100644
--- a/spec/features/search/user_searches_for_users_spec.rb
+++ b/spec/features/search/user_searches_for_users_spec.rb
@@ -17,6 +17,14 @@ RSpec.describe 'User searches for users', :js, :clean_gitlab_redis_rate_limiting
end
end
+ it 'shows scopes when there is no search term' do
+ submit_dashboard_search('')
+
+ within_testid('search-filter') do
+ expect(page).to have_selector('[data-testid="nav-item"]', minimum: 5)
+ end
+ end
+
context 'when on the dashboard' do
it 'finds the user' do
visit dashboard_projects_path
diff --git a/spec/features/search/user_searches_for_wiki_pages_spec.rb b/spec/features/search/user_searches_for_wiki_pages_spec.rb
index 4de28a99c21..85cc3900fad 100644
--- a/spec/features/search/user_searches_for_wiki_pages_spec.rb
+++ b/spec/features/search/user_searches_for_wiki_pages_spec.rb
@@ -23,6 +23,14 @@ RSpec.describe 'User searches for wiki pages', :js, :clean_gitlab_redis_rate_lim
let(:additional_params) { { project_id: project.id } }
end
+ it 'shows scopes when there is no search term' do
+ submit_dashboard_search('')
+
+ page.within('[data-testid="search-filter"]') do
+ expect(page).to have_selector('[data-testid="nav-item"]', minimum: 5)
+ end
+ end
+
shared_examples 'search wiki blobs' do
it 'finds a page' do
find('[data-testid="project-filter"]').click
diff --git a/spec/frontend/comment_templates/components/form_spec.js b/spec/frontend/comment_templates/components/form_spec.js
index b48feba5290..05ddf94b72b 100644
--- a/spec/frontend/comment_templates/components/form_spec.js
+++ b/spec/frontend/comment_templates/components/form_spec.js
@@ -74,7 +74,7 @@ describe('Comment templates form component', () => {
name: 'Test',
});
expect(trackingSpy).toHaveBeenCalledWith(
- expect.any(String),
+ undefined,
'i_code_review_saved_replies_create',
expect.any(Object),
);
diff --git a/spec/frontend/vue_shared/components/markdown/comment_templates_dropdown_spec.js b/spec/frontend/vue_shared/components/markdown/comment_templates_dropdown_spec.js
index 11c57fc5768..01122fe1103 100644
--- a/spec/frontend/vue_shared/components/markdown/comment_templates_dropdown_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/comment_templates_dropdown_spec.js
@@ -98,7 +98,7 @@ describe('Comment templates dropdown', () => {
await selectSavedReply();
expect(trackingSpy).toHaveBeenCalledWith(
- expect.any(String),
+ undefined,
TRACKING_SAVED_REPLIES_USE,
expect.any(Object),
);
@@ -111,7 +111,7 @@ describe('Comment templates dropdown', () => {
await selectSavedReply();
expect(trackingSpy).toHaveBeenCalledWith(
- expect.any(String),
+ undefined,
TRACKING_SAVED_REPLIES_USE_IN_MR,
expect.any(Object),
);
@@ -137,7 +137,7 @@ describe('Comment templates dropdown', () => {
await selectSavedReply();
expect(trackingSpy).toHaveBeenCalledWith(
- expect.any(String),
+ undefined,
TRACKING_SAVED_REPLIES_USE_IN_OTHER,
expect.any(Object),
);
diff --git a/spec/helpers/sessions_helper_spec.rb b/spec/helpers/sessions_helper_spec.rb
index 366032100de..adf7b92127e 100644
--- a/spec/helpers/sessions_helper_spec.rb
+++ b/spec/helpers/sessions_helper_spec.rb
@@ -3,42 +3,6 @@
require 'spec_helper'
RSpec.describe SessionsHelper, feature_category: :system_access do
- describe '#recently_confirmed_com?' do
- subject { helper.recently_confirmed_com? }
-
- context 'when on .com' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- it 'when flash notice is empty it is false' do
- flash[:notice] = nil
- expect(subject).to be false
- end
-
- it 'when flash notice is anything it is false' do
- flash[:notice] = 'hooray!'
- expect(subject).to be false
- end
-
- it 'when flash notice is devise confirmed message it is true' do
- flash[:notice] = t(:confirmed, scope: [:devise, :confirmations])
- expect(subject).to be true
- end
- end
-
- context 'when not on .com' do
- before do
- allow(Gitlab).to receive(:com?).and_return(false)
- end
-
- it 'when flash notice is devise confirmed message it is false' do
- flash[:notice] = t(:confirmed, scope: [:devise, :confirmations])
- expect(subject).to be false
- end
- end
- end
-
describe '#unconfirmed_email?' do
it 'returns true when the flash alert contains a devise failure unconfirmed message' do
flash[:alert] = t(:unconfirmed, scope: [:devise, :failure])
diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb
index b8217ffd2c9..2beab48fb73 100644
--- a/spec/models/deployment_spec.rb
+++ b/spec/models/deployment_spec.rb
@@ -56,6 +56,8 @@ RSpec.describe Deployment, feature_category: :continuous_delivery do
let(:scope_attrs) { { project: project } }
let(:usage) { :deployments }
end
+
+ it { is_expected.to include_module(EachBatch) }
end
describe '.stoppable' do
diff --git a/spec/services/projects/destroy_service_spec.rb b/spec/services/projects/destroy_service_spec.rb
index 3aea329a45f..e5dd17a3c7c 100644
--- a/spec/services/projects/destroy_service_spec.rb
+++ b/spec/services/projects/destroy_service_spec.rb
@@ -166,6 +166,14 @@ RSpec.describe Projects::DestroyService, :aggregate_failures, :event_store_publi
end
end
+ context 'deleting a project with deployments' do
+ let!(:deployment) { create(:deployment, project: project) }
+
+ it 'deletes deployments' do
+ expect { destroy_project(project, user, {}) }.to change(Deployment, :count).by(-1)
+ end
+ end
+
it_behaves_like 'deleting the project'
context 'personal projects count cache' do