Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
d8ee0721db
commit
9b5bb10544
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -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"},
|
||||
|
|
|
|||
32
Gemfile.lock
32
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)
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
2e47913d93f71ab057ba65fe012320959140e2fcef1e73f15e5927298ee19911
|
||||
|
|
@ -0,0 +1 @@
|
|||
87f4bc2809d2259e70fe3b09da62faeac67aaf6440e06fea3d392791a165e1f3
|
||||
|
|
@ -0,0 +1 @@
|
|||
c6e3a11fe9779674a739f36f2f7c40d0707b7d59cdae2f4cdc71826b5de4389a
|
||||
|
|
@ -0,0 +1 @@
|
|||
45f9e4bbf28e5f47d0af5700760756c478bf20f6ee1ee04564b1699f237651a9
|
||||
|
|
@ -0,0 +1 @@
|
|||
5ff679739fbce0653dc0aa73d369874f2386fd04b706bee152c07717db08695f
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation breaking-change" data-milestone="19.0">
|
||||
|
||||
### Single database connection is deprecated
|
||||
|
||||
<div class="deprecation-notes">
|
||||
- Announced in GitLab <span class="milestone">15.9</span>
|
||||
- Removal in GitLab <span class="milestone">19.0</span> ([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).
|
||||
</div>
|
||||
|
||||
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.
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -501,28 +522,6 @@ For updates and details about this deprecation, follow [this epic](https://gitla
|
|||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### Single database connection is deprecated
|
||||
|
||||
<div class="deprecation-notes">
|
||||
- Announced in GitLab <span class="milestone">15.9</span>
|
||||
- End of Support in GitLab <span class="milestone">17.0</span>
|
||||
- Removal in GitLab <span class="milestone">18.0</span> ([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).
|
||||
</div>
|
||||
|
||||
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.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### Slack notifications integration
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 <kbd>e</kbd> 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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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 })
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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}"]
|
||||
|
|
|
|||
|
|
@ -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}"]
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ type RedisConfig struct {
|
|||
URL TomlURL
|
||||
Sentinel []TomlURL
|
||||
SentinelMaster string
|
||||
SentinelUsername string
|
||||
SentinelPassword string
|
||||
Password string
|
||||
DB *int
|
||||
|
|
|
|||
|
|
@ -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 <host>:<port> format
|
||||
// sentinelOptions extracts the sentinel username and password from the URLs
|
||||
// and addresses in <host>:<port> 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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue