diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 32ccaeb1a02..f9f6b01d545 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -176,18 +176,6 @@ variables:
GET_SOURCES_ATTEMPTS: "3"
# CI_FETCH_REPO_GIT_STRATEGY: "none" is from artifacts. "clone" is from cloning
CI_FETCH_REPO_GIT_STRATEGY: "none"
- BUILD_OS: "debian"
- OS_VERSION: "bookworm"
- UBI_VERSION: "8.6"
- CHROME_VERSION: "123"
- DOCKER_VERSION: "24.0.5"
- RUBYGEMS_VERSION: "3.4"
- BUNDLER_VERSION: "2.5"
- GO_VERSION: "1.22"
- NODE_VERSION: "20.12"
- RUST_VERSION: "1.73"
- RUBY_VERSION_DEFAULT: "3.1.5"
- RUBY_VERSION_NEXT: "3.2.4"
FLAKY_RSPEC_SUITE_REPORT_PATH: rspec/flaky/report-suite.json
FRONTEND_FIXTURES_MAPPING_PATH: crystalball/frontend_fixtures_mapping.json
@@ -254,6 +242,7 @@ include:
- local: .gitlab/ci/_skip.yml
rules:
- <<: *if-merge-request-security-canonical-sync
+ - local: .gitlab/ci/version.yml
- local: .gitlab/ci/*.gitlab-ci.yml
rules:
- <<: *if-not-security-canonical-sync
diff --git a/.gitlab/ci/qa-common/main.gitlab-ci.yml b/.gitlab/ci/qa-common/main.gitlab-ci.yml
index febb4e14e33..80ea4a10f2b 100644
--- a/.gitlab/ci/qa-common/main.gitlab-ci.yml
+++ b/.gitlab/ci/qa-common/main.gitlab-ci.yml
@@ -5,7 +5,7 @@ workflow:
name: $PIPELINE_NAME
include:
- - component: "gitlab.com/gitlab-org/quality/pipeline-common/allure-report@8.10.0"
+ - component: "gitlab.com/gitlab-org/quality/pipeline-common/allure-report@8.15.0"
inputs:
job_name: "e2e-test-report"
job_stage: "report"
@@ -15,7 +15,7 @@ include:
gitlab_auth_token_variable_name: "PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE"
allure_job_name: "${QA_RUN_TYPE}"
- project: gitlab-org/quality/pipeline-common
- ref: 8.10.0
+ ref: 8.15.0
file:
- /ci/base.gitlab-ci.yml
- /ci/knapsack-report.yml
diff --git a/.gitlab/ci/version.yml b/.gitlab/ci/version.yml
new file mode 100644
index 00000000000..3369957ff30
--- /dev/null
+++ b/.gitlab/ci/version.yml
@@ -0,0 +1,13 @@
+variables:
+ BUILD_OS: "debian"
+ OS_VERSION: "bookworm"
+ UBI_VERSION: "8.6"
+ CHROME_VERSION: "123"
+ DOCKER_VERSION: "24.0.5"
+ RUBYGEMS_VERSION: "3.4"
+ BUNDLER_VERSION: "2.5"
+ GO_VERSION: "1.22"
+ NODE_VERSION: "20.12"
+ RUST_VERSION: "1.73"
+ RUBY_VERSION_DEFAULT: "3.1.5"
+ RUBY_VERSION_NEXT: "3.2.4"
diff --git a/Gemfile.checksum b/Gemfile.checksum
index 707fa2b6314..755bb64db30 100644
--- a/Gemfile.checksum
+++ b/Gemfile.checksum
@@ -575,17 +575,17 @@
{"name":"rouge","version":"4.2.0","platform":"ruby","checksum":"60dd666b3a223467dc72f5b7384764dfd7ad4e50b0df9eff072be58123506eba"},
{"name":"rqrcode","version":"2.2.0","platform":"ruby","checksum":"23eea88bb44c7ee6d6cab9354d08c287f7ebcdc6112e1fe7bcc2d010d1ffefc1"},
{"name":"rqrcode_core","version":"1.2.0","platform":"ruby","checksum":"cf4989dc82d24e2877984738c4ee569308625fed2a810960f1b02d68d0308d1a"},
-{"name":"rspec","version":"3.13.0","platform":"ruby","checksum":"d490914ac1d5a5a64a0e1400c1d54ddd2a501324d703b8cfe83f458337bab993"},
+{"name":"rspec","version":"3.12.0","platform":"ruby","checksum":"ccc41799a43509dc0be84070e3f0410ac95cbd480ae7b6c245543eb64162399c"},
{"name":"rspec-benchmark","version":"0.6.0","platform":"ruby","checksum":"1014adb57ec2599a2455c63884229f367a2fff6a63a77fd68ce5d804c83dd6cf"},
-{"name":"rspec-core","version":"3.13.0","platform":"ruby","checksum":"557792b4e88da883d580342b263d9652b6a10a12d5bda9ef967b01a48f15454c"},
-{"name":"rspec-expectations","version":"3.13.0","platform":"ruby","checksum":"621d48c62262f955421eaa418130744760802cad47e781df70dba4d9f897102e"},
-{"name":"rspec-mocks","version":"3.13.1","platform":"ruby","checksum":"087189899c337937bcf1d66a50dc3fc999ac88335bbeba4d385c2a38c87d7b38"},
+{"name":"rspec-core","version":"3.12.2","platform":"ruby","checksum":"155b54480f28e2b2813185077fe435c2d663031616360ed3b179a9d6a55d2551"},
+{"name":"rspec-expectations","version":"3.12.3","platform":"ruby","checksum":"093d18e2e7e0a2c619ef8f7343d442fc6c0793fb7897d56f16f26c8a9d244416"},
+{"name":"rspec-mocks","version":"3.12.6","platform":"ruby","checksum":"de51a4148ba2ce6f1c1646a2a03e9df2f52da9a42b164f2e7467b2cbe37e07bf"},
{"name":"rspec-parameterized","version":"1.0.2","platform":"ruby","checksum":"b456dec0091924175ac13963e173cdbaa2ab3e1581a405a948addc34e3f3f4c2"},
{"name":"rspec-parameterized-core","version":"1.0.0","platform":"ruby","checksum":"287b494985e79821160af63aba4f91db8dbfa9a21cb200db34ba38f40e16ccc1"},
{"name":"rspec-parameterized-table_syntax","version":"1.0.0","platform":"ruby","checksum":"d7df951eff9c5dd367ca7d5f9ae4853bb7ab7941f9d5b35bba361d112704988c"},
-{"name":"rspec-rails","version":"6.1.2","platform":"ruby","checksum":"02874ab2e3b09001742af389c48739bed8706943e453afaea5e12614a83b990b"},
+{"name":"rspec-rails","version":"6.1.1","platform":"ruby","checksum":"bd949e61f89379f410ea1e43133163282f8d977c683ce6d10bf5aef6b1e995b2"},
{"name":"rspec-retry","version":"0.6.2","platform":"ruby","checksum":"6101ba23a38809811ae3484acde4ab481c54d846ac66d5037ccb40131a60d858"},
-{"name":"rspec-support","version":"3.13.1","platform":"ruby","checksum":"48877d4f15b772b7538f3693c22225f2eda490ba65a0515c4e7cf6f2f17de70f"},
+{"name":"rspec-support","version":"3.12.0","platform":"ruby","checksum":"dd4d44b247ff679b95b5607ac5641d197a5f9b1d33f916123cb98fc5f917c58b"},
{"name":"rspec_junit_formatter","version":"0.6.0","platform":"ruby","checksum":"40dde674e6ae4e6cc0ff560da25497677e34fefd2338cc467a8972f602b62b15"},
{"name":"rspec_profiling","version":"0.0.9","platform":"ruby","checksum":"6199be2daeaa14bac3d10d704dbb0a8df052cf046332c505603263aea24f7590"},
{"name":"rubocop","version":"1.62.1","platform":"ruby","checksum":"aeb1ec501aef5833617b3b6a1512303806218c349c28ce5b3ea72e3782ad4a35"},
diff --git a/Gemfile.lock b/Gemfile.lock
index 9de3cb335cf..225cdda511c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1525,23 +1525,23 @@ GEM
chunky_png (~> 1.0)
rqrcode_core (~> 1.0)
rqrcode_core (1.2.0)
- rspec (3.13.0)
- rspec-core (~> 3.13.0)
- rspec-expectations (~> 3.13.0)
- rspec-mocks (~> 3.13.0)
+ rspec (3.12.0)
+ rspec-core (~> 3.12.0)
+ rspec-expectations (~> 3.12.0)
+ rspec-mocks (~> 3.12.0)
rspec-benchmark (0.6.0)
benchmark-malloc (~> 0.2)
benchmark-perf (~> 0.6)
benchmark-trend (~> 0.4)
rspec (>= 3.0)
- rspec-core (3.13.0)
- rspec-support (~> 3.13.0)
- rspec-expectations (3.13.0)
+ rspec-core (3.12.2)
+ rspec-support (~> 3.12.0)
+ rspec-expectations (3.12.3)
diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.13.0)
- rspec-mocks (3.13.1)
+ rspec-support (~> 3.12.0)
+ rspec-mocks (3.12.6)
diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.13.0)
+ rspec-support (~> 3.12.0)
rspec-parameterized (1.0.2)
rspec-parameterized-core (< 2)
rspec-parameterized-table_syntax (< 2)
@@ -1553,17 +1553,17 @@ GEM
rspec-parameterized-table_syntax (1.0.0)
binding_of_caller
rspec-parameterized-core (< 2)
- rspec-rails (6.1.2)
+ rspec-rails (6.1.1)
actionpack (>= 6.1)
activesupport (>= 6.1)
railties (>= 6.1)
- rspec-core (~> 3.13)
- rspec-expectations (~> 3.13)
- rspec-mocks (~> 3.13)
- rspec-support (~> 3.13)
+ rspec-core (~> 3.12)
+ rspec-expectations (~> 3.12)
+ rspec-mocks (~> 3.12)
+ rspec-support (~> 3.12)
rspec-retry (0.6.2)
rspec-core (> 3.3)
- rspec-support (3.13.1)
+ rspec-support (3.12.0)
rspec_junit_formatter (0.6.0)
rspec-core (>= 2, < 4, != 2.12.0)
rspec_profiling (0.0.9)
diff --git a/app/assets/javascripts/ci/pipeline_mini_graph/README.md b/app/assets/javascripts/ci/pipeline_mini_graph/README.md
new file mode 100644
index 00000000000..35f1729199e
--- /dev/null
+++ b/app/assets/javascripts/ci/pipeline_mini_graph/README.md
@@ -0,0 +1,35 @@
+# Pipeline Mini Graph
+
+This documentation serves as a usage guide for the Pipeline Mini Graph. The Pipeline Mini Graph is used in various places throughout the platform to communicate to users the status of the relevant pipeline. Users are able to re-run jobs directly from the component or drilldown into said jobs and linked pipelines for further investigation.
+
+The [architecture blueprint for the Pipeline Mini Graph](https://docs.gitlab.com/ee/architecture/blueprints/pipeline_mini_graph/) is available for more context. Furthermore, if you have questions about implementation of this component, please reach out to @gitlab-com/pipeline-authoring-group/frontend in your issue or MR.
+
+## Usage
+
+This component can be instantiated by apps supporting either REST or GraphQL
+
+### REST Structure
+
+This is the current version of the component used by all apps in production. The parent component lives at `app/assets/javascripts/ci/pipeline_mini_graph/legacy_pipeline_mini_graph/legacy_pipeline_mini_graph.vue`. The legacy component needs all necessary pipeline data passed into it. [This data is fetched by apps via REST endpoint](https://docs.gitlab.com/ee/api/pipelines.html#get-a-single-pipeline). To use, import this component into your code and send the following props:
+
+| Name | Type | Required | Description |
+| ---- | ---- | -------- | ----------- |
+|`downstreamPipelines` | Array | false | pipelines triggered by current pipeline |
+|`isMergeTrain` | Boolean | false | whether the pipeline is part of a merge train |
+|`pipelinePath` | String | false | pipeline URL |
+|`stages` | Array | true | stages of current pipeline |
+|`updateDropdown` | Boolean | false | whether to fetch jobs when the dropdown is open |
+|`upstreamPipeline` | Object | false | upstream pipeline which triggered current pipeline |
+
+### GraphQL Structure
+
+Note: This component currently exists behind a feature flag `ci_graphql_pipeline_mini_graph` and is under construction.
+The parent component lives at`app/assets/javascripts/ci/pipeline_mini_graph/pipeline_mini_graph.vue`. This instance of the pipeline mini graph has self-managed data. [We use GraphQL to query for pipeline data within the component](https://docs.gitlab.com/ee/api/graphql/reference/#pipeline). It needs only the fields necessary to query for the data. To use, import this component into your code and send the following props:
+
+| Name | Type | Required | Description |
+| ---- | ---- | -------- | ----------- |
+|`fullPath` | String | true | full path of the project for the queries |
+|`iid` | String | true | pipeline iid for the queries |
+|`isMergeTrain` | Boolean | false | whether the pipeline is part of a merge train (under consideration) |
+|`pipelineEtag` | String | true | etag for caching (under consideration) |
+|`pollInterval` | Number | false | interval for polling updates |
diff --git a/app/assets/stylesheets/page_bundles/wiki.scss b/app/assets/stylesheets/page_bundles/wiki.scss
index 4539e007b83..f765d6ec219 100644
--- a/app/assets/stylesheets/page_bundles/wiki.scss
+++ b/app/assets/stylesheets/page_bundles/wiki.scss
@@ -77,7 +77,7 @@
}
.sidebar-container {
- padding: $gl-padding 0;
+ padding: 20px 0;
padding-right: 100px;
height: 100%;
overflow-y: scroll;
@@ -100,7 +100,7 @@
&:hover {
a {
- color: $black;
+ color: var(--black, $black);
}
}
diff --git a/config/feature_flags/development/github_import_lock_user_finder.yml b/config/feature_flags/development/github_import_lock_user_finder.yml
deleted file mode 100644
index 812e899ae21..00000000000
--- a/config/feature_flags/development/github_import_lock_user_finder.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: github_import_lock_user_finder
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/141826
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/438336
-milestone: '16.9'
-type: development
-group: group::import and integrate
-default_enabled: false
diff --git a/data/deprecations/15-9-database-single-database-connection-conf.yml b/data/deprecations/15-9-database-single-database-connection-conf.yml
index e72f2043be4..853d206de55 100644
--- a/data/deprecations/15-9-database-single-database-connection-conf.yml
+++ b/data/deprecations/15-9-database-single-database-connection-conf.yml
@@ -1,7 +1,6 @@
- title: "Single database connection is deprecated"
announcement_milestone: "15.9"
- end_of_support_milestone: "17.0"
- removal_milestone: "18.0"
+ removal_milestone: "19.0"
breaking_change: true
reporter: tkuah
stage: Enablement
diff --git a/db/docs/batched_background_migrations/backfill_dast_pre_scan_verifications_project_id.yml b/db/docs/batched_background_migrations/backfill_dast_pre_scan_verifications_project_id.yml
new file mode 100644
index 00000000000..6c318a7424b
--- /dev/null
+++ b/db/docs/batched_background_migrations/backfill_dast_pre_scan_verifications_project_id.yml
@@ -0,0 +1,9 @@
+---
+migration_job_name: BackfillDastPreScanVerificationsProjectId
+description: Backfills sharding key `dast_pre_scan_verifications.project_id` from `dast_profiles`.
+feature_category: dynamic_application_security_testing
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/155076
+milestone: '17.1'
+queued_migration_version: 20240603121642
+finalize_after: '2024-07-22'
+finalized_by: # version of the migration that finalized this BBM
diff --git a/db/docs/ci_minutes_additional_packs.yml b/db/docs/ci_minutes_additional_packs.yml
index 0c243aae35e..fe51d074704 100644
--- a/db/docs/ci_minutes_additional_packs.yml
+++ b/db/docs/ci_minutes_additional_packs.yml
@@ -4,7 +4,7 @@ classes:
- Ci::Minutes::AdditionalPack
feature_categories:
- consumables_cost_management
-description: Stores CI minutes purchases for a given namespace with fields for synchronizing
+description: Stores compute minutes purchases for a given namespace with fields for synchronizing
and expiring available minutes between Customers Portal and GitLab.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62393
milestone: '14.0'
diff --git a/db/docs/dast_pre_scan_verifications.yml b/db/docs/dast_pre_scan_verifications.yml
index db235e04b9b..316c3377f23 100644
--- a/db/docs/dast_pre_scan_verifications.yml
+++ b/db/docs/dast_pre_scan_verifications.yml
@@ -19,3 +19,4 @@ desired_sharding_key:
table: dast_profiles
sharding_key: project_id
belongs_to: dast_profile
+desired_sharding_key_migration_job_name: BackfillDastPreScanVerificationsProjectId
diff --git a/db/docs/namespace_statistics.yml b/db/docs/namespace_statistics.yml
index 07ce93e468b..1b1f6e141ef 100644
--- a/db/docs/namespace_statistics.yml
+++ b/db/docs/namespace_statistics.yml
@@ -4,7 +4,7 @@ classes:
- NamespaceStatistics
feature_categories:
- consumables_cost_management
-description: Stores usage statistics for both CI minutes and a limited set of storage types for a given namespace. This should not be confused with namespace_root_storage_statistics table which holds statistics across more storage types for a group.
+description: Stores usage statistics for both compute minutes and a limited set of storage types for a given namespace. This should not be confused with namespace_root_storage_statistics table which holds statistics across more storage types for a group.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/965
milestone: '9.0'
gitlab_schema: gitlab_main_cell
diff --git a/db/migrate/20240603121638_add_project_id_to_dast_pre_scan_verifications.rb b/db/migrate/20240603121638_add_project_id_to_dast_pre_scan_verifications.rb
new file mode 100644
index 00000000000..eaaa05902ca
--- /dev/null
+++ b/db/migrate/20240603121638_add_project_id_to_dast_pre_scan_verifications.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddProjectIdToDastPreScanVerifications < Gitlab::Database::Migration[2.2]
+ milestone '17.1'
+
+ def change
+ add_column :dast_pre_scan_verifications, :project_id, :bigint
+ end
+end
diff --git a/db/post_migrate/20240603121639_index_dast_pre_scan_verifications_on_project_id.rb b/db/post_migrate/20240603121639_index_dast_pre_scan_verifications_on_project_id.rb
new file mode 100644
index 00000000000..65057fd2e36
--- /dev/null
+++ b/db/post_migrate/20240603121639_index_dast_pre_scan_verifications_on_project_id.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class IndexDastPreScanVerificationsOnProjectId < Gitlab::Database::Migration[2.2]
+ milestone '17.1'
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_dast_pre_scan_verifications_on_project_id'
+
+ def up
+ add_concurrent_index :dast_pre_scan_verifications, :project_id, name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :dast_pre_scan_verifications, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20240603121640_add_dast_pre_scan_verifications_project_id_fk.rb b/db/post_migrate/20240603121640_add_dast_pre_scan_verifications_project_id_fk.rb
new file mode 100644
index 00000000000..18a5ae129ec
--- /dev/null
+++ b/db/post_migrate/20240603121640_add_dast_pre_scan_verifications_project_id_fk.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddDastPreScanVerificationsProjectIdFk < Gitlab::Database::Migration[2.2]
+ milestone '17.1'
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :dast_pre_scan_verifications, :projects, column: :project_id, on_delete: :cascade
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :dast_pre_scan_verifications, column: :project_id
+ end
+ end
+end
diff --git a/db/post_migrate/20240603121641_add_dast_pre_scan_verifications_project_id_trigger.rb b/db/post_migrate/20240603121641_add_dast_pre_scan_verifications_project_id_trigger.rb
new file mode 100644
index 00000000000..62dda50b68c
--- /dev/null
+++ b/db/post_migrate/20240603121641_add_dast_pre_scan_verifications_project_id_trigger.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class AddDastPreScanVerificationsProjectIdTrigger < Gitlab::Database::Migration[2.2]
+ milestone '17.1'
+
+ def up
+ install_sharding_key_assignment_trigger(
+ table: :dast_pre_scan_verifications,
+ sharding_key: :project_id,
+ parent_table: :dast_profiles,
+ parent_sharding_key: :project_id,
+ foreign_key: :dast_profile_id
+ )
+ end
+
+ def down
+ remove_sharding_key_assignment_trigger(
+ table: :dast_pre_scan_verifications,
+ sharding_key: :project_id,
+ parent_table: :dast_profiles,
+ parent_sharding_key: :project_id,
+ foreign_key: :dast_profile_id
+ )
+ end
+end
diff --git a/db/post_migrate/20240603121642_queue_backfill_dast_pre_scan_verifications_project_id.rb b/db/post_migrate/20240603121642_queue_backfill_dast_pre_scan_verifications_project_id.rb
new file mode 100644
index 00000000000..bd70313f473
--- /dev/null
+++ b/db/post_migrate/20240603121642_queue_backfill_dast_pre_scan_verifications_project_id.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+class QueueBackfillDastPreScanVerificationsProjectId < Gitlab::Database::Migration[2.2]
+ milestone '17.1'
+ restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
+
+ MIGRATION = "BackfillDastPreScanVerificationsProjectId"
+ DELAY_INTERVAL = 2.minutes
+ BATCH_SIZE = 1000
+ SUB_BATCH_SIZE = 100
+
+ def up
+ queue_batched_background_migration(
+ MIGRATION,
+ :dast_pre_scan_verifications,
+ :id,
+ :project_id,
+ :dast_profiles,
+ :project_id,
+ :dast_profile_id,
+ job_interval: DELAY_INTERVAL,
+ batch_size: BATCH_SIZE,
+ sub_batch_size: SUB_BATCH_SIZE
+ )
+ end
+
+ def down
+ delete_batched_background_migration(
+ MIGRATION,
+ :dast_pre_scan_verifications,
+ :id,
+ [
+ :project_id,
+ :dast_profiles,
+ :project_id,
+ :dast_profile_id
+ ]
+ )
+ end
+end
diff --git a/db/schema_migrations/20240603121638 b/db/schema_migrations/20240603121638
new file mode 100644
index 00000000000..e6b9514a982
--- /dev/null
+++ b/db/schema_migrations/20240603121638
@@ -0,0 +1 @@
+2e47913d93f71ab057ba65fe012320959140e2fcef1e73f15e5927298ee19911
\ No newline at end of file
diff --git a/db/schema_migrations/20240603121639 b/db/schema_migrations/20240603121639
new file mode 100644
index 00000000000..e0906c1237f
--- /dev/null
+++ b/db/schema_migrations/20240603121639
@@ -0,0 +1 @@
+87f4bc2809d2259e70fe3b09da62faeac67aaf6440e06fea3d392791a165e1f3
\ No newline at end of file
diff --git a/db/schema_migrations/20240603121640 b/db/schema_migrations/20240603121640
new file mode 100644
index 00000000000..6b1e6732f23
--- /dev/null
+++ b/db/schema_migrations/20240603121640
@@ -0,0 +1 @@
+c6e3a11fe9779674a739f36f2f7c40d0707b7d59cdae2f4cdc71826b5de4389a
\ No newline at end of file
diff --git a/db/schema_migrations/20240603121641 b/db/schema_migrations/20240603121641
new file mode 100644
index 00000000000..925f56ec588
--- /dev/null
+++ b/db/schema_migrations/20240603121641
@@ -0,0 +1 @@
+45f9e4bbf28e5f47d0af5700760756c478bf20f6ee1ee04564b1699f237651a9
\ No newline at end of file
diff --git a/db/schema_migrations/20240603121642 b/db/schema_migrations/20240603121642
new file mode 100644
index 00000000000..f39b1c46bc6
--- /dev/null
+++ b/db/schema_migrations/20240603121642
@@ -0,0 +1 @@
+5ff679739fbce0653dc0aa73d369874f2386fd04b706bee152c07717db08695f
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 21bc2b0e60b..455a7fe7da8 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -1185,6 +1185,22 @@ RETURN NEW;
END
$$;
+CREATE FUNCTION trigger_c5eec113ea76() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$
+BEGIN
+IF NEW."project_id" IS NULL THEN
+ SELECT "project_id"
+ INTO NEW."project_id"
+ FROM "dast_profiles"
+ WHERE "dast_profiles"."id" = NEW."dast_profile_id";
+END IF;
+
+RETURN NEW;
+
+END
+$$;
+
CREATE FUNCTION trigger_c8bc8646bce9() RETURNS trigger
LANGUAGE plpgsql
AS $$
@@ -8371,7 +8387,8 @@ CREATE TABLE dast_pre_scan_verifications (
ci_pipeline_id bigint,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
- status smallint DEFAULT 0 NOT NULL
+ status smallint DEFAULT 0 NOT NULL,
+ project_id bigint
);
CREATE SEQUENCE dast_pre_scan_verifications_id_seq
@@ -25940,6 +25957,8 @@ CREATE UNIQUE INDEX index_dast_pre_scan_verifications_on_ci_pipeline_id ON dast_
CREATE INDEX index_dast_pre_scan_verifications_on_dast_profile_id ON dast_pre_scan_verifications USING btree (dast_profile_id);
+CREATE INDEX index_dast_pre_scan_verifications_on_project_id ON dast_pre_scan_verifications USING btree (project_id);
+
CREATE INDEX index_dast_profile_schedules_active_next_run_at ON dast_profile_schedules USING btree (active, next_run_at);
CREATE UNIQUE INDEX index_dast_profile_schedules_on_dast_profile_id ON dast_profile_schedules USING btree (dast_profile_id);
@@ -30650,6 +30669,8 @@ CREATE TRIGGER trigger_b4520c29ea74 BEFORE INSERT OR UPDATE ON approval_merge_re
CREATE TRIGGER trigger_c17a166692a2 BEFORE INSERT OR UPDATE ON audit_events_streaming_headers FOR EACH ROW EXECUTE FUNCTION trigger_c17a166692a2();
+CREATE TRIGGER trigger_c5eec113ea76 BEFORE INSERT OR UPDATE ON dast_pre_scan_verifications FOR EACH ROW EXECUTE FUNCTION trigger_c5eec113ea76();
+
CREATE TRIGGER trigger_c8bc8646bce9 BEFORE INSERT OR UPDATE ON vulnerability_state_transitions FOR EACH ROW EXECUTE FUNCTION trigger_c8bc8646bce9();
CREATE TRIGGER trigger_c9090feed334 BEFORE INSERT OR UPDATE ON boards_epic_lists FOR EACH ROW EXECUTE FUNCTION trigger_c9090feed334();
@@ -31752,6 +31773,9 @@ ALTER TABLE ONLY project_mirror_data
ALTER TABLE ONLY environments
ADD CONSTRAINT fk_d1c8c1da6a FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY dast_pre_scan_verifications
+ ADD CONSTRAINT fk_d23ad33d6e FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
ALTER TABLE p_ci_builds
ADD CONSTRAINT fk_d3130c9a7f FOREIGN KEY (commit_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
diff --git a/doc/administration/postgresql/multiple_databases.md b/doc/administration/postgresql/multiple_databases.md
index 4cd0aa262d7..55883ab36cd 100644
--- a/doc/administration/postgresql/multiple_databases.md
+++ b/doc/administration/postgresql/multiple_databases.md
@@ -41,6 +41,7 @@ databases. Some examples:
- Once data is migrated to the `ci` database, you cannot migrate it back.
- Significant downtime is expected for larger installations (database sizes of more 100 GB).
+- Running two databases [is not yet supported with Geo](https://gitlab.com/groups/gitlab-org/-/epics/8631).
## Migrate existing installations using a script
diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md
index 176b90075e1..24435fdfe94 100644
--- a/doc/update/deprecations.md
+++ b/doc/update/deprecations.md
@@ -71,6 +71,27 @@ This change provides additional scalability for the largest of GitLab instances,
This change applies to all installation methods: Omnibus GitLab, GitLab Helm chart, GitLab Operator, GitLab Docker images, and installation from source.
Before upgrading to GitLab 19.0, please ensure you have [migrated](https://docs.gitlab.com/ee/administration/postgresql/multiple_databases.html) to two databases.
+
+
+
+
+### Single database connection is deprecated
+
+
+- Announced in GitLab 15.9
+- Removal in GitLab 19.0 ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
+- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/387898).
+
+
+Previously, [GitLab's database](https://docs.gitlab.com/omnibus/settings/database.html)
+configuration had a single `main:` section. This is being deprecated. The new
+configuration has both a `main:` and a `ci:` section.
+
+This deprecation affects users compiling GitLab from source, who will need
+to [add the `ci:` section](https://docs.gitlab.com/ee/install/installation.html#configure-gitlab-db-settings).
+Omnibus, the Helm chart, and Operator will handle this configuration
+automatically from GitLab 16.0 onwards.
+
@@ -501,28 +522,6 @@ For updates and details about this deprecation, follow [this epic](https://gitla
-### Single database connection is deprecated
-
-
-- Announced in GitLab 15.9
-- End of Support in GitLab 17.0
-- Removal in GitLab 18.0 ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
-- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/387898).
-
-
-Previously, [GitLab's database](https://docs.gitlab.com/omnibus/settings/database.html)
-configuration had a single `main:` section. This is being deprecated. The new
-configuration has both a `main:` and a `ci:` section.
-
-This deprecation affects users compiling GitLab from source, who will need
-to [add the `ci:` section](https://docs.gitlab.com/ee/install/installation.html#configure-gitlab-db-settings).
-Omnibus, the Helm chart, and Operator will handle this configuration
-automatically from GitLab 16.0 onwards.
-
-
-
-
-
### Slack notifications integration
diff --git a/doc/update/versions/gitlab_16_changes.md b/doc/update/versions/gitlab_16_changes.md
index aa82b715171..0643af70c47 100644
--- a/doc/update/versions/gitlab_16_changes.md
+++ b/doc/update/versions/gitlab_16_changes.md
@@ -25,10 +25,7 @@ For more information about upgrading GitLab Helm Chart, see [the release notes f
Perform the [workaround](#undefined-column-error-upgrading-to-162-or-later) before upgrading to 16.x.
- Starting with 16.0, GitLab self-managed installations now have two database connections by default, instead of one. This change doubles the number of PostgreSQL connections. It makes self-managed versions of GitLab behave similarly to GitLab.com, and is a step toward enabling a separate database for CI features for self-managed versions of GitLab. Before upgrading to 16.0, determine if you need to [increase max connections for PostgreSQL](https://docs.gitlab.com/omnibus/settings/database.html#configuring-multiple-database-connections).
- This change applies to installation methods with Linux packages (Omnibus), GitLab Helm chart, GitLab Operator, GitLab Docker images, and self-compiled installations.
- - The second database connection can be disabled:
- - [Linux package and Docker installations](https://docs.gitlab.com/omnibus/settings/database.html#configuring-multiple-database-connections).
- - [Helm chart and GitLab Operator installations](https://docs.gitlab.com/charts/charts/globals.html#configure-multiple-database-connections).
- - [Self-compiled installations](../../install/installation.md#configure-gitlab-db-settings).
+ - [The second database connection can be disabled](#disable-the-second-database-connection).
- Most installations can skip 16.0, 16.1, and 16.2, as the first required stop on the upgrade path is 16.3.
In all cases, you should review the notes for those intermediate versions.
@@ -1575,6 +1572,53 @@ praefect['configuration'] = {
}
```
+### Disable the second database connection
+
+In GitLab 16.0, GitLab defaults to using two database connections that point to the same PostgreSQL database.
+
+PostgreSQL might need to be configured with a larger value for `max_connections`.
+[There is a Rake task for checking if this is necessary](https://docs.gitlab.com/omnibus/settings/database.html#configuring-multiple-database-connections).
+
+If you have PgBouncer deployed:
+
+- The frontend pools (including file handle limits and `max_client_conn`) on your PgBouncer servers [might need to be larger](../../administration/postgresql/pgbouncer.md#fine-tuning).
+- PgBouncer is single threaded. The extra connections might fully saturate a single PgBouncer daemon.
+ [We recommend running three load-balanced PgBouncer servers](../../administration/reference_architectures/5k_users.md#configure-pgbouncer) for all
+ scaled GitLab deployments, in part to address this issue.
+
+Follow the instructions for your installation type to switch back to a single database connection:
+
+::Tabs
+
+:::TabTitle Linux package and Docker
+
+1. Add this setting to `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['databases']['ci']['enable'] = false
+ ```
+
+1. Run `gitlab-ctl reconfigure`.
+
+In a multi-node environment, this setting should be updated on all Rails and Sidekiq nodes.
+
+:::TabTitle Helm chart (Kubernetes)
+
+Set the `ci.enabled` key to `false`:
+
+```yaml
+global:
+ psql:
+ ci:
+ enabled: false
+```
+
+:::TabTitle Self-compiled (source)
+
+Remove the `ci:` section from `config/database.yml`.
+
+::EndTabs
+
## Long-running user type data change
GitLab 16.0 is a required stop for large GitLab instances with a lot of records in the `users` table.
diff --git a/doc/user/project/wiki/index.md b/doc/user/project/wiki/index.md
index e9f09ecba90..8100d4c9cec 100644
--- a/doc/user/project/wiki/index.md
+++ b/doc/user/project/wiki/index.md
@@ -142,7 +142,7 @@ You need at least the Developer role to edit a wiki page:
1. Select **Plan > Wiki**.
1. Go to the page you want to edit, and either:
- Use the
e wiki [keyboard shortcut](../../shortcuts.md#wiki-pages).
- - Select the edit icon (**{pencil}**).
+ - Select **Edit**.
1. Edit the content.
1. Select **Save changes**.
@@ -162,11 +162,13 @@ Prerequisites:
1. On the left sidebar, select **Search or go to** and find your project or group.
1. Select **Plan > Wiki**.
1. Go to the page you want to delete.
-1. Select the edit icon (**{pencil}**).
+1. Select **Edit**.
1. Select **Delete page**.
1. Confirm the deletion.
-## Move a wiki page
+## Move or rename a wiki page
+
+> - [Support for redirecting pages on move or rename](https://gitlab.com/gitlab-org/gitlab/-/issues/257892) added in GitLab 17.1 [with a flag](../../../administration/feature_flags.md) named `wiki_redirection`. Enabled by default.
Prerequisites:
@@ -174,13 +176,18 @@ Prerequisites:
1. On the left sidebar, select **Search or go to** and find your project or group.
1. Select **Plan > Wiki**.
-1. Go to the page you want to move.
-1. Select the edit icon (**{pencil}**).
-1. Add the new path to the **Title** field. For example, if you have a wiki page
- called `about` under `company` and you want to move it to the wiki's root,
- change the **Title** from `about` to `/about`.
+1. Go to the page you want to move or rename.
+1. Select **Edit**.
+1. To move the page, add the new path to the **Title** field. For example,
+ if you have a wiki page called `About` under `Company` and you want to
+ move it to the wiki's root, change the **Title** from `About` to `/About`.
+1. To rename the page, change the **Title**.
1. Select **Save changes**.
+In GitLab 17.1 and later, when you move or rename a page, a redirect is
+automatically set up from the old page to the new page. A list of redirects
+is stored in the `.gitlab/redirects.yml` file in the Wiki repository.
+
## Export a wiki page
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/414691) in GitLab 16.3 [with a flag](../../../administration/feature_flags.md) named `print_wiki`. Disabled by default.
diff --git a/gems/gem-pg.gitlab-ci.yml b/gems/gem-pg.gitlab-ci.yml
index 5ae5a8b768d..f02f4439058 100644
--- a/gems/gem-pg.gitlab-ci.yml
+++ b/gems/gem-pg.gitlab-ci.yml
@@ -27,11 +27,12 @@ variables:
GIT_STRATEGY: "clone"
GIT_SUBMODULE_STRATEGY: "none"
GET_SOURCES_ATTEMPTS: "3"
- RUBY_VERSION_DEFAULT: "3.1.5"
- RUBY_VERSION_NEXT: "3.2.4"
# Default Ruby version for jobs that don't use .ruby_matrix
RUBY_VERSION: "${RUBY_VERSION_DEFAULT}"
+include:
+ - local: .gitlab/ci/version.yml
+
default:
tags:
- gitlab-org
diff --git a/gems/gem.gitlab-ci.yml b/gems/gem.gitlab-ci.yml
index 284d87e4246..d2791c62c2c 100644
--- a/gems/gem.gitlab-ci.yml
+++ b/gems/gem.gitlab-ci.yml
@@ -27,11 +27,12 @@ variables:
GIT_STRATEGY: "clone"
GIT_SUBMODULE_STRATEGY: "none"
GET_SOURCES_ATTEMPTS: "3"
- RUBY_VERSION_DEFAULT: "3.1.5"
- RUBY_VERSION_NEXT: "3.2.4"
# Default Ruby version for jobs that don't use .ruby_matrix
RUBY_VERSION: "${RUBY_VERSION_DEFAULT}"
+include:
+ - local: .gitlab/ci/version.yml
+
default:
tags:
- gitlab-org
diff --git a/lib/gitlab/background_migration/backfill_dast_pre_scan_verifications_project_id.rb b/lib/gitlab/background_migration/backfill_dast_pre_scan_verifications_project_id.rb
new file mode 100644
index 00000000000..2d0148a9d3c
--- /dev/null
+++ b/lib/gitlab/background_migration/backfill_dast_pre_scan_verifications_project_id.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ class BackfillDastPreScanVerificationsProjectId < BackfillDesiredShardingKeyJob
+ operation_name :backfill_dast_pre_scan_verifications_project_id
+ feature_category :dynamic_application_security_testing
+ end
+ end
+end
diff --git a/lib/gitlab/github_import/user_finder.rb b/lib/gitlab/github_import/user_finder.rb
index e0bda5fca75..204851fdeb0 100644
--- a/lib/gitlab/github_import/user_finder.rb
+++ b/lib/gitlab/github_import/user_finder.rb
@@ -130,7 +130,7 @@ module Gitlab
email = read_email_from_cache(username)
if email.blank? && !email_fetched_for_project?(username)
- feature_flag_in_lock(lease_key(username), sleep_sec: 0.2.seconds, retries: 30) do |retried|
+ in_lock(lease_key(username), sleep_sec: 0.2.seconds, retries: 30) do |retried|
# when retried, check the cache again as the other process that had the lease may have fetched the email
if retried
email = read_email_from_cache(username)
@@ -306,14 +306,6 @@ module Gitlab
message: message
)
end
-
- def feature_flag_in_lock(lease_key, sleep_sec:, retries:)
- return yield(false) if Feature.disabled?(:github_import_lock_user_finder, project.creator)
-
- in_lock(lease_key, sleep_sec: sleep_sec, retries: retries) do |retried|
- yield(retried)
- end
- end
end
end
end
diff --git a/scripts/frontend/compare_css_util_classes.mjs b/scripts/frontend/compare_css_util_classes.mjs
index 9dfb568f0d7..d409572c796 100755
--- a/scripts/frontend/compare_css_util_classes.mjs
+++ b/scripts/frontend/compare_css_util_classes.mjs
@@ -11,7 +11,7 @@ import {
darkModeTokenToHex,
mismatchAllowList,
} from './lib/tailwind_migration.mjs';
-import { convertUtilsToCSSInJS } from './tailwind_all_the_way.mjs';
+import { convertUtilsToCSSInJS, toMinimalUtilities } from './tailwind_all_the_way.mjs';
function darkModeResolver(str) {
return str.replace(
@@ -26,10 +26,10 @@ function darkModeResolver(str) {
);
}
-function compareApplicationUtilsToTailwind(appUtils, tailWind, colorResolver) {
+function compareApplicationUtilsToTailwind(appUtils, tailwindCSS, colorResolver) {
let fail = 0;
- const tailwind = extractRules(tailWind);
+ const tailwind = extractRules(tailwindCSS);
Object.keys(appUtils).forEach((selector) => {
if (mismatchAllowList.includes(selector)) {
@@ -50,9 +50,33 @@ function compareApplicationUtilsToTailwind(appUtils, tailWind, colorResolver) {
});
if (fail) {
- console.log(`${fail} selectors failed`);
- process.exitCode = 1;
+ console.log(`\t${fail} selectors failed`);
+ } else {
+ console.log('\tAll good');
}
+
+ return fail;
+}
+
+function ensureNoLegacyUtilIsUsedWithATailwindModifier(minimalUtils) {
+ let fail = 0;
+ for (const [key, value] of Object.entries(minimalUtils)) {
+ if (key.startsWith('.\\!')) {
+ console.warn('Using legacy util with important modifier. This is not supported.');
+ console.warn(`Please migrate ${key} to a proper tailwind util.`);
+ fail += 1;
+ }
+ if (key.endsWith('\\')) {
+ console.warn(`Using legacy util with ${key} modifier. This is not supported.`);
+ console.warn(`Please migrate the following classes to a proper tailwind util:`);
+ console.warn(JSON.stringify(value, null, 2).replace(/^/gm, ' '.repeat(4)));
+ fail += 1;
+ }
+ }
+ if (fail) {
+ console.log(`\t${fail} legacy utils with modifiers found`);
+ }
+ return fail;
}
console.log('# Converting legacy styles to CSS-in-JS definitions');
@@ -64,6 +88,8 @@ if (stats.hardcodedColors || stats.potentialMismatches) {
process.exitCode = 1;
}
+let failures = 0;
+
console.log('# Comparing tailwind to legacy utils');
const applicationUtilsLight = extractRules(
@@ -77,6 +103,20 @@ const applicationUtilsDark = extractRules(
const tailwind = loadCSSFromFile('app/assets/builds/tailwind.css');
console.log('## Comparing tailwind light mode');
-compareApplicationUtilsToTailwind(applicationUtilsLight, tailwind);
+failures += compareApplicationUtilsToTailwind(applicationUtilsLight, tailwind);
console.log('## Comparing tailwind dark mode');
-compareApplicationUtilsToTailwind(applicationUtilsDark, tailwind, darkModeResolver);
+failures += compareApplicationUtilsToTailwind(applicationUtilsDark, tailwind, darkModeResolver);
+
+console.log('# Checking whether legacy GitLab utility classes are used with tailwind modifiers');
+
+console.log('## Reducing utility definitions to minimally used');
+const { rules } = await toMinimalUtilities();
+
+console.log('## Running checks');
+failures += ensureNoLegacyUtilIsUsedWithATailwindModifier(rules);
+
+if (failures) {
+ process.exitCode = 1;
+} else {
+ console.log('# All good – Happiness. May the tailwind boost your journey');
+}
diff --git a/scripts/frontend/tailwind_all_the_way.mjs b/scripts/frontend/tailwind_all_the_way.mjs
index 3b692bb1759..2d6df177b5f 100755
--- a/scripts/frontend/tailwind_all_the_way.mjs
+++ b/scripts/frontend/tailwind_all_the_way.mjs
@@ -136,7 +136,7 @@ const hardCodedColors = ${JSON.stringify(hardcodedColors, null, 2)};
/**
* Writes only the style definitions we actually need.
*/
-async function toMinimalUtilities() {
+export async function toMinimalUtilities() {
// We re-import the config with a `?minimal` query in order to cache-bust
// the previously loaded config, which doesn't have the latest css_in_js
const { default: tailwindConfig } = await import('../../config/tailwind.config.js?minimal');
@@ -166,7 +166,7 @@ async function toMinimalUtilities() {
*/
module.exports = ${JSON.stringify(rules)}`);
- return { minimalUtils };
+ return { minimalUtils, rules };
}
/**
diff --git a/spec/lib/gitlab/background_migration/backfill_dast_pre_scan_verifications_project_id_spec.rb b/spec/lib/gitlab/background_migration/backfill_dast_pre_scan_verifications_project_id_spec.rb
new file mode 100644
index 00000000000..ab50ca0f164
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_dast_pre_scan_verifications_project_id_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillDastPreScanVerificationsProjectId,
+ feature_category: :dynamic_application_security_testing,
+ schema: 20240603121638 do
+ include_examples 'desired sharding key backfill job' do
+ let(:batch_table) { :dast_pre_scan_verifications }
+ let(:backfill_column) { :project_id }
+ let(:backfill_via_table) { :dast_profiles }
+ let(:backfill_via_column) { :project_id }
+ let(:backfill_via_foreign_key) { :dast_profile_id }
+ end
+end
diff --git a/spec/lib/gitlab/github_import/user_finder_spec.rb b/spec/lib/gitlab/github_import/user_finder_spec.rb
index a5e8d428128..1cd1e76c5c2 100644
--- a/spec/lib/gitlab/github_import/user_finder_spec.rb
+++ b/spec/lib/gitlab/github_import/user_finder_spec.rb
@@ -313,19 +313,6 @@ RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_shared_stat
email_for_github_username
end
- context 'when github_import_lock_user_finder feature flag is disabled' do
- before do
- stub_feature_flags(github_import_lock_user_finder: false)
- end
-
- it 'does not lock the finder' do
- expect(finder).not_to receive(:in_lock)
- expect(client).to receive(:user)
-
- email_for_github_username
- end
- end
-
context 'if the response contains an email' do
before do
allow(client).to receive(:user).and_return({ email: email })
diff --git a/spec/migrations/20240603121642_queue_backfill_dast_pre_scan_verifications_project_id_spec.rb b/spec/migrations/20240603121642_queue_backfill_dast_pre_scan_verifications_project_id_spec.rb
new file mode 100644
index 00000000000..6b33cf6ed1d
--- /dev/null
+++ b/spec/migrations/20240603121642_queue_backfill_dast_pre_scan_verifications_project_id_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueBackfillDastPreScanVerificationsProjectId, feature_category: :dynamic_application_security_testing do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :dast_pre_scan_verifications,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE,
+ gitlab_schema: :gitlab_main_cell,
+ job_arguments: [
+ :project_id,
+ :dast_profiles,
+ :project_id,
+ :dast_profile_id
+ ]
+ )
+ }
+ end
+ end
+end
diff --git a/vendor/gems/attr_encrypted/.gitlab-ci.yml b/vendor/gems/attr_encrypted/.gitlab-ci.yml
index 2583f281fb8..b30e9ad1c62 100644
--- a/vendor/gems/attr_encrypted/.gitlab-ci.yml
+++ b/vendor/gems/attr_encrypted/.gitlab-ci.yml
@@ -9,4 +9,4 @@ rspec:
- bundle exec rake test
parallel:
matrix:
- - RUBY_VERSION: ["3.1.5", "3.2.4"]
+ - RUBY_VERSION: ["${RUBY_VERSION_DEFAULT}", "${RUBY_VERSION_NEXT}"]
diff --git a/vendor/gems/diff_match_patch/.gitlab-ci.yml b/vendor/gems/diff_match_patch/.gitlab-ci.yml
index f00418ca118..6765a52f954 100644
--- a/vendor/gems/diff_match_patch/.gitlab-ci.yml
+++ b/vendor/gems/diff_match_patch/.gitlab-ci.yml
@@ -9,4 +9,4 @@ rspec:
- rake test
parallel:
matrix:
- - RUBY_VERSION: ["3.1.5", "3.2.4"]
+ - RUBY_VERSION: ["${RUBY_VERSION_DEFAULT}", "${RUBY_VERSION_NEXT}"]
diff --git a/vendor/gems/sidekiq-7.1.6/.gitlab-ci.yml b/vendor/gems/sidekiq-7.1.6/.gitlab-ci.yml
index 7ac772fde82..1bb1431d600 100644
--- a/vendor/gems/sidekiq-7.1.6/.gitlab-ci.yml
+++ b/vendor/gems/sidekiq-7.1.6/.gitlab-ci.yml
@@ -11,7 +11,7 @@ rspec:
- .with_redis
parallel:
matrix:
- - RUBY_VERSION: ["3.1.5", "3.2.4"]
+ - RUBY_VERSION: ["${RUBY_VERSION_DEFAULT}", "${RUBY_VERSION_NEXT}"]
REDIS_VERSION: ["6.0", "6.2", "7.0"]
.with_redis:
diff --git a/vendor/gems/sidekiq-reliable-fetch/.gitlab-ci.yml b/vendor/gems/sidekiq-reliable-fetch/.gitlab-ci.yml
index 30786ca8eef..c0dc78bf550 100644
--- a/vendor/gems/sidekiq-reliable-fetch/.gitlab-ci.yml
+++ b/vendor/gems/sidekiq-reliable-fetch/.gitlab-ci.yml
@@ -9,7 +9,7 @@ rspec:
- .with_redis
parallel:
matrix:
- - RUBY_VERSION: ["3.1.5"] # 3.2 isn't supported yet
+ - RUBY_VERSION: ["${RUBY_VERSION_DEFAULT}"] # 3.2 isn't supported yet
.with_redis:
services:
diff --git a/workhorse/_support/lint_last_known_acceptable_go1.21.txt b/workhorse/_support/lint_last_known_acceptable_go1.21.txt
index 8397dde183c..9961b4e285e 100644
--- a/workhorse/_support/lint_last_known_acceptable_go1.21.txt
+++ b/workhorse/_support/lint_last_known_acceptable_go1.21.txt
@@ -9,8 +9,8 @@ cmd/gitlab-workhorse/authorization_test.go:114:3: go-require: do not use require
cmd/gitlab-workhorse/authorization_test.go:115:3: go-require: do not use require in http handlers (testifylint)
cmd/gitlab-workhorse/authorization_test.go:116:3: go-require: do not use require in http handlers (testifylint)
cmd/gitlab-workhorse/authorization_test.go:120:3: go-require: do not use require in http handlers (testifylint)
-cmd/gitlab-workhorse/config_test.go:189: cmd/gitlab-workhorse/config_test.go:189: Line contains TODO/BUG/FIXME/NOTE/OPTIMIZE/HACK: "TODO this is meant to be 50*time.Second ..." (godox)
-cmd/gitlab-workhorse/config_test.go:331:16: unused-parameter: parameter 't' seems to be unused, consider removing or renaming it as _ (revive)
+cmd/gitlab-workhorse/config_test.go:191: cmd/gitlab-workhorse/config_test.go:191: Line contains TODO/BUG/FIXME/NOTE/OPTIMIZE/HACK: "TODO this is meant to be 50*time.Second ..." (godox)
+cmd/gitlab-workhorse/config_test.go:333:16: unused-parameter: parameter 't' seems to be unused, consider removing or renaming it as _ (revive)
cmd/gitlab-workhorse/jobs_test.go:37:29: response body must be closed (bodyclose)
cmd/gitlab-workhorse/jobs_test.go:42:29: response body must be closed (bodyclose)
cmd/gitlab-workhorse/listener.go:34:16: G402: TLS MinVersion too low. (gosec)
@@ -164,21 +164,21 @@ internal/config/config.go:84:6: exported: exported type GoCloudConfig should hav
internal/config/config.go:88:6: exported: exported type AzureCredentials should have comment or be unexported (revive)
internal/config/config.go:93:6: exported: exported type GoogleCredentials should have comment or be unexported (revive)
internal/config/config.go:99:6: exported: exported type RedisConfig should have comment or be unexported (revive)
-internal/config/config.go:110:6: exported: exported type ImageResizerConfig should have comment or be unexported (revive)
-internal/config/config.go:116:6: exported: exported type MetadataConfig should have comment or be unexported (revive)
-internal/config/config.go:120:6: exported: exported type TLSConfig should have comment or be unexported (revive)
-internal/config/config.go:127:6: exported: exported type ListenerConfig should have comment or be unexported (revive)
-internal/config/config.go:130:2: var-naming: struct field Tls should be TLS (revive)
-internal/config/config.go:133:6: exported: exported type Config should have comment or be unexported (revive)
-internal/config/config.go:161:5: exported: exported var DefaultImageResizerConfig should have comment or be unexported (revive)
-internal/config/config.go:166:5: exported: exported var DefaultMetadataConfig should have comment or be unexported (revive)
-internal/config/config.go:170:1: exported: exported function NewDefaultConfig should have comment or be unexported (revive)
-internal/config/config.go:177:1: exported: exported function LoadConfigFromFile should have comment or be unexported (revive)
-internal/config/config.go:191:1: exported: exported function LoadConfig should have comment or be unexported (revive)
-internal/config/config.go:200:18: G204: Subprocess launched with variable (gosec)
-internal/config/config.go:218:1: exported: exported method Config.RegisterGoCloudURLOpeners should have comment or be unexported (revive)
-internal/config/config.go:241:70: (*AzureCredentials).getURLOpener - result 1 (error) is always nil (unparam)
-internal/config/config.go:284:8: G101: Potential hardcoded credentials (gosec)
+internal/config/config.go:111:6: exported: exported type ImageResizerConfig should have comment or be unexported (revive)
+internal/config/config.go:117:6: exported: exported type MetadataConfig should have comment or be unexported (revive)
+internal/config/config.go:121:6: exported: exported type TLSConfig should have comment or be unexported (revive)
+internal/config/config.go:128:6: exported: exported type ListenerConfig should have comment or be unexported (revive)
+internal/config/config.go:131:2: var-naming: struct field Tls should be TLS (revive)
+internal/config/config.go:134:6: exported: exported type Config should have comment or be unexported (revive)
+internal/config/config.go:162:5: exported: exported var DefaultImageResizerConfig should have comment or be unexported (revive)
+internal/config/config.go:167:5: exported: exported var DefaultMetadataConfig should have comment or be unexported (revive)
+internal/config/config.go:171:1: exported: exported function NewDefaultConfig should have comment or be unexported (revive)
+internal/config/config.go:178:1: exported: exported function LoadConfigFromFile should have comment or be unexported (revive)
+internal/config/config.go:192:1: exported: exported function LoadConfig should have comment or be unexported (revive)
+internal/config/config.go:201:18: G204: Subprocess launched with variable (gosec)
+internal/config/config.go:219:1: exported: exported method Config.RegisterGoCloudURLOpeners should have comment or be unexported (revive)
+internal/config/config.go:242:70: (*AzureCredentials).getURLOpener - result 1 (error) is always nil (unparam)
+internal/config/config.go:285:8: G101: Potential hardcoded credentials (gosec)
internal/dependencyproxy/dependencyproxy.go:77: Function 'Inject' is too long (70 > 60) (funlen)
internal/dependencyproxy/dependencyproxy.go:115:32: `cancelled` is a misspelling of `canceled` (misspell)
internal/dependencyproxy/dependencyproxy_test.go:101:91: unused-parameter: parameter 'r' seems to be unused, consider removing or renaming it as _ (revive)
@@ -322,7 +322,7 @@ internal/redis/redis.go:1:1: ST1000: at least one file in a package should have
internal/redis/redis.go:16:2: blank-imports: a blank import should be only in a main or test package, or have a comment justifying it (revive)
internal/redis/redis.go:21:24: var-declaration: should omit type error from declaration of var errSentinelMasterAddr; it will be inferred from the right-hand side (revive)
internal/redis/redis.go:23:2: exported: exported var TotalConnections should have comment or be unexported (revive)
-internal/redis/redis.go:95:10: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic)
+internal/redis/redis.go:102:10: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic)
internal/redis/redis_test.go:18:2: error-nil: use require.NoError (testifylint)
internal/redis/redis_test.go:23:3: error-nil: use require.NoError (testifylint)
internal/redis/redis_test.go:66:15: `initialise` is a misspelling of `initialize` (misspell)
diff --git a/workhorse/_support/lint_last_known_acceptable_go1.22.txt b/workhorse/_support/lint_last_known_acceptable_go1.22.txt
index 24386e6f25c..e92aabd02d5 100644
--- a/workhorse/_support/lint_last_known_acceptable_go1.22.txt
+++ b/workhorse/_support/lint_last_known_acceptable_go1.22.txt
@@ -9,8 +9,8 @@ cmd/gitlab-workhorse/authorization_test.go:114:3: go-require: do not use require
cmd/gitlab-workhorse/authorization_test.go:115:3: go-require: do not use require in http handlers (testifylint)
cmd/gitlab-workhorse/authorization_test.go:116:3: go-require: do not use require in http handlers (testifylint)
cmd/gitlab-workhorse/authorization_test.go:120:3: go-require: do not use require in http handlers (testifylint)
-cmd/gitlab-workhorse/config_test.go:189: cmd/gitlab-workhorse/config_test.go:189: Line contains TODO/BUG/FIXME/NOTE/OPTIMIZE/HACK: "TODO this is meant to be 50*time.Second ..." (godox)
-cmd/gitlab-workhorse/config_test.go:331:16: unused-parameter: parameter 't' seems to be unused, consider removing or renaming it as _ (revive)
+cmd/gitlab-workhorse/config_test.go:191: cmd/gitlab-workhorse/config_test.go:191: Line contains TODO/BUG/FIXME/NOTE/OPTIMIZE/HACK: "TODO this is meant to be 50*time.Second ..." (godox)
+cmd/gitlab-workhorse/config_test.go:333:16: unused-parameter: parameter 't' seems to be unused, consider removing or renaming it as _ (revive)
cmd/gitlab-workhorse/jobs_test.go:37:29: response body must be closed (bodyclose)
cmd/gitlab-workhorse/jobs_test.go:42:29: response body must be closed (bodyclose)
cmd/gitlab-workhorse/listener.go:34:16: G402: TLS MinVersion too low. (gosec)
@@ -164,21 +164,21 @@ internal/config/config.go:84:6: exported: exported type GoCloudConfig should hav
internal/config/config.go:88:6: exported: exported type AzureCredentials should have comment or be unexported (revive)
internal/config/config.go:93:6: exported: exported type GoogleCredentials should have comment or be unexported (revive)
internal/config/config.go:99:6: exported: exported type RedisConfig should have comment or be unexported (revive)
-internal/config/config.go:110:6: exported: exported type ImageResizerConfig should have comment or be unexported (revive)
-internal/config/config.go:116:6: exported: exported type MetadataConfig should have comment or be unexported (revive)
-internal/config/config.go:120:6: exported: exported type TLSConfig should have comment or be unexported (revive)
-internal/config/config.go:127:6: exported: exported type ListenerConfig should have comment or be unexported (revive)
-internal/config/config.go:130:2: var-naming: struct field Tls should be TLS (revive)
-internal/config/config.go:133:6: exported: exported type Config should have comment or be unexported (revive)
-internal/config/config.go:161:5: exported: exported var DefaultImageResizerConfig should have comment or be unexported (revive)
-internal/config/config.go:166:5: exported: exported var DefaultMetadataConfig should have comment or be unexported (revive)
-internal/config/config.go:170:1: exported: exported function NewDefaultConfig should have comment or be unexported (revive)
-internal/config/config.go:177:1: exported: exported function LoadConfigFromFile should have comment or be unexported (revive)
-internal/config/config.go:191:1: exported: exported function LoadConfig should have comment or be unexported (revive)
-internal/config/config.go:200:18: G204: Subprocess launched with variable (gosec)
-internal/config/config.go:218:1: exported: exported method Config.RegisterGoCloudURLOpeners should have comment or be unexported (revive)
-internal/config/config.go:241:70: (*AzureCredentials).getURLOpener - result 1 (error) is always nil (unparam)
-internal/config/config.go:284:8: G101: Potential hardcoded credentials (gosec)
+internal/config/config.go:111:6: exported: exported type ImageResizerConfig should have comment or be unexported (revive)
+internal/config/config.go:117:6: exported: exported type MetadataConfig should have comment or be unexported (revive)
+internal/config/config.go:121:6: exported: exported type TLSConfig should have comment or be unexported (revive)
+internal/config/config.go:128:6: exported: exported type ListenerConfig should have comment or be unexported (revive)
+internal/config/config.go:131:2: var-naming: struct field Tls should be TLS (revive)
+internal/config/config.go:134:6: exported: exported type Config should have comment or be unexported (revive)
+internal/config/config.go:162:5: exported: exported var DefaultImageResizerConfig should have comment or be unexported (revive)
+internal/config/config.go:167:5: exported: exported var DefaultMetadataConfig should have comment or be unexported (revive)
+internal/config/config.go:171:1: exported: exported function NewDefaultConfig should have comment or be unexported (revive)
+internal/config/config.go:178:1: exported: exported function LoadConfigFromFile should have comment or be unexported (revive)
+internal/config/config.go:192:1: exported: exported function LoadConfig should have comment or be unexported (revive)
+internal/config/config.go:201:18: G204: Subprocess launched with variable (gosec)
+internal/config/config.go:219:1: exported: exported method Config.RegisterGoCloudURLOpeners should have comment or be unexported (revive)
+internal/config/config.go:242:70: (*AzureCredentials).getURLOpener - result 1 (error) is always nil (unparam)
+internal/config/config.go:285:8: G101: Potential hardcoded credentials (gosec)
internal/dependencyproxy/dependencyproxy.go:77: Function 'Inject' is too long (70 > 60) (funlen)
internal/dependencyproxy/dependencyproxy.go:115:32: `cancelled` is a misspelling of `canceled` (misspell)
internal/dependencyproxy/dependencyproxy_test.go:101:91: unused-parameter: parameter 'r' seems to be unused, consider removing or renaming it as _ (revive)
@@ -322,7 +322,7 @@ internal/redis/redis.go:1:1: ST1000: at least one file in a package should have
internal/redis/redis.go:16:2: blank-imports: a blank import should be only in a main or test package, or have a comment justifying it (revive)
internal/redis/redis.go:21:24: var-declaration: should omit type error from declaration of var errSentinelMasterAddr; it will be inferred from the right-hand side (revive)
internal/redis/redis.go:23:2: exported: exported var TotalConnections should have comment or be unexported (revive)
-internal/redis/redis.go:95:10: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic)
+internal/redis/redis.go:102:10: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic)
internal/redis/redis_test.go:18:2: error-nil: use require.NoError (testifylint)
internal/redis/redis_test.go:23:3: error-nil: use require.NoError (testifylint)
internal/redis/redis_test.go:66:15: `initialise` is a misspelling of `initialize` (misspell)
diff --git a/workhorse/cmd/gitlab-workhorse/config_test.go b/workhorse/cmd/gitlab-workhorse/config_test.go
index ae35c22b019..1a117ecda62 100644
--- a/workhorse/cmd/gitlab-workhorse/config_test.go
+++ b/workhorse/cmd/gitlab-workhorse/config_test.go
@@ -38,7 +38,8 @@ trusted_cidrs_for_x_forwarded_for = ["127.0.0.1/8", "192.168.0.1/8"]
trusted_cidrs_for_propagation = ["10.0.0.1/8"]
[redis]
-password = "redis password"
+Password = "redis password"
+SentinelUsername = "sentinel-user"
SentinelPassword = "sentinel password"
[object_storage]
provider = "test provider"
@@ -74,6 +75,7 @@ key = "/path/to/private/key"
// fields in each section; that should happen in the tests of the
// internal/config package.
require.Equal(t, "redis password", cfg.Redis.Password)
+ require.Equal(t, "sentinel-user", cfg.Redis.SentinelUsername)
require.Equal(t, "sentinel password", cfg.Redis.SentinelPassword)
require.Equal(t, "test provider", cfg.ObjectStorageCredentials.Provider)
require.Equal(t, uint32(123), cfg.ImageResizerConfig.MaxScalerProcs, "image resizer max_scaler_procs")
diff --git a/workhorse/internal/config/config.go b/workhorse/internal/config/config.go
index b1975c8ee75..85b1e22306d 100644
--- a/workhorse/internal/config/config.go
+++ b/workhorse/internal/config/config.go
@@ -100,6 +100,7 @@ type RedisConfig struct {
URL TomlURL
Sentinel []TomlURL
SentinelMaster string
+ SentinelUsername string
SentinelPassword string
Password string
DB *int
diff --git a/workhorse/internal/redis/redis.go b/workhorse/internal/redis/redis.go
index 1fd30b05de5..df87ec9ce68 100644
--- a/workhorse/internal/redis/redis.go
+++ b/workhorse/internal/redis/redis.go
@@ -53,6 +53,13 @@ const (
defaultIdleTimeout = 3 * time.Minute
)
+// SentinelOptions contains grouped, related values
+type SentinelOptions struct {
+ SentinelUsername string
+ SentinelPassword string
+ Sentinels []string
+}
+
// createDialer references https://github.com/redis/go-redis/blob/b1103e3d436b6fe98813ecbbe1f99dc8d59b06c9/options.go#L214
// it intercepts the error and tracks it via a Prometheus counter
func createDialer(sentinels []string, tlsConfig *tls.Config) func(ctx context.Context, network, addr string) (net.Conn, error) {
@@ -172,12 +179,13 @@ func configureRedis(cfg *config.RedisConfig) (*redis.Client, error) {
}
func configureSentinel(cfg *config.RedisConfig) *redis.Client {
- sentinelPassword, sentinels := sentinelOptions(cfg)
+ options := sentinelOptions(cfg)
client := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: cfg.SentinelMaster,
- SentinelAddrs: sentinels,
+ SentinelAddrs: options.Sentinels,
Password: cfg.Password,
- SentinelPassword: sentinelPassword,
+ SentinelUsername: options.SentinelUsername,
+ SentinelPassword: options.SentinelPassword,
DB: getOrDefault(cfg.DB, 0),
PoolSize: getOrDefault(cfg.MaxActive, defaultMaxActive),
@@ -187,7 +195,7 @@ func configureSentinel(cfg *config.RedisConfig) *redis.Client {
ReadTimeout: defaultReadTimeout,
WriteTimeout: defaultWriteTimeout,
- Dialer: createDialer(sentinels, nil),
+ Dialer: createDialer(options.Sentinels, nil),
})
client.AddHook(sentinelInstrumentationHook{})
@@ -195,10 +203,13 @@ func configureSentinel(cfg *config.RedisConfig) *redis.Client {
return client
}
-// sentinelOptions extracts the sentinel password and addresses in
: format
+// sentinelOptions extracts the sentinel username and password from the URLs
+// and addresses in : format.
// the order of priority for the passwords is: SentinelPassword -> first password-in-url
-func sentinelOptions(cfg *config.RedisConfig) (string, []string) {
+// SentinelUsername will be the username associated with SentinelPassword.
+func sentinelOptions(cfg *config.RedisConfig) SentinelOptions {
sentinels := make([]string, len(cfg.Sentinel))
+ sentinelUsername := cfg.SentinelUsername
sentinelPassword := cfg.SentinelPassword
for i := range cfg.Sentinel {
@@ -208,10 +219,16 @@ func sentinelOptions(cfg *config.RedisConfig) (string, []string) {
if pw, exist := sentinelDetails.User.Password(); exist && len(sentinelPassword) == 0 {
// sets password using the first non-empty password
sentinelPassword = pw
+
+ // If a password is specified, a username is optional. Ensure that we use the
+ // username associated with the password.
+ if username := sentinelDetails.User.Username(); username != "" && sentinelUsername == "" {
+ sentinelUsername = username
+ }
}
}
- return sentinelPassword, sentinels
+ return SentinelOptions{sentinelUsername, sentinelPassword, sentinels}
}
func getOrDefault(ptr *int, val int) int {
diff --git a/workhorse/internal/redis/redis_test.go b/workhorse/internal/redis/redis_test.go
index cbceb7e6183..e0f34ebdbfe 100644
--- a/workhorse/internal/redis/redis_test.go
+++ b/workhorse/internal/redis/redis_test.go
@@ -112,8 +112,10 @@ func TestConnectToSentinel(t *testing.T) {
func TestSentinelOptions(t *testing.T) {
testCases := []struct {
description string
+ inputSentinelUsername string
inputSentinelPassword string
inputSentinel []string
+ username string
password string
sentinels []string
}{
@@ -142,6 +144,38 @@ func TestSentinelOptions(t *testing.T) {
inputSentinelPassword: "password1",
password: "password1",
},
+ {
+ description: "specific sentinel username defined",
+ inputSentinel: []string{"redis://localhost:26480"},
+ inputSentinelUsername: "username1",
+ inputSentinelPassword: "password1",
+ sentinels: []string{"localhost:26480"},
+ username: "username1",
+ password: "password1",
+ },
+ {
+ description: "specific sentinel username defined in url",
+ inputSentinel: []string{"redis://username2:password2@localhost:26480", "redis://username3:password3@localhost:26481"},
+ sentinels: []string{"localhost:26480", "localhost:26481"},
+ username: "username2",
+ password: "password2",
+ },
+ {
+ description: "usernames and passwords defined specifically and in url",
+ inputSentinel: []string{"tcp://someuser2:password2@localhost:26480", "tcp://someuser3:password3@localhost:26481"},
+ sentinels: []string{"localhost:26480", "localhost:26481"},
+ inputSentinelUsername: "someuser1",
+ inputSentinelPassword: "password1",
+ username: "someuser1",
+ password: "password1",
+ },
+ {
+ description: "username set for first sentinel",
+ inputSentinel: []string{"tcp://someuser2@localhost:26480", "tcp://someuser3:password3@localhost:26481"},
+ sentinels: []string{"localhost:26480", "localhost:26481"},
+ username: "someuser3",
+ password: "password3",
+ },
}
for _, tc := range testCases {
@@ -153,13 +187,15 @@ func TestSentinelOptions(t *testing.T) {
sentinelUrls[i] = config.TomlURL{URL: *parsedURL}
}
- outputPw, outputSentinels := sentinelOptions(&config.RedisConfig{
+ options := sentinelOptions(&config.RedisConfig{
Sentinel: sentinelUrls,
+ SentinelUsername: tc.inputSentinelUsername,
SentinelPassword: tc.inputSentinelPassword,
})
- require.Equal(t, tc.password, outputPw)
- require.Equal(t, tc.sentinels, outputSentinels)
+ require.Equal(t, tc.username, options.SentinelUsername)
+ require.Equal(t, tc.password, options.SentinelPassword)
+ require.Equal(t, tc.sentinels, options.Sentinels)
})
}
}