diff --git a/.rubocop_todo/gitlab/bounded_contexts.yml b/.rubocop_todo/gitlab/bounded_contexts.yml
index 01ae4b178bc..529152c7bac 100644
--- a/.rubocop_todo/gitlab/bounded_contexts.yml
+++ b/.rubocop_todo/gitlab/bounded_contexts.yml
@@ -2907,7 +2907,6 @@ Gitlab/BoundedContexts:
- 'ee/app/models/elastic/index_setting.rb'
- 'ee/app/models/elastic/migration_record.rb'
- 'ee/app/models/elastic/reindexing_slice.rb'
- - 'ee/app/models/elastic/reindexing_subtask.rb'
- 'ee/app/models/elastic/reindexing_task.rb'
- 'ee/app/models/elasticsearch_indexed_namespace.rb'
- 'ee/app/models/elasticsearch_indexed_project.rb'
diff --git a/.rubocop_todo/gitlab/documentation_links/link.yml b/.rubocop_todo/gitlab/documentation_links/link.yml
index dfedee119f5..2fb80207ed5 100644
--- a/.rubocop_todo/gitlab/documentation_links/link.yml
+++ b/.rubocop_todo/gitlab/documentation_links/link.yml
@@ -22,7 +22,6 @@ Gitlab/DocumentationLinks/Link:
- 'ee/app/helpers/projects/security/api_fuzzing_configuration_helper.rb'
- 'ee/app/helpers/vulnerabilities_helper.rb'
- 'ee/app/models/integrations/github.rb'
- - 'ee/lib/api/managed_licenses.rb'
- 'ee/lib/ee/gitlab/namespace_storage_size_error_message.rb'
- 'ee/lib/gitlab/checks/secrets_check.rb'
- 'ee/lib/gitlab/llm/chain/tools/tool.rb'
@@ -38,7 +37,6 @@ Gitlab/DocumentationLinks/Link:
- 'lib/gitlab/usage_data_counters/hll_redis_counter.rb'
- 'lib/slack/block_kit/app_home_opened.rb'
- 'lib/system_check/helpers.rb'
- - 'lib/users/internal.rb'
- 'spec/helpers/ide_helper_spec.rb'
- 'spec/mailers/emails/pages_domains_spec.rb'
- 'spec/presenters/clusters/cluster_presenter_spec.rb'
diff --git a/.rubocop_todo/rails/inverse_of.yml b/.rubocop_todo/rails/inverse_of.yml
index c8dbb9b7a0e..2ed8bc1ae8c 100644
--- a/.rubocop_todo/rails/inverse_of.yml
+++ b/.rubocop_todo/rails/inverse_of.yml
@@ -60,7 +60,6 @@ Rails/InverseOf:
- 'ee/app/models/ee/project.rb'
- 'ee/app/models/ee/service_desk_setting.rb'
- 'ee/app/models/ee/user.rb'
- - 'ee/app/models/elastic/reindexing_subtask.rb'
- 'ee/app/models/geo/event.rb'
- 'ee/app/models/geo/event_log.rb'
- 'ee/app/models/geo/job_artifact_registry.rb'
diff --git a/.rubocop_todo/rspec/feature_category.yml b/.rubocop_todo/rspec/feature_category.yml
index 7721a1987be..3967d117d3b 100644
--- a/.rubocop_todo/rspec/feature_category.yml
+++ b/.rubocop_todo/rspec/feature_category.yml
@@ -816,7 +816,6 @@ RSpec/FeatureCategory:
- 'ee/spec/models/ee/users_statistics_spec.rb'
- 'ee/spec/models/elastic/index_setting_spec.rb'
- 'ee/spec/models/elastic/reindexing_slice_spec.rb'
- - 'ee/spec/models/elastic/reindexing_subtask_spec.rb'
- 'ee/spec/models/elastic/reindexing_task_spec.rb'
- 'ee/spec/models/epic_user_mention_spec.rb'
- 'ee/spec/models/gitlab/seat_link_data_spec.rb'
diff --git a/.rubocop_todo/search/namespaced_class.yml b/.rubocop_todo/search/namespaced_class.yml
index 28479ab5826..118f7842990 100644
--- a/.rubocop_todo/search/namespaced_class.yml
+++ b/.rubocop_todo/search/namespaced_class.yml
@@ -31,7 +31,6 @@ Search/NamespacedClass:
- 'ee/app/models/elastic/index_setting.rb'
- 'ee/app/models/elastic/migration_record.rb'
- 'ee/app/models/elastic/reindexing_slice.rb'
- - 'ee/app/models/elastic/reindexing_subtask.rb'
- 'ee/app/models/elastic/reindexing_task.rb'
- 'ee/app/models/elasticsearch_indexed_namespace.rb'
- 'ee/app/models/elasticsearch_indexed_project.rb'
diff --git a/.rubocop_todo/style/class_and_module_children.yml b/.rubocop_todo/style/class_and_module_children.yml
index 6867e5d4eda..542cbbc3bb2 100644
--- a/.rubocop_todo/style/class_and_module_children.yml
+++ b/.rubocop_todo/style/class_and_module_children.yml
@@ -421,7 +421,6 @@ Style/ClassAndModuleChildren:
- 'ee/app/models/dast/profile_schedule.rb'
- 'ee/app/models/ee/ci/job_artifact.rb'
- 'ee/app/models/elastic/reindexing_slice.rb'
- - 'ee/app/models/elastic/reindexing_subtask.rb'
- 'ee/app/models/elastic/reindexing_task.rb'
- 'ee/app/models/epic/metrics.rb'
- 'ee/app/models/epic/related_epic_link.rb'
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 712ed302de9..d18cb6e9aff 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-f5742bf5cd567c3bfc02aca8880bc8f73a7fb7c4
+c2675ac3885b916376fb35eb123dd54820ca797d
diff --git a/app/assets/javascripts/ci/pipelines_page/components/failure_widget/pipeline_failed_jobs_widget.vue b/app/assets/javascripts/ci/pipelines_page/components/failure_widget/pipeline_failed_jobs_widget.vue
index b0c2c509251..317f9b508cf 100644
--- a/app/assets/javascripts/ci/pipelines_page/components/failure_widget/pipeline_failed_jobs_widget.vue
+++ b/app/assets/javascripts/ci/pipelines_page/components/failure_widget/pipeline_failed_jobs_widget.vue
@@ -1,11 +1,12 @@
@@ -157,5 +172,22 @@ export default {
+
diff --git a/app/assets/javascripts/notes/components/noteable_note.vue b/app/assets/javascripts/notes/components/noteable_note.vue
index c57cfbe90d2..0c6c2c4fbc2 100644
--- a/app/assets/javascripts/notes/components/noteable_note.vue
+++ b/app/assets/javascripts/notes/components/noteable_note.vue
@@ -421,7 +421,7 @@ export default {
diff --git a/app/assets/javascripts/notes/components/toggle_replies_widget.vue b/app/assets/javascripts/notes/components/toggle_replies_widget.vue
index 6c15f94ed4e..bc9a7f89a08 100644
--- a/app/assets/javascripts/notes/components/toggle_replies_widget.vue
+++ b/app/assets/javascripts/notes/components/toggle_replies_widget.vue
@@ -60,7 +60,7 @@ export default {
.timeline-entry-inner {
- @apply gl-bg-default;
-
- // stylelint-disable-next-line gitlab/no-gl-class
- .gl-dark & {
- @apply gl-bg-strong gl-border-b-default;
- }
+ @apply gl-bg-section dark:gl-border-b-section;
.toggle-replies-widget {
- @apply gl-border-b-subtle;
+ @apply gl-border-b-subtle dark:gl-border-b-section;
}
.toggle-replies-widget[aria-expanded="false"] {
@@ -317,7 +312,7 @@
.diff-files-holder {
.discussion-notes .timeline-entry:first-of-type > .timeline-entry-inner {
- @apply gl-border-b gl-border-b-subtle;
+ @apply gl-border-b gl-border-b-subtle dark:gl-border-b-section;
}
}
@@ -386,16 +381,11 @@
.timeline-entry-inner {
margin-left: $note-spacing-left;
- @apply gl-bg-subtle gl-border-l gl-border-r;
+ @apply gl-bg-subtle gl-border-l gl-border-l-section gl-border-r gl-border-r-section;
.timeline-content {
padding: $gl-padding-8 $gl-padding-8 $gl-padding-8 $gl-padding;
- @apply gl-bg-default gl-border-b gl-border-b-subtle;
-
- // stylelint-disable-next-line gitlab/no-gl-class
- .gl-dark & {
- @apply gl-bg-strong gl-border-b-default;
- }
+ @apply gl-bg-section gl-border-b gl-border-b-subtle dark:gl-border-b-section;
}
.timeline-avatar {
diff --git a/app/assets/stylesheets/page_bundles/notes/_notes_base.scss b/app/assets/stylesheets/page_bundles/notes/_notes_base.scss
index 5febce4f715..b0dbd05d169 100644
--- a/app/assets/stylesheets/page_bundles/notes/_notes_base.scss
+++ b/app/assets/stylesheets/page_bundles/notes/_notes_base.scss
@@ -29,13 +29,8 @@
.timeline-content {
margin-left: $note-spacing-left;
- @apply gl-border gl-rounded-base;
+ @apply gl-bg-section gl-border gl-border-section gl-rounded-base;
padding: $gl-padding-4 $gl-padding-8;
-
- // stylelint-disable-next-line gitlab/no-gl-class
- .gl-dark & {
- @apply gl-bg-strong gl-border-default;
- }
}
.note-header-info {
@@ -64,19 +59,14 @@
.timeline-content {
margin-left: $note-spacing-left;
- @apply gl-border gl-border-b-subtle gl-rounded-t-base;
+ @apply gl-bg-section gl-border gl-border-b-subtle dark:gl-border-section gl-rounded-t-base;
padding: $gl-padding-4 $gl-padding-8;
-
- // stylelint-disable-next-line gitlab/no-gl-class
- .gl-dark & {
- @apply gl-bg-strong gl-border-default;
- }
}
}
&:not(:first-of-type) .timeline-entry-inner {
margin-left: $note-spacing-left;
- @apply gl-bg-subtle gl-border-l gl-border-r;
+ @apply gl-bg-subtle gl-border-l gl-border-l-section gl-border-r gl-border-r-section;
.timeline-content {
padding: $gl-padding-8 $gl-padding-8 $gl-padding-8 18px;
@@ -102,7 +92,7 @@
}
.discussion-reply-holder {
- @apply gl-border-1 gl-border-solid gl-border-default gl-border-t-0;
+ @apply gl-border gl-border-section gl-border-t-0;
@apply gl-bg-subtle;
}
}
@@ -292,16 +282,10 @@
.timeline-content {
padding: $gl-padding-8 !important;
- @apply gl-border gl-rounded-base;
-
- // stylelint-disable-next-line gitlab/no-gl-class
- .gl-dark & {
- @apply gl-bg-strong gl-border-b;
- }
+ @apply gl-bg-section gl-border gl-border-section gl-rounded-base;
&.expanded {
- // Render border invisible
- border-bottom: 1px solid var(--gl-background-color-subtle);
+ @apply gl-border-b-0;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
diff --git a/app/models/ci/runner_manager.rb b/app/models/ci/runner_manager.rb
index c0a2c74baf6..5f44ad32b1d 100644
--- a/app/models/ci/runner_manager.rb
+++ b/app/models/ci/runner_manager.rb
@@ -36,7 +36,7 @@ module Ci
EXECUTOR_TYPE_TO_NAMES = EXECUTOR_NAME_TO_TYPES.invert.freeze
- belongs_to :runner
+ belongs_to :runner, class_name: 'Ci::Runner', inverse_of: :runner_managers
enum creation_state: {
started: 0,
@@ -83,8 +83,11 @@ module Ci
).where(created_before_stale_deadline)
end
- scope :for_runner, ->(runner_id) do
- where(runner_id: runner_id)
+ scope :for_runner, ->(runner) do
+ scope = where(runner_id: runner)
+ scope = scope.where(runner_type: runner.runner_type) if runner.is_a?(Ci::Runner) # Use unique index if possible
+
+ scope
end
scope :with_system_xid, ->(system_xid) do
diff --git a/app/models/group.rb b/app/models/group.rb
index 5df5af5b2b6..6d6fbaa5cfb 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -884,7 +884,7 @@ class Group < Namespace
def parent_allows_two_factor_authentication?
return true unless has_parent?
- ancestor_settings = ancestors.find_by(parent_id: nil).namespace_settings
+ ancestor_settings = ancestors.find_top_level.namespace_settings
ancestor_settings.allow_mfa_for_subgroups
end
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 4bbb5100b15..cf0c51463cf 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -220,6 +220,7 @@ class Namespace < ApplicationRecord
scope :in_organization, ->(organization) { where(organization: organization) }
scope :by_name, ->(name) { where('name LIKE ?', "#{sanitize_sql_like(name)}%") }
scope :ordered_by_name, -> { order(:name) }
+ scope :top_level, -> { by_parent(nil) }
scope :with_statistics, -> do
namespace_statistic_columns = STATISTICS_COLUMNS.map { |column| sum_project_statistics_column(column) }
@@ -279,6 +280,10 @@ class Namespace < ApplicationRecord
find_by("lower(path) = :path OR lower(name) = :path", path: path.downcase)
end
+ def find_top_level
+ top_level.take
+ end
+
# Searches for namespaces matching the given query.
#
# This method uses ILIKE on PostgreSQL.
@@ -346,10 +351,6 @@ class Namespace < ApplicationRecord
value.scan(Gitlab::Regex.group_name_regex_chars).join(' ')
end
- def top_most
- by_parent(nil)
- end
-
def reference_prefix
User.reference_prefix
end
@@ -366,7 +367,7 @@ class Namespace < ApplicationRecord
end
def username_reserved?(username)
- without_project_namespaces.where(parent_id: nil).find_by_path_or_name(username).present?
+ without_project_namespaces.top_level.find_by_path_or_name(username).present?
end
end
diff --git a/app/models/namespace/traversal_hierarchy.rb b/app/models/namespace/traversal_hierarchy.rb
index fd381251734..ea2d71cbc83 100644
--- a/app/models/namespace/traversal_hierarchy.rb
+++ b/app/models/namespace/traversal_hierarchy.rb
@@ -107,7 +107,7 @@ class Namespace
.new(Namespace.where(id: namespace))
.base_and_ancestors
.reorder(nil)
- .find_by(parent_id: nil)
+ .find_top_level
end
def db_query_timeout_counter
diff --git a/app/models/namespaces/traversal/linear.rb b/app/models/namespaces/traversal/linear.rb
index 2d11d0bfddc..394e01843fd 100644
--- a/app/models/namespaces/traversal/linear.rb
+++ b/app/models/namespaces/traversal/linear.rb
@@ -259,7 +259,7 @@ module Namespaces
.new(Namespace.where(id: parent_ids))
.base_and_ancestors
.reorder(nil)
- .where(parent_id: nil)
+ .top_level
Namespace.lock.select(:id).where(id: roots).order(id: :asc).load
end
diff --git a/app/models/namespaces/traversal/recursive.rb b/app/models/namespaces/traversal/recursive.rb
index 881f2af6d71..01135440b90 100644
--- a/app/models/namespaces/traversal/recursive.rb
+++ b/app/models/namespaces/traversal/recursive.rb
@@ -9,7 +9,7 @@ module Namespaces
def root_ancestor
if persisted? && !parent_id.nil?
strong_memoize(:root_ancestor) do
- recursive_ancestors.reorder(nil).find_by(parent_id: nil)
+ recursive_ancestors.reorder(nil).find_top_level
end
elsif parent.nil?
self
diff --git a/db/docs/batched_background_migrations/backfill_has_vulnerability_resolution.yml b/db/docs/batched_background_migrations/backfill_has_vulnerability_resolution.yml
index dc37059029f..d7ae69bab86 100644
--- a/db/docs/batched_background_migrations/backfill_has_vulnerability_resolution.yml
+++ b/db/docs/batched_background_migrations/backfill_has_vulnerability_resolution.yml
@@ -10,4 +10,4 @@ feature_category: vulnerability_management
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/166110
milestone: '17.5'
queued_migration_version: 20240912184158
-finalized_by: # version of the migration that finalized this BBM
+finalized_by: 20241025010332
diff --git a/db/docs/ci_runner_machines_687967fa8a.yml b/db/docs/ci_runner_machines_687967fa8a.yml
new file mode 100644
index 00000000000..0ca2b8df6e9
--- /dev/null
+++ b/db/docs/ci_runner_machines_687967fa8a.yml
@@ -0,0 +1,13 @@
+---
+table_name: ci_runner_machines_687967fa8a
+classes:
+- Ci::RunnerManager
+feature_categories:
+- runner
+- fleet_visibility
+- hosted_runners
+description: Routing table for CI runner managers
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/168131
+milestone: '17.6'
+gitlab_schema: gitlab_ci
+exempt_from_sharding: true
diff --git a/db/docs/dependency_list_exports.yml b/db/docs/dependency_list_exports.yml
index d77a8926821..6e0e235cc20 100644
--- a/db/docs/dependency_list_exports.yml
+++ b/db/docs/dependency_list_exports.yml
@@ -17,4 +17,4 @@ desired_sharding_key_migration_job_name: BackfillProjectIdToDependencyListExport
# organization_id: organizations
#
# A multi-column not-null constraint should be added on these columns.
-
+sharding_key_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/501463
diff --git a/db/docs/elastic_reindexing_subtasks.yml b/db/docs/elastic_reindexing_subtasks.yml
index 5f05170cf16..ae61b89eef1 100644
--- a/db/docs/elastic_reindexing_subtasks.yml
+++ b/db/docs/elastic_reindexing_subtasks.yml
@@ -1,7 +1,7 @@
---
table_name: elastic_reindexing_subtasks
classes:
-- Elastic::ReindexingSubtask
+- Search::Elastic::ReindexingSubtask
feature_categories:
- global_search
description: TODO
diff --git a/db/docs/group_type_ci_runner_machines_687967fa8a.yml b/db/docs/group_type_ci_runner_machines_687967fa8a.yml
new file mode 100644
index 00000000000..a42723ec38d
--- /dev/null
+++ b/db/docs/group_type_ci_runner_machines_687967fa8a.yml
@@ -0,0 +1,13 @@
+---
+table_name: group_type_ci_runner_machines_687967fa8a
+classes:
+- Ci::RunnerManager
+feature_categories:
+- runner
+- fleet_visibility
+description: Information about runner managers associated to group Ci::Runner models
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/168131
+milestone: '17.6'
+gitlab_schema: gitlab_ci
+sharding_key:
+ sharding_key_id: namespaces
diff --git a/db/docs/instance_type_ci_runner_machines_687967fa8a.yml b/db/docs/instance_type_ci_runner_machines_687967fa8a.yml
new file mode 100644
index 00000000000..d7815d2371c
--- /dev/null
+++ b/db/docs/instance_type_ci_runner_machines_687967fa8a.yml
@@ -0,0 +1,13 @@
+---
+table_name: instance_type_ci_runner_machines_687967fa8a
+classes:
+- Ci::RunnerManager
+feature_categories:
+- runner
+- fleet_visibility
+- hosted_runners
+description: Information about runner managers associated to instance Ci::Runner models
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/168131
+milestone: '17.6'
+gitlab_schema: gitlab_ci
+exempt_from_sharding: true
diff --git a/db/docs/project_type_ci_runner_machines_687967fa8a.yml b/db/docs/project_type_ci_runner_machines_687967fa8a.yml
new file mode 100644
index 00000000000..e7efff1cf29
--- /dev/null
+++ b/db/docs/project_type_ci_runner_machines_687967fa8a.yml
@@ -0,0 +1,13 @@
+---
+table_name: project_type_ci_runner_machines_687967fa8a
+classes:
+- Ci::RunnerManager
+feature_categories:
+- runner
+- fleet_visibility
+description: Information about runner managers associated to project Ci::Runner models
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/168131
+milestone: '17.6'
+gitlab_schema: gitlab_ci
+sharding_key:
+ sharding_key_id: projects
diff --git a/db/docs/protected_branch_merge_access_levels.yml b/db/docs/protected_branch_merge_access_levels.yml
index a16ddd6aba0..2ab9e779349 100644
--- a/db/docs/protected_branch_merge_access_levels.yml
+++ b/db/docs/protected_branch_merge_access_levels.yml
@@ -8,4 +8,22 @@ description: Stores merge access settings for protected branches
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/5081
milestone: '8.11'
gitlab_schema: gitlab_main_cell
-sharding_key_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/490485
+allow_cross_foreign_keys:
+- gitlab_main_clusterwide
+desired_sharding_key:
+ protected_branch_project_id:
+ references: projects
+ backfill_via:
+ parent:
+ foreign_key: protected_branch_id
+ table: protected_branches
+ sharding_key: project_id
+ belongs_to: protected_branch
+ protected_branch_namespace_id:
+ references: namespaces
+ backfill_via:
+ parent:
+ foreign_key: protected_branch_id
+ table: protected_branches
+ sharding_key: namespace_id
+ belongs_to: protected_branch
diff --git a/db/docs/security_scans.yml b/db/docs/security_scans.yml
index 6598bd77f79..fa732999004 100644
--- a/db/docs/security_scans.yml
+++ b/db/docs/security_scans.yml
@@ -12,3 +12,4 @@ gitlab_schema: gitlab_sec
# because the backfill migration was processed manually.
# This migration is custom due to data consistency issues and cross-DB backfill.
desired_sharding_key_migration_job_name: BackfillProjectIdToSecurityScans
+sharding_key_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/501459
diff --git a/db/post_migrate/20241022181600_remove_backfill_vulnerability_occurrence_pipelines_project_id.rb b/db/migrate/20241022181600_remove_backfill_vulnerability_occurrence_pipelines_project_id.rb
similarity index 72%
rename from db/post_migrate/20241022181600_remove_backfill_vulnerability_occurrence_pipelines_project_id.rb
rename to db/migrate/20241022181600_remove_backfill_vulnerability_occurrence_pipelines_project_id.rb
index 3a30ce9b067..8fcaadaaee2 100644
--- a/db/post_migrate/20241022181600_remove_backfill_vulnerability_occurrence_pipelines_project_id.rb
+++ b/db/migrate/20241022181600_remove_backfill_vulnerability_occurrence_pipelines_project_id.rb
@@ -7,6 +7,8 @@ class RemoveBackfillVulnerabilityOccurrencePipelinesProjectId < Gitlab::Database
MIGRATION = "BackfillVulnerabilityOccurrencePipelinesProjectId"
def up
+ # rubocop:disable Migration/BatchMigrationsPostOnly -- Must be run before BBM code is deleted.
+ # Estimated runtime on .com is only 5 seconds.
delete_batched_background_migration(
MIGRATION,
:vulnerability_occurrence_pipelines,
@@ -18,6 +20,7 @@ class RemoveBackfillVulnerabilityOccurrencePipelinesProjectId < Gitlab::Database
:occurrence_id
]
)
+ # rubocop:enable Migration/BatchMigrationsPostOnly
end
def down
diff --git a/db/migrate/20241024204816_create_partitioned_ci_runner_managers.rb b/db/migrate/20241024204816_create_partitioned_ci_runner_managers.rb
new file mode 100644
index 00000000000..d2e4376d258
--- /dev/null
+++ b/db/migrate/20241024204816_create_partitioned_ci_runner_managers.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+class CreatePartitionedCiRunnerManagers < Gitlab::Database::Migration[2.2]
+ include Gitlab::Database::PartitioningMigrationHelpers::ForeignKeyHelpers
+ include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers
+
+ milestone '17.6'
+ disable_ddl_transaction!
+
+ TABLE_NAME = 'ci_runner_machines'
+ PARTITIONED_TABLE_NAME = :ci_runner_machines_687967fa8a
+ PARTITIONED_TABLE_PK = %w[id runner_type]
+
+ def up
+ partition_table_by_list(
+ TABLE_NAME, 'runner_type', primary_key: PARTITIONED_TABLE_PK,
+ partition_mappings: { instance_type: 1, group_type: 2, project_type: 3 },
+ partition_name_format: '%{partition_name}_%{table_name}',
+ create_partitioned_table_fn: ->(name) { create_partitioned_table(name) }
+ )
+ end
+
+ def down
+ drop_partitioned_table_for(TABLE_NAME)
+ end
+
+ private
+
+ def create_partitioned_table(name)
+ options = 'PARTITION BY LIST (runner_type)'
+ # rubocop: disable Migration/EnsureFactoryForTable -- we'll reuse the ci_runner_machines factory once migrated
+ create_table name, primary_key: PARTITIONED_TABLE_PK, options: options do |t|
+ t.bigint :id, null: false
+ t.bigint :runner_id, null: false
+ t.bigint :sharding_key_id, null: true
+ t.timestamps_with_timezone null: false
+ t.datetime_with_timezone :contacted_at
+ t.integer :creation_state, null: false, limit: 2, default: 0
+ t.integer :executor_type, null: true, limit: 2
+ t.integer :runner_type, null: false, limit: 2
+ t.jsonb :config, null: false, default: {}
+ t.text :system_xid, null: false, limit: 64
+ t.text :platform, limit: 255
+ t.text :architecture, limit: 255
+ t.text :revision, limit: 255
+ t.text :ip_address, limit: 1024
+ t.text :version, limit: 2048
+
+ t.index [:runner_id, :runner_type, :system_xid], name: "idx_uniq_#{name}_on_runner_id_system_xid", unique: true
+ t.index :sharding_key_id, name: "idx_#{name}_on_sharding_key_where_notnull",
+ where: 'sharding_key_id IS NOT NULL'
+ t.index %i[contacted_at id], name: "idx_#{name}_on_contacted_at_desc_id_desc",
+ order: { contacted_at: :desc, id: :desc }
+ t.index %i[created_at id], name: "index_#{name}_on_created_at_and_id_desc",
+ order: { runner_type: :asc, id: :desc }
+ t.index %q[((substring(version from '^\d+\.'))), version, runner_id], name: "index_#{name}_on_major_version"
+ t.index %q[((substring(version from '^\d+\.\d+\.'))), version, runner_id], name: "index_#{name}_on_minor_version"
+ t.index %q[((substring(version from '^\d+\.\d+\.\d+'))), version, runner_id],
+ name: "index_#{name}_on_patch_version"
+ t.index :version, name: "index_#{name}_on_version"
+ end
+ # rubocop: enable Migration/EnsureFactoryForTable
+ end
+end
diff --git a/db/migrate/20241025112847_add_sharding_key_check_constraint_to_partitioned_ci_runner_managers.rb b/db/migrate/20241025112847_add_sharding_key_check_constraint_to_partitioned_ci_runner_managers.rb
new file mode 100644
index 00000000000..c9cf1a7f6f2
--- /dev/null
+++ b/db/migrate/20241025112847_add_sharding_key_check_constraint_to_partitioned_ci_runner_managers.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class AddShardingKeyCheckConstraintToPartitionedCiRunnerManagers < Gitlab::Database::Migration[2.2]
+ disable_ddl_transaction!
+ milestone '17.6'
+
+ PARTITIONED_TABLE_NAME = :ci_runner_machines_687967fa8a
+ CONSTRAINT_NAME = 'check_sharding_key_id_nullness'
+
+ def up
+ Gitlab::Database::PostgresPartitionedTable.each_partition(PARTITIONED_TABLE_NAME) do |partition|
+ source = partition.to_s
+
+ add_check_constraint(source,
+ source.start_with?('instance_type') ? 'sharding_key_id IS NULL' : 'sharding_key_id IS NOT NULL',
+ CONSTRAINT_NAME)
+ end
+ end
+
+ def down
+ Gitlab::Database::PostgresPartitionedTable.each_partition(PARTITIONED_TABLE_NAME) do |partition|
+ source = partition.to_s
+
+ remove_check_constraint(source, CONSTRAINT_NAME)
+ end
+ end
+end
diff --git a/db/migrate/20241025153240_add_fk_from_partitioned_ci_runner_managers_to_partitioned_ci_runners.rb b/db/migrate/20241025153240_add_fk_from_partitioned_ci_runner_managers_to_partitioned_ci_runners.rb
new file mode 100644
index 00000000000..04254950177
--- /dev/null
+++ b/db/migrate/20241025153240_add_fk_from_partitioned_ci_runner_managers_to_partitioned_ci_runners.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+class AddFkFromPartitionedCiRunnerManagersToPartitionedCiRunners < Gitlab::Database::Migration[2.2]
+ include Gitlab::Database::PartitioningMigrationHelpers::ForeignKeyHelpers
+ include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers
+
+ milestone '17.6'
+
+ disable_ddl_transaction!
+
+ SOURCE_TABLE_NAME = :ci_runner_machines_687967fa8a
+ TARGET_TABLE_NAME = :ci_runners_e59bb2812d
+ COLUMN = %i[runner_id runner_type]
+ TARGET_COLUMN = %i[id runner_type]
+ FK_NAME = :fk_rails_3f92913d27
+
+ def up
+ Gitlab::Database::PostgresPartitionedTable.each_partition(SOURCE_TABLE_NAME) do |partition|
+ add_partitioned_foreign_key(partition)
+ end
+
+ add_concurrent_foreign_key(SOURCE_TABLE_NAME, TARGET_TABLE_NAME,
+ name: FK_NAME,
+ column: COLUMN,
+ target_column: TARGET_COLUMN,
+ validate: true,
+ on_update: :cascade,
+ on_delete: :cascade,
+ reverse_lock_order: true,
+ allow_partitioned: true)
+ end
+
+ def down
+ Gitlab::Database::PostgresPartitionedTable.each_partition(SOURCE_TABLE_NAME) do |partition|
+ source = partition.to_s
+
+ with_lock_retries do
+ remove_foreign_key_if_exists(source, partitioned_target_table_name(source),
+ name: FK_NAME, reverse_lock_order: true)
+ end
+ end
+
+ with_lock_retries do
+ remove_foreign_key_if_exists(SOURCE_TABLE_NAME, TARGET_TABLE_NAME,
+ name: FK_NAME, reverse_lock_order: true)
+ end
+ end
+
+ private
+
+ def partitioned_target_table_name(source)
+ runner_type = source.match(/(.+?_type).+/)[1]
+ "#{runner_type}_#{TARGET_TABLE_NAME}"
+ end
+
+ def add_partitioned_foreign_key(partition)
+ source = partition.to_s
+ add_concurrent_foreign_key(source, partitioned_target_table_name(source),
+ name: FK_NAME,
+ column: COLUMN,
+ target_column: TARGET_COLUMN,
+ validate: true,
+ on_update: :cascade,
+ on_delete: :cascade,
+ reverse_lock_order: true)
+ end
+end
diff --git a/db/post_migrate/20241025010332_finalize_backfill_has_vulnerability_resolution.rb b/db/post_migrate/20241025010332_finalize_backfill_has_vulnerability_resolution.rb
new file mode 100644
index 00000000000..99159fe2be7
--- /dev/null
+++ b/db/post_migrate/20241025010332_finalize_backfill_has_vulnerability_resolution.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class FinalizeBackfillHasVulnerabilityResolution < Gitlab::Database::Migration[2.2]
+ MIGRATION = 'BackfillHasVulnerabilityResolution'
+
+ disable_ddl_transaction!
+ restrict_gitlab_migration gitlab_schema: :gitlab_main
+ milestone '17.6'
+
+ def up
+ ensure_batched_background_migration_is_finished(
+ job_class_name: MIGRATION,
+ table_name: :vulnerability_reads,
+ column_name: :id,
+ job_arguments: [],
+ finalize: true
+ )
+ end
+
+ def down
+ # no op
+ end
+end
diff --git a/db/schema_migrations/20241024204816 b/db/schema_migrations/20241024204816
new file mode 100644
index 00000000000..f21efd5a97f
--- /dev/null
+++ b/db/schema_migrations/20241024204816
@@ -0,0 +1 @@
+e0857bad7c3c291efa74c22894774df18956cf7abb4ca3d65eb8c3dbfd3d7cbf
\ No newline at end of file
diff --git a/db/schema_migrations/20241025010332 b/db/schema_migrations/20241025010332
new file mode 100644
index 00000000000..db615bcf311
--- /dev/null
+++ b/db/schema_migrations/20241025010332
@@ -0,0 +1 @@
+219459af48a3bdd8be64ba0cb8386dc6c2285b3106bda3ee5a83581cafa60d49
\ No newline at end of file
diff --git a/db/schema_migrations/20241025112847 b/db/schema_migrations/20241025112847
new file mode 100644
index 00000000000..dfd00a2d7b1
--- /dev/null
+++ b/db/schema_migrations/20241025112847
@@ -0,0 +1 @@
+ba92199ba7a07d17d1d2d08d283762e068dbc6daba4b9139475e9630ce769a85
\ No newline at end of file
diff --git a/db/schema_migrations/20241025153240 b/db/schema_migrations/20241025153240
new file mode 100644
index 00000000000..c040f4460d0
--- /dev/null
+++ b/db/schema_migrations/20241025153240
@@ -0,0 +1 @@
+2c9398a7f550db94fe876e862009cb26fdebb7a334165e13f35f98496e7c3729
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 8eb006d9aee..a892b0b4086 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -839,6 +839,71 @@ $$;
COMMENT ON FUNCTION table_sync_function_686d6c7993() IS 'Partitioning migration: table sync for ci_runners table';
+CREATE FUNCTION table_sync_function_e438f29263() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$
+BEGIN
+IF (TG_OP = 'DELETE') THEN
+ DELETE FROM ci_runner_machines_687967fa8a where "id" = OLD."id";
+ELSIF (TG_OP = 'UPDATE') THEN
+ UPDATE ci_runner_machines_687967fa8a
+ SET "runner_id" = NEW."runner_id",
+ "sharding_key_id" = NEW."sharding_key_id",
+ "created_at" = NEW."created_at",
+ "updated_at" = NEW."updated_at",
+ "contacted_at" = NEW."contacted_at",
+ "creation_state" = NEW."creation_state",
+ "executor_type" = NEW."executor_type",
+ "runner_type" = NEW."runner_type",
+ "config" = NEW."config",
+ "system_xid" = NEW."system_xid",
+ "platform" = NEW."platform",
+ "architecture" = NEW."architecture",
+ "revision" = NEW."revision",
+ "ip_address" = NEW."ip_address",
+ "version" = NEW."version"
+ WHERE ci_runner_machines_687967fa8a."id" = NEW."id";
+ELSIF (TG_OP = 'INSERT') THEN
+ INSERT INTO ci_runner_machines_687967fa8a ("id",
+ "runner_id",
+ "sharding_key_id",
+ "created_at",
+ "updated_at",
+ "contacted_at",
+ "creation_state",
+ "executor_type",
+ "runner_type",
+ "config",
+ "system_xid",
+ "platform",
+ "architecture",
+ "revision",
+ "ip_address",
+ "version")
+ VALUES (NEW."id",
+ NEW."runner_id",
+ NEW."sharding_key_id",
+ NEW."created_at",
+ NEW."updated_at",
+ NEW."contacted_at",
+ NEW."creation_state",
+ NEW."executor_type",
+ NEW."runner_type",
+ NEW."config",
+ NEW."system_xid",
+ NEW."platform",
+ NEW."architecture",
+ NEW."revision",
+ NEW."ip_address",
+ NEW."version");
+END IF;
+RETURN NULL;
+
+END
+$$;
+
+COMMENT ON FUNCTION table_sync_function_e438f29263() IS 'Partitioning migration: table sync for ci_runner_machines table';
+
CREATE FUNCTION trigger_01b3fc052119() RETURNS trigger
LANGUAGE plpgsql
AS $$
@@ -9301,6 +9366,32 @@ CREATE TABLE ci_runner_machines (
CONSTRAINT check_f214590856 CHECK ((char_length(ip_address) <= 1024))
);
+CREATE TABLE ci_runner_machines_687967fa8a (
+ id bigint NOT NULL,
+ runner_id bigint NOT NULL,
+ sharding_key_id bigint,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ contacted_at timestamp with time zone,
+ creation_state smallint DEFAULT 0 NOT NULL,
+ executor_type smallint,
+ runner_type smallint NOT NULL,
+ config jsonb DEFAULT '{}'::jsonb NOT NULL,
+ system_xid text NOT NULL,
+ platform text,
+ architecture text,
+ revision text,
+ ip_address text,
+ version text,
+ CONSTRAINT check_3d8736b3af CHECK ((char_length(system_xid) <= 64)),
+ CONSTRAINT check_5bad2a6944 CHECK ((char_length(revision) <= 255)),
+ CONSTRAINT check_7dc4eee8a5 CHECK ((char_length(version) <= 2048)),
+ CONSTRAINT check_b1e456641b CHECK ((char_length(ip_address) <= 1024)),
+ CONSTRAINT check_c788f4b18a CHECK ((char_length(platform) <= 255)),
+ CONSTRAINT check_f3d25ab844 CHECK ((char_length(architecture) <= 255))
+)
+PARTITION BY LIST (runner_type);
+
CREATE SEQUENCE ci_runner_machines_id_seq
START WITH 1
INCREMENT BY 1
@@ -12399,6 +12490,32 @@ CREATE SEQUENCE group_ssh_certificates_id_seq
ALTER SEQUENCE group_ssh_certificates_id_seq OWNED BY group_ssh_certificates.id;
+CREATE TABLE group_type_ci_runner_machines_687967fa8a (
+ id bigint NOT NULL,
+ runner_id bigint NOT NULL,
+ sharding_key_id bigint,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ contacted_at timestamp with time zone,
+ creation_state smallint DEFAULT 0 NOT NULL,
+ executor_type smallint,
+ runner_type smallint NOT NULL,
+ config jsonb DEFAULT '{}'::jsonb NOT NULL,
+ system_xid text NOT NULL,
+ platform text,
+ architecture text,
+ revision text,
+ ip_address text,
+ version text,
+ CONSTRAINT check_3d8736b3af CHECK ((char_length(system_xid) <= 64)),
+ CONSTRAINT check_5bad2a6944 CHECK ((char_length(revision) <= 255)),
+ CONSTRAINT check_7dc4eee8a5 CHECK ((char_length(version) <= 2048)),
+ CONSTRAINT check_b1e456641b CHECK ((char_length(ip_address) <= 1024)),
+ CONSTRAINT check_c788f4b18a CHECK ((char_length(platform) <= 255)),
+ CONSTRAINT check_f3d25ab844 CHECK ((char_length(architecture) <= 255)),
+ CONSTRAINT check_sharding_key_id_nullness CHECK ((sharding_key_id IS NOT NULL))
+);
+
CREATE TABLE group_type_ci_runners_e59bb2812d (
id bigint NOT NULL,
creator_id bigint,
@@ -12965,6 +13082,32 @@ CREATE SEQUENCE instance_integrations_id_seq
ALTER SEQUENCE instance_integrations_id_seq OWNED BY instance_integrations.id;
+CREATE TABLE instance_type_ci_runner_machines_687967fa8a (
+ id bigint NOT NULL,
+ runner_id bigint NOT NULL,
+ sharding_key_id bigint,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ contacted_at timestamp with time zone,
+ creation_state smallint DEFAULT 0 NOT NULL,
+ executor_type smallint,
+ runner_type smallint NOT NULL,
+ config jsonb DEFAULT '{}'::jsonb NOT NULL,
+ system_xid text NOT NULL,
+ platform text,
+ architecture text,
+ revision text,
+ ip_address text,
+ version text,
+ CONSTRAINT check_3d8736b3af CHECK ((char_length(system_xid) <= 64)),
+ CONSTRAINT check_5bad2a6944 CHECK ((char_length(revision) <= 255)),
+ CONSTRAINT check_7dc4eee8a5 CHECK ((char_length(version) <= 2048)),
+ CONSTRAINT check_b1e456641b CHECK ((char_length(ip_address) <= 1024)),
+ CONSTRAINT check_c788f4b18a CHECK ((char_length(platform) <= 255)),
+ CONSTRAINT check_f3d25ab844 CHECK ((char_length(architecture) <= 255)),
+ CONSTRAINT check_sharding_key_id_nullness CHECK ((sharding_key_id IS NULL))
+);
+
CREATE TABLE instance_type_ci_runners_e59bb2812d (
id bigint NOT NULL,
creator_id bigint,
@@ -17821,6 +17964,32 @@ CREATE SEQUENCE project_topics_id_seq
ALTER SEQUENCE project_topics_id_seq OWNED BY project_topics.id;
+CREATE TABLE project_type_ci_runner_machines_687967fa8a (
+ id bigint NOT NULL,
+ runner_id bigint NOT NULL,
+ sharding_key_id bigint,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ contacted_at timestamp with time zone,
+ creation_state smallint DEFAULT 0 NOT NULL,
+ executor_type smallint,
+ runner_type smallint NOT NULL,
+ config jsonb DEFAULT '{}'::jsonb NOT NULL,
+ system_xid text NOT NULL,
+ platform text,
+ architecture text,
+ revision text,
+ ip_address text,
+ version text,
+ CONSTRAINT check_3d8736b3af CHECK ((char_length(system_xid) <= 64)),
+ CONSTRAINT check_5bad2a6944 CHECK ((char_length(revision) <= 255)),
+ CONSTRAINT check_7dc4eee8a5 CHECK ((char_length(version) <= 2048)),
+ CONSTRAINT check_b1e456641b CHECK ((char_length(ip_address) <= 1024)),
+ CONSTRAINT check_c788f4b18a CHECK ((char_length(platform) <= 255)),
+ CONSTRAINT check_f3d25ab844 CHECK ((char_length(architecture) <= 255)),
+ CONSTRAINT check_sharding_key_id_nullness CHECK ((sharding_key_id IS NOT NULL))
+);
+
CREATE TABLE project_type_ci_runners_e59bb2812d (
id bigint NOT NULL,
creator_id bigint,
@@ -22229,10 +22398,16 @@ ALTER TABLE ONLY p_ci_pipelines ATTACH PARTITION ci_pipelines FOR VALUES IN ('10
ALTER TABLE ONLY p_ci_stages ATTACH PARTITION ci_stages FOR VALUES IN ('100', '101');
+ALTER TABLE ONLY ci_runner_machines_687967fa8a ATTACH PARTITION group_type_ci_runner_machines_687967fa8a FOR VALUES IN ('2');
+
ALTER TABLE ONLY ci_runners_e59bb2812d ATTACH PARTITION group_type_ci_runners_e59bb2812d FOR VALUES IN ('2');
+ALTER TABLE ONLY ci_runner_machines_687967fa8a ATTACH PARTITION instance_type_ci_runner_machines_687967fa8a FOR VALUES IN ('1');
+
ALTER TABLE ONLY ci_runners_e59bb2812d ATTACH PARTITION instance_type_ci_runners_e59bb2812d FOR VALUES IN ('1');
+ALTER TABLE ONLY ci_runner_machines_687967fa8a ATTACH PARTITION project_type_ci_runner_machines_687967fa8a FOR VALUES IN ('3');
+
ALTER TABLE ONLY ci_runners_e59bb2812d ATTACH PARTITION project_type_ci_runners_e59bb2812d FOR VALUES IN ('3');
ALTER TABLE ONLY abuse_events ALTER COLUMN id SET DEFAULT nextval('abuse_events_id_seq'::regclass);
@@ -24546,6 +24721,9 @@ ALTER TABLE ONLY ci_resource_groups
ALTER TABLE ONLY ci_resources
ADD CONSTRAINT ci_resources_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY ci_runner_machines_687967fa8a
+ ADD CONSTRAINT ci_runner_machines_687967fa8a_pkey PRIMARY KEY (id, runner_type);
+
ALTER TABLE ONLY ci_runner_machines
ADD CONSTRAINT ci_runner_machines_pkey PRIMARY KEY (id);
@@ -25011,6 +25189,9 @@ ALTER TABLE ONLY group_security_exclusions
ALTER TABLE ONLY group_ssh_certificates
ADD CONSTRAINT group_ssh_certificates_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY group_type_ci_runner_machines_687967fa8a
+ ADD CONSTRAINT group_type_ci_runner_machines_687967fa8a_pkey PRIMARY KEY (id, runner_type);
+
ALTER TABLE ONLY group_type_ci_runners_e59bb2812d
ADD CONSTRAINT group_type_ci_runners_e59bb2812d_pkey PRIMARY KEY (id, runner_type);
@@ -25098,6 +25279,9 @@ ALTER TABLE ONLY instance_audit_events_streaming_headers
ALTER TABLE ONLY instance_integrations
ADD CONSTRAINT instance_integrations_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY instance_type_ci_runner_machines_687967fa8a
+ ADD CONSTRAINT instance_type_ci_runner_machines_687967fa8a_pkey PRIMARY KEY (id, runner_type);
+
ALTER TABLE ONLY instance_type_ci_runners_e59bb2812d
ADD CONSTRAINT instance_type_ci_runners_e59bb2812d_pkey PRIMARY KEY (id, runner_type);
@@ -25788,6 +25972,9 @@ ALTER TABLE ONLY project_statistics
ALTER TABLE ONLY project_topics
ADD CONSTRAINT project_topics_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY project_type_ci_runner_machines_687967fa8a
+ ADD CONSTRAINT project_type_ci_runner_machines_687967fa8a_pkey PRIMARY KEY (id, runner_type);
+
ALTER TABLE ONLY project_type_ci_runners_e59bb2812d
ADD CONSTRAINT project_type_ci_runners_e59bb2812d_pkey PRIMARY KEY (id, runner_type);
@@ -27554,6 +27741,38 @@ CREATE UNIQUE INDEX finding_link_name_url_idx ON vulnerability_finding_links USI
CREATE UNIQUE INDEX finding_link_url_idx ON vulnerability_finding_links USING btree (vulnerability_occurrence_id, url) WHERE (name IS NULL);
+CREATE INDEX idx_ci_runner_machines_687967fa8a_on_contacted_at_desc_id_desc ON ONLY ci_runner_machines_687967fa8a USING btree (contacted_at DESC, id DESC);
+
+CREATE INDEX group_type_ci_runner_machines_687967fa8a_contacted_at_id_idx ON group_type_ci_runner_machines_687967fa8a USING btree (contacted_at DESC, id DESC);
+
+CREATE INDEX index_ci_runner_machines_687967fa8a_on_created_at_and_id_desc ON ONLY ci_runner_machines_687967fa8a USING btree (created_at, id DESC);
+
+CREATE INDEX group_type_ci_runner_machines_687967fa8a_created_at_id_idx ON group_type_ci_runner_machines_687967fa8a USING btree (created_at, id DESC);
+
+CREATE INDEX idx_ci_runner_machines_687967fa8a_on_sharding_key_where_notnull ON ONLY ci_runner_machines_687967fa8a USING btree (sharding_key_id) WHERE (sharding_key_id IS NOT NULL);
+
+CREATE INDEX group_type_ci_runner_machines_687967fa8a_sharding_key_id_idx ON group_type_ci_runner_machines_687967fa8a USING btree (sharding_key_id) WHERE (sharding_key_id IS NOT NULL);
+
+CREATE INDEX index_ci_runner_machines_687967fa8a_on_version ON ONLY ci_runner_machines_687967fa8a USING btree (version);
+
+CREATE INDEX group_type_ci_runner_machines_687967fa8a_version_idx ON group_type_ci_runner_machines_687967fa8a USING btree (version);
+
+CREATE INDEX index_ci_runner_machines_687967fa8a_on_major_version ON ONLY ci_runner_machines_687967fa8a USING btree ("substring"(version, '^\d+\.'::text), version, runner_id);
+
+CREATE INDEX group_type_ci_runner_machines_6_substring_version_runner_id_idx ON group_type_ci_runner_machines_687967fa8a USING btree ("substring"(version, '^\d+\.'::text), version, runner_id);
+
+CREATE INDEX index_ci_runner_machines_687967fa8a_on_minor_version ON ONLY ci_runner_machines_687967fa8a USING btree ("substring"(version, '^\d+\.\d+\.'::text), version, runner_id);
+
+CREATE INDEX group_type_ci_runner_machines__substring_version_runner_id_idx1 ON group_type_ci_runner_machines_687967fa8a USING btree ("substring"(version, '^\d+\.\d+\.'::text), version, runner_id);
+
+CREATE INDEX index_ci_runner_machines_687967fa8a_on_patch_version ON ONLY ci_runner_machines_687967fa8a USING btree ("substring"(version, '^\d+\.\d+\.\d+'::text), version, runner_id);
+
+CREATE INDEX group_type_ci_runner_machines__substring_version_runner_id_idx2 ON group_type_ci_runner_machines_687967fa8a USING btree ("substring"(version, '^\d+\.\d+\.\d+'::text), version, runner_id);
+
+CREATE UNIQUE INDEX idx_uniq_ci_runner_machines_687967fa8a_on_runner_id_system_xid ON ONLY ci_runner_machines_687967fa8a USING btree (runner_id, runner_type, system_xid);
+
+CREATE UNIQUE INDEX group_type_ci_runner_machines_runner_id_runner_type_system__idx ON group_type_ci_runner_machines_687967fa8a USING btree (runner_id, runner_type, system_xid);
+
CREATE UNIQUE INDEX index_uniq_ci_runners_e59bb2812d_on_token_encrypted_and_type ON ONLY ci_runners_e59bb2812d USING btree (token_encrypted, runner_type);
CREATE UNIQUE INDEX group_type_ci_runners_e59bb2812_token_encrypted_runner_type_idx ON group_type_ci_runners_e59bb2812d USING btree (token_encrypted, runner_type);
@@ -32198,6 +32417,22 @@ CREATE INDEX index_zoom_meetings_on_issue_status ON zoom_meetings USING btree (i
CREATE INDEX index_zoom_meetings_on_project_id ON zoom_meetings USING btree (project_id);
+CREATE UNIQUE INDEX instance_type_ci_runner_machi_runner_id_runner_type_system__idx ON instance_type_ci_runner_machines_687967fa8a USING btree (runner_id, runner_type, system_xid);
+
+CREATE INDEX instance_type_ci_runner_machin_substring_version_runner_id_idx1 ON instance_type_ci_runner_machines_687967fa8a USING btree ("substring"(version, '^\d+\.\d+\.'::text), version, runner_id);
+
+CREATE INDEX instance_type_ci_runner_machin_substring_version_runner_id_idx2 ON instance_type_ci_runner_machines_687967fa8a USING btree ("substring"(version, '^\d+\.\d+\.\d+'::text), version, runner_id);
+
+CREATE INDEX instance_type_ci_runner_machine_substring_version_runner_id_idx ON instance_type_ci_runner_machines_687967fa8a USING btree ("substring"(version, '^\d+\.'::text), version, runner_id);
+
+CREATE INDEX instance_type_ci_runner_machines_687967fa8a_contacted_at_id_idx ON instance_type_ci_runner_machines_687967fa8a USING btree (contacted_at DESC, id DESC);
+
+CREATE INDEX instance_type_ci_runner_machines_687967fa8a_created_at_id_idx ON instance_type_ci_runner_machines_687967fa8a USING btree (created_at, id DESC);
+
+CREATE INDEX instance_type_ci_runner_machines_687967fa8a_sharding_key_id_idx ON instance_type_ci_runner_machines_687967fa8a USING btree (sharding_key_id) WHERE (sharding_key_id IS NOT NULL);
+
+CREATE INDEX instance_type_ci_runner_machines_687967fa8a_version_idx ON instance_type_ci_runner_machines_687967fa8a USING btree (version);
+
CREATE INDEX instance_type_ci_runners_e59bb2812d_active_id_idx ON instance_type_ci_runners_e59bb2812d USING btree (active, id);
CREATE INDEX instance_type_ci_runners_e59bb2812d_contacted_at_id_idx ON instance_type_ci_runners_e59bb2812d USING btree (contacted_at, id DESC);
@@ -32272,6 +32507,22 @@ CREATE INDEX partial_index_user_id_app_id_created_at_token_not_revoked ON oauth_
CREATE UNIQUE INDEX pm_checkpoints_path_components ON pm_checkpoints USING btree (purl_type, data_type, version_format);
+CREATE UNIQUE INDEX project_type_ci_runner_machin_runner_id_runner_type_system__idx ON project_type_ci_runner_machines_687967fa8a USING btree (runner_id, runner_type, system_xid);
+
+CREATE INDEX project_type_ci_runner_machine_substring_version_runner_id_idx1 ON project_type_ci_runner_machines_687967fa8a USING btree ("substring"(version, '^\d+\.\d+\.'::text), version, runner_id);
+
+CREATE INDEX project_type_ci_runner_machine_substring_version_runner_id_idx2 ON project_type_ci_runner_machines_687967fa8a USING btree ("substring"(version, '^\d+\.\d+\.\d+'::text), version, runner_id);
+
+CREATE INDEX project_type_ci_runner_machines_687967fa8a_contacted_at_id_idx ON project_type_ci_runner_machines_687967fa8a USING btree (contacted_at DESC, id DESC);
+
+CREATE INDEX project_type_ci_runner_machines_687967fa8a_created_at_id_idx ON project_type_ci_runner_machines_687967fa8a USING btree (created_at, id DESC);
+
+CREATE INDEX project_type_ci_runner_machines_687967fa8a_sharding_key_id_idx ON project_type_ci_runner_machines_687967fa8a USING btree (sharding_key_id) WHERE (sharding_key_id IS NOT NULL);
+
+CREATE INDEX project_type_ci_runner_machines_687967fa8a_version_idx ON project_type_ci_runner_machines_687967fa8a USING btree (version);
+
+CREATE INDEX project_type_ci_runner_machines_substring_version_runner_id_idx ON project_type_ci_runner_machines_687967fa8a USING btree ("substring"(version, '^\d+\.'::text), version, runner_id);
+
CREATE INDEX project_type_ci_runners_e59bb2812d_active_id_idx ON project_type_ci_runners_e59bb2812d USING btree (active, id);
CREATE INDEX project_type_ci_runners_e59bb2812d_contacted_at_id_idx ON project_type_ci_runners_e59bb2812d USING btree (contacted_at, id DESC);
@@ -33942,6 +34193,24 @@ ALTER INDEX p_ci_pipelines_pkey ATTACH PARTITION ci_pipelines_pkey;
ALTER INDEX p_ci_stages_pkey ATTACH PARTITION ci_stages_pkey;
+ALTER INDEX idx_ci_runner_machines_687967fa8a_on_contacted_at_desc_id_desc ATTACH PARTITION group_type_ci_runner_machines_687967fa8a_contacted_at_id_idx;
+
+ALTER INDEX index_ci_runner_machines_687967fa8a_on_created_at_and_id_desc ATTACH PARTITION group_type_ci_runner_machines_687967fa8a_created_at_id_idx;
+
+ALTER INDEX ci_runner_machines_687967fa8a_pkey ATTACH PARTITION group_type_ci_runner_machines_687967fa8a_pkey;
+
+ALTER INDEX idx_ci_runner_machines_687967fa8a_on_sharding_key_where_notnull ATTACH PARTITION group_type_ci_runner_machines_687967fa8a_sharding_key_id_idx;
+
+ALTER INDEX index_ci_runner_machines_687967fa8a_on_version ATTACH PARTITION group_type_ci_runner_machines_687967fa8a_version_idx;
+
+ALTER INDEX index_ci_runner_machines_687967fa8a_on_major_version ATTACH PARTITION group_type_ci_runner_machines_6_substring_version_runner_id_idx;
+
+ALTER INDEX index_ci_runner_machines_687967fa8a_on_minor_version ATTACH PARTITION group_type_ci_runner_machines__substring_version_runner_id_idx1;
+
+ALTER INDEX index_ci_runner_machines_687967fa8a_on_patch_version ATTACH PARTITION group_type_ci_runner_machines__substring_version_runner_id_idx2;
+
+ALTER INDEX idx_uniq_ci_runner_machines_687967fa8a_on_runner_id_system_xid ATTACH PARTITION group_type_ci_runner_machines_runner_id_runner_type_system__idx;
+
ALTER INDEX index_uniq_ci_runners_e59bb2812d_on_token_encrypted_and_type ATTACH PARTITION group_type_ci_runners_e59bb2812_token_encrypted_runner_type_idx;
ALTER INDEX index_ci_runners_e59bb2812d_on_active_and_id ATTACH PARTITION group_type_ci_runners_e59bb2812d_active_id_idx;
@@ -34106,6 +34375,24 @@ ALTER INDEX p_ci_builds_user_id_name_created_at_idx ATTACH PARTITION index_secur
ALTER INDEX p_ci_builds_name_id_idx ATTACH PARTITION index_security_ci_builds_on_name_and_id_parser_features;
+ALTER INDEX idx_uniq_ci_runner_machines_687967fa8a_on_runner_id_system_xid ATTACH PARTITION instance_type_ci_runner_machi_runner_id_runner_type_system__idx;
+
+ALTER INDEX index_ci_runner_machines_687967fa8a_on_minor_version ATTACH PARTITION instance_type_ci_runner_machin_substring_version_runner_id_idx1;
+
+ALTER INDEX index_ci_runner_machines_687967fa8a_on_patch_version ATTACH PARTITION instance_type_ci_runner_machin_substring_version_runner_id_idx2;
+
+ALTER INDEX index_ci_runner_machines_687967fa8a_on_major_version ATTACH PARTITION instance_type_ci_runner_machine_substring_version_runner_id_idx;
+
+ALTER INDEX idx_ci_runner_machines_687967fa8a_on_contacted_at_desc_id_desc ATTACH PARTITION instance_type_ci_runner_machines_687967fa8a_contacted_at_id_idx;
+
+ALTER INDEX index_ci_runner_machines_687967fa8a_on_created_at_and_id_desc ATTACH PARTITION instance_type_ci_runner_machines_687967fa8a_created_at_id_idx;
+
+ALTER INDEX ci_runner_machines_687967fa8a_pkey ATTACH PARTITION instance_type_ci_runner_machines_687967fa8a_pkey;
+
+ALTER INDEX idx_ci_runner_machines_687967fa8a_on_sharding_key_where_notnull ATTACH PARTITION instance_type_ci_runner_machines_687967fa8a_sharding_key_id_idx;
+
+ALTER INDEX index_ci_runner_machines_687967fa8a_on_version ATTACH PARTITION instance_type_ci_runner_machines_687967fa8a_version_idx;
+
ALTER INDEX index_ci_runners_e59bb2812d_on_active_and_id ATTACH PARTITION instance_type_ci_runners_e59bb2812d_active_id_idx;
ALTER INDEX index_ci_runners_e59bb2812d_on_contacted_at_and_id_desc ATTACH PARTITION instance_type_ci_runners_e59bb2812d_contacted_at_id_idx;
@@ -34140,6 +34427,24 @@ ALTER INDEX index_uniq_ci_runners_e59bb2812d_on_token_encrypted_and_type ATTACH
ALTER INDEX p_ci_builds_scheduled_at_idx ATTACH PARTITION partial_index_ci_builds_on_scheduled_at_with_scheduled_jobs;
+ALTER INDEX idx_uniq_ci_runner_machines_687967fa8a_on_runner_id_system_xid ATTACH PARTITION project_type_ci_runner_machin_runner_id_runner_type_system__idx;
+
+ALTER INDEX index_ci_runner_machines_687967fa8a_on_minor_version ATTACH PARTITION project_type_ci_runner_machine_substring_version_runner_id_idx1;
+
+ALTER INDEX index_ci_runner_machines_687967fa8a_on_patch_version ATTACH PARTITION project_type_ci_runner_machine_substring_version_runner_id_idx2;
+
+ALTER INDEX idx_ci_runner_machines_687967fa8a_on_contacted_at_desc_id_desc ATTACH PARTITION project_type_ci_runner_machines_687967fa8a_contacted_at_id_idx;
+
+ALTER INDEX index_ci_runner_machines_687967fa8a_on_created_at_and_id_desc ATTACH PARTITION project_type_ci_runner_machines_687967fa8a_created_at_id_idx;
+
+ALTER INDEX ci_runner_machines_687967fa8a_pkey ATTACH PARTITION project_type_ci_runner_machines_687967fa8a_pkey;
+
+ALTER INDEX idx_ci_runner_machines_687967fa8a_on_sharding_key_where_notnull ATTACH PARTITION project_type_ci_runner_machines_687967fa8a_sharding_key_id_idx;
+
+ALTER INDEX index_ci_runner_machines_687967fa8a_on_version ATTACH PARTITION project_type_ci_runner_machines_687967fa8a_version_idx;
+
+ALTER INDEX index_ci_runner_machines_687967fa8a_on_major_version ATTACH PARTITION project_type_ci_runner_machines_substring_version_runner_id_idx;
+
ALTER INDEX index_ci_runners_e59bb2812d_on_active_and_id ATTACH PARTITION project_type_ci_runners_e59bb2812d_active_id_idx;
ALTER INDEX index_ci_runners_e59bb2812d_on_contacted_at_and_id_desc ATTACH PARTITION project_type_ci_runners_e59bb2812d_contacted_at_id_idx;
@@ -34234,6 +34539,8 @@ CREATE TRIGGER table_sync_trigger_57c8465cd7 AFTER INSERT OR DELETE OR UPDATE ON
CREATE TRIGGER table_sync_trigger_61879721b5 AFTER INSERT OR DELETE OR UPDATE ON ci_runners FOR EACH ROW EXECUTE FUNCTION table_sync_function_686d6c7993();
+CREATE TRIGGER table_sync_trigger_bc3e7b56bd AFTER INSERT OR DELETE OR UPDATE ON ci_runner_machines FOR EACH ROW EXECUTE FUNCTION table_sync_function_e438f29263();
+
CREATE TRIGGER table_sync_trigger_cd362c20e2 AFTER INSERT OR DELETE OR UPDATE ON merge_request_diff_files FOR EACH ROW EXECUTE FUNCTION table_sync_function_3f39f64fc3();
CREATE TRIGGER tags_loose_fk_trigger AFTER DELETE ON tags REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
@@ -36634,6 +36941,18 @@ ALTER TABLE ONLY issuable_resource_links
ALTER TABLE ONLY board_assignees
ADD CONSTRAINT fk_rails_3f6f926bd5 FOREIGN KEY (board_id) REFERENCES boards(id) ON DELETE CASCADE;
+ALTER TABLE ONLY group_type_ci_runner_machines_687967fa8a
+ ADD CONSTRAINT fk_rails_3f92913d27 FOREIGN KEY (runner_id, runner_type) REFERENCES group_type_ci_runners_e59bb2812d(id, runner_type) ON UPDATE CASCADE ON DELETE CASCADE;
+
+ALTER TABLE ONLY instance_type_ci_runner_machines_687967fa8a
+ ADD CONSTRAINT fk_rails_3f92913d27 FOREIGN KEY (runner_id, runner_type) REFERENCES instance_type_ci_runners_e59bb2812d(id, runner_type) ON UPDATE CASCADE ON DELETE CASCADE;
+
+ALTER TABLE ONLY project_type_ci_runner_machines_687967fa8a
+ ADD CONSTRAINT fk_rails_3f92913d27 FOREIGN KEY (runner_id, runner_type) REFERENCES project_type_ci_runners_e59bb2812d(id, runner_type) ON UPDATE CASCADE ON DELETE CASCADE;
+
+ALTER TABLE ci_runner_machines_687967fa8a
+ ADD CONSTRAINT fk_rails_3f92913d27 FOREIGN KEY (runner_id, runner_type) REFERENCES ci_runners_e59bb2812d(id, runner_type) ON UPDATE CASCADE ON DELETE CASCADE;
+
ALTER TABLE ONLY description_versions
ADD CONSTRAINT fk_rails_3ff658220b FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE;
diff --git a/doc/administration/package_information/supported_os.md b/doc/administration/package_information/supported_os.md
index 4c4f029fe04..b3190c7c3a7 100644
--- a/doc/administration/package_information/supported_os.md
+++ b/doc/administration/package_information/supported_os.md
@@ -75,7 +75,7 @@ These versions of Oracle Linux are supported.
|:-----------------|:-------------------------------|:-------------|:----------------------------------------------------------------------------------------|:---------------------|:--------|
| Oracle Linux 7 | GitLab CE / GitLab EE 8.14.0 | `x86_64` | [Use CentOS installation documentation](https://about.gitlab.com/install/#centos-7) | Dec 2024 | [Oracle Linux details](https://www.oracle.com/a/ocom/docs/elsp-lifetime-069338.pdf) |
| Oracle Linux 8 | GitLab CE / GitLab EE 12.8.1 | `x86_64` | [Use AlmaLinux installation documentation](https://about.gitlab.com/install/#almalinux) | July 2029 | [Oracle Linux details](https://www.oracle.com/a/ocom/docs/elsp-lifetime-069338.pdf) |
-| Oracle Linux 9 | GitLab CE / GitLab EE 16.0.0 | `x86_64` | [Use AlmaLinux installation documentation](https://about.gitlab.com/install/#almalinux) | June 2032 | [Oracle Linux details](https://www.oracle.com/a/ocom/docs/elsp-lifetime-069338.pdf) |
+| Oracle Linux 9 | GitLab CE / GitLab EE 16.2.0 | `x86_64` | [Use AlmaLinux installation documentation](https://about.gitlab.com/install/#almalinux) | June 2032 | [Oracle Linux details](https://www.oracle.com/a/ocom/docs/elsp-lifetime-069338.pdf) |
## Raspberry Pi OS
diff --git a/doc/ci/steps/index.md b/doc/ci/steps/index.md
index e30b1efae2e..cfbeecd3362 100644
--- a/doc/ci/steps/index.md
+++ b/doc/ci/steps/index.md
@@ -82,7 +82,7 @@ Configure a GitLab CI/CD job to use CI Steps with the `run` keyword. You cannot
The `run` keyword accepts a list of steps to run. Steps are run one at a time in the order they are defined in the list.
Each list item has a `name` and either `step`, `script`, or `action`.
-Name must consist only of alpha-numeric characters and underscores, and must not start with a number.
+Name must consist only of alphanumeric characters and underscores, and must not start with a number.
### Run a step
@@ -296,7 +296,7 @@ The specification defines inputs and outputs that the step receives and returns.
#### Specify inputs
-Input names can only use alpha-numeric characters and underscores, and must not start with a number.
+Input names can only use alphanumeric characters and underscores, and must not start with a number.
Inputs must have a type, and they can optionally specify a default value. An input with no default value
is a required input, it must be specified when using the step.
@@ -333,7 +333,7 @@ run:
#### Specify outputs
-Similar to inputs, output names can only use alpha-numeric characters and underscores,
+Similar to inputs, output names can only use alphanumeric characters and underscores,
and must not start with a number. Outputs must have a type, and they can optionally specify a default value.
The default value is returned when the step doesn't return the output.
@@ -409,7 +409,7 @@ Steps can:
#### Set environment variables
Set environment variables by using the `env` keyword. Environment variable names can only use
-alpha-numeric characters and underscores, and must not start with a number.
+alphanumeric characters and underscores, and must not start with a number.
Environment variables are made available either to the executable command or to all of the steps
if running a sequence of steps. For example:
@@ -494,7 +494,7 @@ exec:
A step declares it runs a sequence of steps using the `steps` keyword. Steps run one at a time
in the order they are defined in the list. This syntax is the same as the `run` keyword.
-Steps must have a name consisting only of alpha-numeric characters and underscores, and must not start with a number.
+Steps must have a name consisting only of alphanumeric characters and underscores, and must not start with a number.
For example, this step installs Go, then runs a second step that expects Go to already
have been installed:
diff --git a/doc/ci/variables/index.md b/doc/ci/variables/index.md
index 4725eed1a5b..949c5a7216c 100644
--- a/doc/ci/variables/index.md
+++ b/doc/ci/variables/index.md
@@ -306,7 +306,7 @@ The value of the variable must:
- Be a single line with no spaces.
- Be 8 characters or longer.
- Not match the name of an existing predefined or custom CI/CD variable.
-- Not include non-alpha-numeric characters other than `@`, `_`, `-`, `:`, or `+`.
+- Not include non-alphanumeric characters other than `@`, `_`, `-`, `:`, or `+`.
Additionally, if [variable expansion](#prevent-cicd-variable-expansion) is enabled,
the value can contain only:
diff --git a/doc/development/fe_guide/style/scss.md b/doc/development/fe_guide/style/scss.md
index b2c45c92533..2f7001f187e 100644
--- a/doc/development/fe_guide/style/scss.md
+++ b/doc/development/fe_guide/style/scss.md
@@ -255,6 +255,47 @@ For CSS properties that are unit-less (e.g `display: flex`) it is okay to use CS
}
```
+The preferred way to use `@apply` is to combine multiple CSS classes in a single line or at most two,
+like in the example above. This approach keeps the CSS concise and easy to read:
+
+```css
+// Good
+.my-class {
+ @apply gl-mt-5 gl-flex gl-items-center;
+}
+```
+
+Avoid splitting classes across multiple lines, as shown below.
+
+```css
+// Avoid
+@apply gl-mt-5;
+@apply gl-flex;
+@apply gl-items-center;
+```
+
+The reason for this is that IDE extensions might only be able to detect conflicts when
+the CSS Classes are in one line:
+
+```css
+// ✅ Conflict detected: 'gl-bg-black' applies the same CSS properties as 'gl-bg-white'.(cssConflict)
+@apply gl-bg-white gl-bg-black;
+
+// ❌ No conflict detected
+@apply gl-bg-white;
+@apply gl-bg-black;
+```
+
+The exception to this rule is when working with `!important`. Since `!important` applies to
+the entire line, each class that requires it should be applied on its own line. For instance:
+
+```css
+@apply gl-flex gl-items-center;
+@apply gl-mt-5 #{!important};
+```
+
+This ensures that `!important` applies only where intended without affecting other classes in the same line.
+
## Naming
Filenames should use `snake_case`.
diff --git a/doc/tutorials/compliance_pipeline/index.md b/doc/tutorials/compliance_pipeline/index.md
index 4cb8093e21d..646f841a2f1 100644
--- a/doc/tutorials/compliance_pipeline/index.md
+++ b/doc/tutorials/compliance_pipeline/index.md
@@ -4,12 +4,19 @@ group: Compliance
info: For assistance with this tutorial, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments-to-other-projects-and-subjects.
---
-# Tutorial: Create a compliance pipeline
+
+
+# Tutorial: Create a compliance pipeline (deprecated)
DETAILS:
**Tier:** Ultimate
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
+WARNING:
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159841) in GitLab 17.3
+and is planned for removal in 18.0. Use [pipeline execution policy type](../../user/application_security/policies/pipeline_execution_policies.md) instead.
+This change is a breaking change. For more information, see the [migration guide](../../user/group/compliance_pipelines.md#pipeline-execution-policies-migration).
+
You can use [compliance pipelines](../../user/group/compliance_pipelines.md) to ensure specific
compliance-related jobs are run on pipelines for all projects in a group. Compliance pipelines are applied
to projects through [compliance frameworks](../../user/group/compliance_frameworks.md).
@@ -180,3 +187,5 @@ Notice the pipeline runs two jobs in a **test** stage:
Congratulations, you've created and configured a compliance pipeline!
See more [example compliance pipeline configurations](../../user/group/compliance_pipelines.md#example-configuration).
+
+
diff --git a/doc/update/index.md b/doc/update/index.md
index 24424aa490a..d838aaa8222 100644
--- a/doc/update/index.md
+++ b/doc/update/index.md
@@ -30,7 +30,8 @@ To upgrade GitLab:
1. Familiarize yourself with the [maintenance policy documentation](../policy/maintenance.md).
1. Read the [release posts](https://about.gitlab.com/releases/categories/releases/) for versions you're passing over.
In particular, deprecations, removals, and important notes on upgrading.
-1. Determine what [upgrade path](upgrade_paths.md) you should take. Your upgrade might require multiple upgrades. If
+1. Determine what [upgrade path](upgrade_paths.md) you should take. If your upgrade path includes required upgrade stops, you might have to perform multiple
+ upgrades to move from your current version to your target version. If
relevant, check [OS compatibility with the target GitLab version](../administration/package_information/supported_os.md).
1. Check for [background migrations](background_migrations.md). All migrations must finish running before each upgrade.
You must spread out upgrades between major and minor releases to allow time for background migrations to finish.
diff --git a/doc/user/group/compliance_pipelines.md b/doc/user/group/compliance_pipelines.md
index 4d21d99d215..598acd25f60 100644
--- a/doc/user/group/compliance_pipelines.md
+++ b/doc/user/group/compliance_pipelines.md
@@ -4,7 +4,9 @@ group: Compliance
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
-# Compliance pipelines
+
+
+# Compliance pipelines (deprecated)
DETAILS:
**Tier:** Ultimate
@@ -398,3 +400,5 @@ This error occurs because the pipeline execution policy includes the project's `
jobs when the jobs have already been declared in the pipeline.
To resolve this error, remove `include.project` from the separate YAML file linked in the pipeline execution policy.
+
+
diff --git a/lib/api/namespaces.rb b/lib/api/namespaces.rb
index 17425c288fc..0ef9c23f915 100644
--- a/lib/api/namespaces.rb
+++ b/lib/api/namespaces.rb
@@ -44,7 +44,7 @@ module API
namespaces = current_user.admin ? Namespace.all : current_user.namespaces(owned_only: owned_only)
- namespaces = namespaces.top_most if params[:top_level_only]
+ namespaces = namespaces.top_level if params[:top_level_only]
namespaces = namespaces.without_project_namespaces.include_route
diff --git a/lib/api/npm_instance_packages.rb b/lib/api/npm_instance_packages.rb
index 4b2d83a480c..dbf6bc240c1 100644
--- a/lib/api/npm_instance_packages.rb
+++ b/lib/api/npm_instance_packages.rb
@@ -9,7 +9,7 @@ module API
namespace_path = ::Packages::Npm.scope_of(params[:package_name])
return unless namespace_path
- Namespace.top_most.by_path(namespace_path)
+ Namespace.top_level.by_path(namespace_path)
end
end
diff --git a/lib/gitlab/database/partitioning/monthly_strategy.rb b/lib/gitlab/database/partitioning/monthly_strategy.rb
index 91af9dcf222..9d7592747cc 100644
--- a/lib/gitlab/database/partitioning/monthly_strategy.rb
+++ b/lib/gitlab/database/partitioning/monthly_strategy.rb
@@ -47,6 +47,12 @@ module Gitlab
# No-op, required by the partition manager
end
+ def partition_name(lower_bound)
+ suffix = lower_bound&.strftime('%Y%m') || '000000'
+
+ "#{table_name}_#{suffix}"
+ end
+
private
def desired_partitions
@@ -97,7 +103,7 @@ module Gitlab
end
def partition_for(upper_bound:, lower_bound: nil)
- TimePartition.new(table_name, lower_bound, upper_bound)
+ TimePartition.new(table_name, lower_bound, upper_bound, partition_name: partition_name(lower_bound))
end
def pruning_old_partitions?
diff --git a/lib/gitlab/database/partitioning/time_partition.rb b/lib/gitlab/database/partitioning/time_partition.rb
index 50c8c6f3e41..deaf8d88c88 100644
--- a/lib/gitlab/database/partitioning/time_partition.rb
+++ b/lib/gitlab/database/partitioning/time_partition.rb
@@ -19,23 +19,17 @@ module Gitlab
new(table, from, to, partition_name: partition_name)
end
- attr_reader :table, :from, :to
+ attr_reader :table, :from, :to, :partition_name
+
+ def initialize(table, from, to, partition_name:)
+ raise ArgumentError, "partition_name required but none given" unless partition_name
- def initialize(table, from, to, partition_name: nil)
@table = table.to_s
@from = date_or_nil(from)
@to = date_or_nil(to)
@partition_name = partition_name
end
- def partition_name
- return @partition_name if @partition_name
-
- suffix = from&.strftime('%Y%m') || '000000'
-
- "#{table}_#{suffix}"
- end
-
def to_sql
from_sql = from ? conn.quote(from.to_date.iso8601) : 'MINVALUE'
to_sql = conn.quote(to.to_date.iso8601)
diff --git a/lib/gitlab/diff/merge_request_suggestion.rb b/lib/gitlab/diff/merge_request_suggestion.rb
index afbe530febb..8a90af27e81 100644
--- a/lib/gitlab/diff/merge_request_suggestion.rb
+++ b/lib/gitlab/diff/merge_request_suggestion.rb
@@ -10,11 +10,12 @@ module Gitlab
SUGGESTION_HEADER = "```suggestion:"
SUGGESTION_FOOTER = "```"
- def initialize(diff, path, merge_request)
+ def initialize(diff, path, merge_request, prepend_text = nil)
@diff = diff
@path = path
@merge_request = merge_request
@project = merge_request.project
+ @prepend_text = prepend_text
end
def note_attributes_hash
@@ -100,7 +101,9 @@ module Gitlab
end
def suggestion
- array = [SUGGESTION_HEADER + suggestion_meta]
+ array = []
+ array << @prepend_text if @prepend_text
+ array << [SUGGESTION_HEADER + suggestion_meta]
diff_lines.each do |line|
array << line.text(prefix: false) if line.added? || line.unchanged?
diff --git a/lib/gitlab/pages/virtual_host_finder.rb b/lib/gitlab/pages/virtual_host_finder.rb
index f4f95750bb9..05d79ece196 100644
--- a/lib/gitlab/pages/virtual_host_finder.rb
+++ b/lib/gitlab/pages/virtual_host_finder.rb
@@ -34,7 +34,7 @@ module Gitlab
end
def by_namespace_domain(name)
- namespace = Namespace.top_most.by_path(name)
+ namespace = Namespace.top_level.by_path(name)
return if namespace.blank?
diff --git a/lib/users/internal.rb b/lib/users/internal.rb
index 902625f1f91..989934e2331 100644
--- a/lib/users/internal.rb
+++ b/lib/users/internal.rb
@@ -46,7 +46,6 @@ module Users
u.bio = 'System bot that monitors detected vulnerabilities for solutions ' \
'and creates merge requests with the fixes.'
u.name = 'GitLab Security Bot'
- u.website_url = Gitlab::Routing.url_helpers.help_page_url('user/application_security/security_bot/index.md')
u.avatar = bot_avatar(image: 'security-bot.png')
u.confirmed_at = Time.zone.now
u.private_profile = true
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 0b272ccd198..d51b2aba9dc 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -18989,6 +18989,9 @@ msgstr ""
msgid "Deployments|No deployment history"
msgstr ""
+msgid "Deployment|%{releaseName} release notes:"
+msgstr ""
+
msgid "Deployment|A colleague"
msgstr ""
@@ -44452,13 +44455,13 @@ msgstr ""
msgid "ProtectedBranch|default"
msgstr ""
-msgid "ProtectedEnvironments|%d Approval Rule"
-msgid_plural "ProtectedEnvironments|%d Approval Rules"
+msgid "ProtectedEnvironments|%d approval rule"
+msgid_plural "ProtectedEnvironments|%d approval rules"
msgstr[0] ""
msgstr[1] ""
-msgid "ProtectedEnvironments|%d Deployment Rule"
-msgid_plural "ProtectedEnvironments|%d Deployment Rules"
+msgid "ProtectedEnvironments|%d deployment rule"
+msgid_plural "ProtectedEnvironments|%d deployment rules"
msgstr[0] ""
msgstr[1] ""
@@ -55446,6 +55449,9 @@ msgstr ""
msgid "The subject will be used as the title of the new issue, and the message will be the description. %{quickActionsLinkStart}Quick actions%{quickActionsLinkEnd} and styling with %{markdownLinkStart}Markdown%{markdownLinkEnd} are supported."
msgstr ""
+msgid "The suggested code changes were generated by GitLab Duo Vulnerability Resolution, an AI feature. **Use this feature with caution.** Before you apply the code changes, carefully review and test them, to ensure that they solve the vulnerability.%{line_break}The large language model that generated the suggested code changes was provided with the entire file that contains the vulnerable lines of code. It is not aware of any functionality outside of this context. Please see our [documentation](%{docs_link}) for more information about this feature and leave feedback in this [issue](%{feedback_issue_link})."
+msgstr ""
+
msgid "The tag name can't be changed for an existing release."
msgstr ""
diff --git a/qa/gdk/Dockerfile.gdk b/qa/gdk/Dockerfile.gdk
index 625579a90e6..77846222178 100644
--- a/qa/gdk/Dockerfile.gdk
+++ b/qa/gdk/Dockerfile.gdk
@@ -1,4 +1,4 @@
-ARG GDK_SHA=d05ca4d8f629cc5c00d7fca73ae663789bcc3410
+ARG GDK_SHA=f14f8f3445959818c1272a9767fefa3b282f59c2
# Use tag prefix when running on 'stable' branch to make sure 'protected' image is used which is not deleted by registry cleanup
ARG GDK_BASE_TAG_PREFIX
diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb
index 702b3f17f41..65ee7ea5071 100644
--- a/spec/db/schema_spec.rb
+++ b/spec/db/schema_spec.rb
@@ -109,6 +109,10 @@ RSpec.describe 'Database schema',
p_ci_runner_machine_builds: %w[project_id],
ci_runners: %w[sharding_key_id], # This value is meant to populate the partitioned table, no other usage
ci_runner_machines: %w[sharding_key_id], # This value is meant to populate the partitioned table, no other usage
+ ci_runner_machines_687967fa8a: %w[sharding_key_id], # This field is only used in the partitions, and has the appropriate FKs
+ instance_type_ci_runner_machines_687967fa8a: %w[sharding_key_id], # This field is always NULL in this partition
+ group_type_ci_runner_machines_687967fa8a: %w[sharding_key_id], # No need for LFK, rows will be deleted by the FK to ci_runners
+ project_type_ci_runner_machines_687967fa8a: %w[sharding_key_id], # No need for LFK, rows will be deleted by the FK to ci_runners
ci_runner_projects: %w[runner_id],
ci_runners_e59bb2812d: %w[sharding_key_id], # This field is only used in the partitions, and has the appropriate FKs
instance_type_ci_runners_e59bb2812d: %w[sharding_key_id], # This field is always NULL in this partition
diff --git a/spec/frontend/ci/pipelines_page/components/failure_widget/pipeline_failed_jobs_widget_spec.js b/spec/frontend/ci/pipelines_page/components/failure_widget/pipeline_failed_jobs_widget_spec.js
index 153c287acc0..a764143b002 100644
--- a/spec/frontend/ci/pipelines_page/components/failure_widget/pipeline_failed_jobs_widget_spec.js
+++ b/spec/frontend/ci/pipelines_page/components/failure_widget/pipeline_failed_jobs_widget_spec.js
@@ -1,4 +1,4 @@
-import { GlButton } from '@gitlab/ui';
+import { GlBadge, GlButton } from '@gitlab/ui';
import CrudComponent from '~/vue_shared/components/crud_component.vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import PipelineFailedJobsWidget from '~/ci/pipelines_page/components/failure_widget/pipeline_failed_jobs_widget.vue';
@@ -38,6 +38,7 @@ describe('PipelineFailedJobsWidget component', () => {
const findFailedJobsButton = () => wrapper.findComponent(GlButton);
const findFailedJobsList = () => wrapper.findAllComponents(FailedJobsList);
const findCrudComponent = () => wrapper.findComponent(CrudComponent);
+ const findCount = () => wrapper.findComponent(GlBadge);
describe('when there are failed jobs', () => {
beforeEach(() => {
@@ -46,7 +47,7 @@ describe('PipelineFailedJobsWidget component', () => {
it('renders the show failed jobs button with correct count', () => {
expect(findFailedJobsButton().exists()).toBe(true);
- expect(findFailedJobsButton().text()).toContain(`${defaultProps.failedJobsCount}`);
+ expect(findCount().text()).toBe(String(defaultProps.failedJobsCount));
});
it('does not render the failed jobs widget', () => {
@@ -54,7 +55,7 @@ describe('PipelineFailedJobsWidget component', () => {
});
});
- const CSS_BORDER_CLASSES = 'is-collapsed gl-border-white hover:gl-border-gray-100';
+ const CSS_BORDER_CLASSES = 'is-collapsed gl-border-transparent hover:gl-border-default';
describe('when the job button is clicked', () => {
beforeEach(async () => {
@@ -98,11 +99,11 @@ describe('PipelineFailedJobsWidget component', () => {
it('updates the job count', async () => {
const newJobCount = 12;
- expect(findFailedJobsButton().text()).toContain(String(defaultProps.failedJobsCount));
+ expect(findCount().text()).toBe(String(defaultProps.failedJobsCount));
await wrapper.setProps({ failedJobsCount: newJobCount });
- expect(findFailedJobsButton().text()).toContain(String(newJobCount));
+ expect(findCount().text()).toBe(String(newJobCount));
});
});
@@ -114,11 +115,11 @@ describe('PipelineFailedJobsWidget component', () => {
it('updates the job count', async () => {
const newJobCount = 12;
- expect(findFailedJobsButton().text()).toContain(String(defaultProps.failedJobsCount));
+ expect(findCount().text()).toBe(String(defaultProps.failedJobsCount));
await findFailedJobsList().at(0).vm.$emit('failed-jobs-count', newJobCount);
- expect(findFailedJobsButton().text()).toContain(String(newJobCount));
+ expect(findCount().text()).toBe(String(newJobCount));
});
});
});
diff --git a/spec/frontend/deployments/components/show_deployment_spec.js b/spec/frontend/deployments/components/show_deployment_spec.js
index 4192eb5cd75..24dd1ea1a40 100644
--- a/spec/frontend/deployments/components/show_deployment_spec.js
+++ b/spec/frontend/deployments/components/show_deployment_spec.js
@@ -153,7 +153,7 @@ describe('~/deployments/components/show_deployment.vue', () => {
return createComponent();
});
- it('should set up a toggle visiblity hook on mount', () => {
+ it('should set up a toggle visibility hook on mount', () => {
expect(toggleQueryPollingByVisibility).toHaveBeenCalled();
});
});
diff --git a/spec/lib/api/ci/helpers/runner_spec.rb b/spec/lib/api/ci/helpers/runner_spec.rb
index d6b5a67402e..cecafc04e7e 100644
--- a/spec/lib/api/ci/helpers/runner_spec.rb
+++ b/spec/lib/api/ci/helpers/runner_spec.rb
@@ -107,17 +107,23 @@ RSpec.describe API::Ci::Helpers::Runner, feature_category: :runner do
expect(current_runner_manager.contacted_at).to eq 1.hour.ago
end
- context 'when a runner manager with nil runner_type and sharding_key_id already exists' do
+ context 'when a runner manager with nil sharding_key_id already exists' do
before do
- existing_runner_manager.update_columns(runner_type: nil, sharding_key_id: nil)
+ Ci::ApplicationRecord.connection.execute <<~SQL
+ ALTER TABLE group_type_ci_runner_machines_687967fa8a
+ DROP CONSTRAINT IF EXISTS check_sharding_key_id_nullness
+ SQL
+
+ existing_runner_manager.update_columns(sharding_key_id: nil)
end
- it 'reuses and updates existing runner manager', :aggregate_failures do
+ it 'reuses existing runner manager', :aggregate_failures do
expect { current_runner_manager }.not_to raise_error
expect(current_runner_manager).not_to be_nil
+ expect(current_runner_manager).to eq existing_runner_manager
expect(current_runner_manager.reload.contacted_at).to eq 1.hour.ago
- expect(current_runner_manager.runner_type).to be_nil
+ expect(current_runner_manager.runner_type).to eq runner.runner_type
expect(current_runner_manager.sharding_key_id).to be_nil
end
end
diff --git a/spec/lib/gitlab/database/partitioning/monthly_strategy_spec.rb b/spec/lib/gitlab/database/partitioning/monthly_strategy_spec.rb
index ea0b63979b2..c1b6fa9ba45 100644
--- a/spec/lib/gitlab/database/partitioning/monthly_strategy_spec.rb
+++ b/spec/lib/gitlab/database/partitioning/monthly_strategy_spec.rb
@@ -78,34 +78,34 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy, feature_category
subject { described_class.new(model, partitioning_key, retain_for: 1.month).missing_partitions }
it 'does not include the missing partition from May 2020 because it would be dropped' do
- expect(subject).not_to include(Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-05-01', '2020-06-01'))
+ expect(subject).not_to include(Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-05-01', '2020-06-01', partition_name: "#{model.table_name}_202005"))
end
it 'detects the missing partition for 1 month ago (July 2020)' do
- expect(subject).to include(Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-07-01', '2020-08-01'))
+ expect(subject).to include(Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-07-01', '2020-08-01', partition_name: "#{model.table_name}_202007"))
end
end
it 'detects the gap and the missing partition in May 2020' do
- expect(subject).to include(Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-05-01', '2020-06-01'))
+ expect(subject).to include(Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-05-01', '2020-06-01', partition_name: "#{model.table_name}_202005"))
end
it 'detects the missing partitions at the end of the range and expects a partition for July 2020' do
- expect(subject).to include(Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-07-01', '2020-08-01'))
+ expect(subject).to include(Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-07-01', '2020-08-01', partition_name: "#{model.table_name}_202007"))
end
it 'detects the missing partitions at the end of the range and expects a partition for August 2020' do
- expect(subject).to include(Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-08-01', '2020-09-01'))
+ expect(subject).to include(Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-08-01', '2020-09-01', partition_name: "#{model.table_name}_202008"))
end
it 'creates partitions 6 months out from now (Sep 2020 through Feb 2021)' do
expect(subject).to include(
- Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-09-01', '2020-10-01'),
- Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-10-01', '2020-11-01'),
- Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-11-01', '2020-12-01'),
- Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-12-01', '2021-01-01'),
- Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2021-01-01', '2021-02-01'),
- Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2021-02-01', '2021-03-01')
+ Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-09-01', '2020-10-01', partition_name: "#{model.table_name}_202009"),
+ Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-10-01', '2020-11-01', partition_name: "#{model.table_name}_202010"),
+ Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-11-01', '2020-12-01', partition_name: "#{model.table_name}_202011"),
+ Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-12-01', '2021-01-01', partition_name: "#{model.table_name}_202012"),
+ Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2021-01-01', '2021-02-01', partition_name: "#{model.table_name}_202101"),
+ Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2021-02-01', '2021-03-01', partition_name: "#{model.table_name}_202102")
)
end
@@ -129,7 +129,8 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy, feature_category
it 'detects exactly the set of partitions from June 2020 to March 2021' do
months = %w[2020-07-01 2020-08-01 2020-09-01 2020-10-01 2020-11-01 2020-12-01 2021-01-01 2021-02-01 2021-03-01]
expected = months[..-2].zip(months.drop(1)).map do |(from, to)|
- Gitlab::Database::Partitioning::TimePartition.new(model.table_name, from, to)
+ partition_name = "#{model.table_name}_#{Date.parse(from).strftime('%Y%m')}"
+ Gitlab::Database::Partitioning::TimePartition.new(model.table_name, from, to, partition_name: partition_name)
end
expect(subject).to match_array(expected)
@@ -137,21 +138,21 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy, feature_category
end
it 'detects the missing catch-all partition at the beginning' do
- expect(subject).to include(Gitlab::Database::Partitioning::TimePartition.new(model.table_name, nil, '2020-08-01'))
+ expect(subject).to include(Gitlab::Database::Partitioning::TimePartition.new(model.table_name, nil, '2020-08-01', partition_name: "#{model.table_name}_000000"))
end
it 'detects the missing partition for today and expects a partition for August 2020' do
- expect(subject).to include(Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-08-01', '2020-09-01'))
+ expect(subject).to include(Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-08-01', '2020-09-01', partition_name: "#{model.table_name}_202008"))
end
it 'creates partitions 6 months out from now (Sep 2020 through Feb 2021' do
expect(subject).to include(
- Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-09-01', '2020-10-01'),
- Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-10-01', '2020-11-01'),
- Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-11-01', '2020-12-01'),
- Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-12-01', '2021-01-01'),
- Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2021-01-01', '2021-02-01'),
- Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2021-02-01', '2021-03-01')
+ Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-09-01', '2020-10-01', partition_name: "#{model.table_name}_202009"),
+ Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-10-01', '2020-11-01', partition_name: "#{model.table_name}_202010"),
+ Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-11-01', '2020-12-01', partition_name: "#{model.table_name}_202011"),
+ Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-12-01', '2021-01-01', partition_name: "#{model.table_name}_202012"),
+ Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2021-01-01', '2021-02-01', partition_name: "#{model.table_name}_202101"),
+ Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2021-02-01', '2021-03-01', partition_name: "#{model.table_name}_202102")
)
end
@@ -174,7 +175,7 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy, feature_category
end
it 'detects a missing catch-all partition to add before the existing partition' do
- expect(subject).to include(Gitlab::Database::Partitioning::TimePartition.new(model.table_name, nil, '2020-06-01'))
+ expect(subject).to include(Gitlab::Database::Partitioning::TimePartition.new(model.table_name, nil, '2020-06-01', partition_name: "#{model.table_name}_000000"))
end
end
end
@@ -400,4 +401,30 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy, feature_category
})
end
end
+
+ describe '#partition_name' do
+ let(:model) { double('model', table_name: table_name) }
+ let(:partitioning_key) { double }
+ let(:table_name) { '_test_partitioned_test' }
+ let(:from) { Date.parse('2020-04-01 00:00:00') }
+ let(:to) { Date.parse('2020-05-01 00:00:00') }
+
+ subject(:partition_name) { described_class.new(model, partitioning_key).partition_name(from) }
+
+ it 'uses table_name as prefix' do
+ expect(partition_name).to start_with(table_name)
+ end
+
+ it 'uses Year-Month (from) as suffix' do
+ expect(partition_name).to end_with("_202004")
+ end
+
+ context 'without from date' do
+ let(:from) { nil }
+
+ it 'uses 000000 as suffix for first partition' do
+ expect(partition_name).to end_with("_000000")
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/database/partitioning/time_partition_spec.rb b/spec/lib/gitlab/database/partitioning/time_partition_spec.rb
index 45ed0d5fcb7..a7ab6e808cd 100644
--- a/spec/lib/gitlab/database/partitioning/time_partition_spec.rb
+++ b/spec/lib/gitlab/database/partitioning/time_partition_spec.rb
@@ -43,45 +43,14 @@ RSpec.describe Gitlab::Database::Partitioning::TimePartition, feature_category:
end
end
- describe '#partition_name' do
- subject { described_class.new(table, from, to, partition_name: partition_name).partition_name }
-
- let(:table) { 'foo' }
- let(:from) { '2020-04-01 00:00:00' }
- let(:to) { '2020-05-01 00:00:00' }
- let(:partition_name) { nil }
-
- it 'uses table as prefix' do
- expect(subject).to start_with(table)
- end
-
- it 'uses Year-Month (from) as suffix' do
- expect(subject).to end_with("_202004")
- end
-
- context 'without from date' do
- let(:from) { nil }
-
- it 'uses 000000 as suffix for first partition' do
- expect(subject).to end_with("_000000")
- end
- end
-
- context 'with partition name explicitly given' do
- let(:partition_name) { "foo_bar" }
-
- it 'uses given partition name' do
- expect(subject).to eq(partition_name)
- end
- end
- end
-
describe '#to_sql' do
- subject { described_class.new(table, from, to).to_sql }
+ subject { described_class.new(table, from, to, partition_name: partition_name).to_sql }
let(:table) { 'foo' }
let(:from) { '2020-04-01 00:00:00' }
let(:to) { '2020-05-01 00:00:00' }
+ let(:suffix) { '202004' }
+ let(:partition_name) { "#{table}_#{suffix}" }
it 'transforms to a CREATE TABLE statement' do
expect(subject).to eq(<<~SQL)
@@ -93,6 +62,7 @@ RSpec.describe Gitlab::Database::Partitioning::TimePartition, feature_category:
context 'without from date' do
let(:from) { nil }
+ let(:suffix) { '000000' }
it 'uses MINVALUE instead' do
expect(subject).to eq(<<~SQL)
@@ -140,8 +110,8 @@ RSpec.describe Gitlab::Database::Partitioning::TimePartition, feature_category:
expect_inequality(make_new, make_new(partition_name: 'different'))
end
- it 'nil partition_name is ignored if auto-generated matches' do
- expect_equality(make_new, make_new(partition_name: nil))
+ it 'raises en error if partition_name is nil' do
+ expect { make_new(partition_name: nil) }.to raise_error(ArgumentError, "partition_name required but none given")
end
end
@@ -150,24 +120,24 @@ RSpec.describe Gitlab::Database::Partitioning::TimePartition, feature_category:
it 'sorts by partition name, i.e. by month - MINVALUE partition first' do
partitions = [
- described_class.new(table, '2020-04-01', '2020-05-01'),
- described_class.new(table, '2020-02-01', '2020-03-01'),
- described_class.new(table, nil, '2020-02-01'),
- described_class.new(table, '2020-03-01', '2020-04-01')
+ described_class.new(table, '2020-04-01', '2020-05-01', partition_name: "#{table}_202004"),
+ described_class.new(table, '2020-02-01', '2020-03-01', partition_name: "#{table}_202002"),
+ described_class.new(table, nil, '2020-02-01', partition_name: "#{table}_000000"),
+ described_class.new(table, '2020-03-01', '2020-04-01', partition_name: "#{table}_202003")
]
expect(partitions.sort).to eq(
[
- described_class.new(table, nil, '2020-02-01'),
- described_class.new(table, '2020-02-01', '2020-03-01'),
- described_class.new(table, '2020-03-01', '2020-04-01'),
- described_class.new(table, '2020-04-01', '2020-05-01')
+ described_class.new(table, nil, '2020-02-01', partition_name: "#{table}_000000"),
+ described_class.new(table, '2020-02-01', '2020-03-01', partition_name: "#{table}_202002"),
+ described_class.new(table, '2020-03-01', '2020-04-01', partition_name: "#{table}_202003"),
+ described_class.new(table, '2020-04-01', '2020-05-01', partition_name: "#{table}_202004")
])
end
it 'returns nil for partitions of different tables' do
- one = described_class.new('foo', '2020-02-01', '2020-03-01')
- two = described_class.new('bar', '2020-02-01', '2020-03-01')
+ one = described_class.new('foo', '2020-02-01', '2020-03-01', partition_name: 'foo_202002')
+ two = described_class.new('bar', '2020-02-01', '2020-03-01', partition_name: 'bar_202002')
expect(one.<=>(two)).to be_nil
end
diff --git a/spec/lib/gitlab/diff/merge_request_suggestion_spec.rb b/spec/lib/gitlab/diff/merge_request_suggestion_spec.rb
index f9f6a3dba8d..38e38ac9d84 100644
--- a/spec/lib/gitlab/diff/merge_request_suggestion_spec.rb
+++ b/spec/lib/gitlab/diff/merge_request_suggestion_spec.rb
@@ -25,7 +25,8 @@ RSpec.describe Gitlab::Diff::MergeRequestSuggestion, feature_category: :vulnerab
end
let_it_be(:diff) { File.read(File.join(fixtures_folder, 'input.diff')) }
- let(:mr_suggestion) { described_class.new(diff, filepath, merge_request) }
+ let_it_be(:prepend_text) { nil }
+ let(:mr_suggestion) { described_class.new(diff, filepath, merge_request, prepend_text) }
subject(:attributes_hash) { mr_suggestion.note_attributes_hash }
@@ -34,6 +35,8 @@ RSpec.describe Gitlab::Diff::MergeRequestSuggestion, feature_category: :vulnerab
end
context 'when a valid diff is supplied' do
+ let_it_be(:suggestion) { File.read(File.join(fixtures_folder, 'suggestion.md')) }
+
it 'returns a correctly formatted suggestion request payload' do
position_payload = {
position_type: 'text',
@@ -51,7 +54,15 @@ RSpec.describe Gitlab::Diff::MergeRequestSuggestion, feature_category: :vulnerab
expect(attributes_hash[:noteable_type]).to eq(MergeRequest)
expect(attributes_hash[:noteable_id]).to eq(merge_request.id)
expect(attributes_hash[:position]).to eq(position_payload)
- expect(attributes_hash[:note]).to eq(File.read(File.join(fixtures_folder, 'suggestion.md')))
+ expect(attributes_hash[:note]).to eq(suggestion)
+ end
+
+ context 'when a prepend text is present' do
+ let_it_be(:prepend_text) { 'prepend text' }
+
+ it 'returns a correctly formatted suggestion request payload' do
+ expect(attributes_hash[:note]).to eq("#{prepend_text}\n#{suggestion}")
+ end
end
end
diff --git a/spec/models/ci/runner_manager_spec.rb b/spec/models/ci/runner_manager_spec.rb
index 903aeb4704a..4c1be14ddf8 100644
--- a/spec/models/ci/runner_manager_spec.rb
+++ b/spec/models/ci/runner_manager_spec.rb
@@ -216,6 +216,12 @@ RSpec.describe Ci::RunnerManager, feature_category: :fleet_visibility, type: :mo
it { is_expected.to contain_exactly(runner_manager_a1, runner_manager_a2) }
end
+ context 'with numeric id for single runner' do
+ let(:runner_arg) { runner_a.id }
+
+ it { is_expected.to contain_exactly(runner_manager_a1, runner_manager_a2) }
+ end
+
context 'with multiple runners' do
let(:runner_arg) { [runner_a, runner_b] }
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 4f0ef85fc16..1e7980de16a 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -540,6 +540,12 @@ RSpec.describe Namespace, feature_category: :groups_and_projects do
end
end
+ describe '.top_level' do
+ it 'includes correct namespaces' do
+ expect(described_class.top_level).to match_array([namespace, namespace1, namespace2])
+ end
+ end
+
describe '.by_root_id' do
it 'returns correct namespaces' do
expect(described_class.by_root_id(namespace1.id)).to match_array([namespace1, namespace1sub])
@@ -1458,26 +1464,33 @@ RSpec.describe Namespace, feature_category: :groups_and_projects do
end
end
- describe '.top_most' do
- let_it_be(:namespace) { create(:namespace) }
- let_it_be(:group) { create(:group) }
- let_it_be(:subgroup) { create(:group, parent: group) }
+ describe '.find_by_path_or_name' do
+ let_it_be(:namespace) { create(:namespace, name: 'WoW', path: 'woW') }
- subject { described_class.top_most.ids }
-
- it 'only contains root namespaces' do
- is_expected.to contain_exactly(group.id, namespace.id)
- end
+ it { expect(described_class.find_by_path_or_name('wow')).to eq(namespace) }
+ it { expect(described_class.find_by_path_or_name('WOW')).to eq(namespace) }
+ it { expect(described_class.find_by_path_or_name('unknown')).to be_nil }
end
- describe '.find_by_path_or_name' do
- before do
- @namespace = create(:namespace, name: 'WoW', path: 'woW')
+ describe '.find_top_level' do
+ # Due to the top level scope of this spec having a create of namespace, we'll avoid possible future flakiness here.
+ let(:namespace) { nil }
+
+ subject { described_class.find_top_level }
+
+ context 'when there are top level namespaces' do
+ # Order of creation matters here as we are only taking the first result and the single
+ # threaded FIFO order of creation in specs.
+ let_it_be(:sub_group) { create(:group, :nested) }
+ let_it_be(:another_parent_namespace) { create(:group) }
+ let(:parent_namespace) { sub_group.parent }
+
+ it { is_expected.to eq(parent_namespace) }
end
- it { expect(described_class.find_by_path_or_name('wow')).to eq(@namespace) }
- it { expect(described_class.find_by_path_or_name('WOW')).to eq(@namespace) }
- it { expect(described_class.find_by_path_or_name('unknown')).to eq(nil) }
+ context 'when there are no top level namespaces' do
+ it { is_expected.to be_nil }
+ end
end
describe ".clean_path" do