diff --git a/db/docs/merge_requests_approval_rules_approver_groups.yml b/db/docs/merge_requests_approval_rules_approver_groups.yml new file mode 100644 index 0000000000000000000000000000000000000000..65161adf4bee947fa257a2f486b2433eaac823d3 --- /dev/null +++ b/db/docs/merge_requests_approval_rules_approver_groups.yml @@ -0,0 +1,12 @@ +--- +table_name: merge_requests_approval_rules_approver_groups +classes: +- MergeRequests::ApprovalRulesApproverGroup +feature_categories: +- code_review_workflow +description: Stores approval groups for approval rules v2 +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/179877 +milestone: '17.10' +gitlab_schema: gitlab_main_cell +sharding_key: + group_id: namespaces diff --git a/db/docs/merge_requests_approval_rules_approver_users.yml b/db/docs/merge_requests_approval_rules_approver_users.yml new file mode 100644 index 0000000000000000000000000000000000000000..084da085100d6225f48f2c79c9800bd27e214972 --- /dev/null +++ b/db/docs/merge_requests_approval_rules_approver_users.yml @@ -0,0 +1,13 @@ +--- +table_name: merge_requests_approval_rules_approver_users +classes: + - MergeRequests::ApprovalRulesApproverUser +feature_categories: + - code_review_workflow +description: Stores approver users for approval rules v2 +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/179877 +milestone: '17.10' +gitlab_schema: gitlab_main_cell +sharding_key: + group_id: namespaces + project_id: projects diff --git a/db/migrate/20250123151841_create_merge_requests_approval_rules_approver_groups.rb b/db/migrate/20250123151841_create_merge_requests_approval_rules_approver_groups.rb new file mode 100644 index 0000000000000000000000000000000000000000..600d390e4f0e28b230c5c1679ef2f6c839e00629 --- /dev/null +++ b/db/migrate/20250123151841_create_merge_requests_approval_rules_approver_groups.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class CreateMergeRequestsApprovalRulesApproverGroups < Gitlab::Database::Migration[2.2] + milestone '17.10' + + def change + create_table :merge_requests_approval_rules_approver_groups do |t| + t.bigint :approval_rule_id, null: false + t.bigint :group_id, null: false + t.index :group_id + + t.timestamps_with_timezone null: false + end + + add_index( + :merge_requests_approval_rules_approver_groups, + %i[approval_rule_id group_id], + unique: true, + name: 'index_mrs_ars_approver_groups_on_ar_id_and_group_id' + ) + end +end diff --git a/db/migrate/20250123151859_create_merge_requests_approval_rules_approver_users.rb b/db/migrate/20250123151859_create_merge_requests_approval_rules_approver_users.rb new file mode 100644 index 0000000000000000000000000000000000000000..23255e8dbe2fb459d9c563b8432f5151ccb529af --- /dev/null +++ b/db/migrate/20250123151859_create_merge_requests_approval_rules_approver_users.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +class CreateMergeRequestsApprovalRulesApproverUsers < Gitlab::Database::Migration[2.2] + milestone '17.10' + + def change + create_table :merge_requests_approval_rules_approver_users do |t| + t.bigint :approval_rule_id, null: false + t.bigint :user_id, null: false + t.bigint :project_id, null: true + t.bigint :group_id, null: true + t.index :user_id + t.index :project_id, name: 'index_mrs_approval_rules_approver_users_on_project_id' + t.index :group_id + + t.timestamps_with_timezone null: false + end + + add_index( + :merge_requests_approval_rules_approver_users, + %i[approval_rule_id user_id], + unique: true, + name: 'index_mrs_ars_users_on_ar_id_and_user_id' + ) + end +end diff --git a/db/migrate/20250214133158_add_merge_requests_approval_rules_approver_groups_approval_rule_fk.rb b/db/migrate/20250214133158_add_merge_requests_approval_rules_approver_groups_approval_rule_fk.rb new file mode 100644 index 0000000000000000000000000000000000000000..0542cb9b6680d83245dfd102d52f405478df2a58 --- /dev/null +++ b/db/migrate/20250214133158_add_merge_requests_approval_rules_approver_groups_approval_rule_fk.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AddMergeRequestsApprovalRulesApproverGroupsApprovalRuleFk < Gitlab::Database::Migration[2.2] + milestone '17.10' + disable_ddl_transaction! + + def up + add_concurrent_foreign_key :merge_requests_approval_rules_approver_groups, :merge_requests_approval_rules, + column: :approval_rule_id, on_delete: :cascade + end + + def down + with_lock_retries do + remove_foreign_key :merge_requests_approval_rules_approver_groups, column: :approval_rule_id + end + end +end diff --git a/db/migrate/20250214133235_add_merge_requests_approval_rules_approver_groups_group_fk.rb b/db/migrate/20250214133235_add_merge_requests_approval_rules_approver_groups_group_fk.rb new file mode 100644 index 0000000000000000000000000000000000000000..699c8f6c37a6be73d928db60e592ea90b49d9163 --- /dev/null +++ b/db/migrate/20250214133235_add_merge_requests_approval_rules_approver_groups_group_fk.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AddMergeRequestsApprovalRulesApproverGroupsGroupFk < Gitlab::Database::Migration[2.2] + milestone '17.10' + disable_ddl_transaction! + + def up + add_concurrent_foreign_key :merge_requests_approval_rules_approver_groups, :namespaces, column: :group_id, + on_delete: :cascade + end + + def down + with_lock_retries do + remove_foreign_key :merge_requests_approval_rules_approver_groups, column: :group_id + end + end +end diff --git a/db/migrate/20250214134117_add_merge_requests_approval_rules_users_user_fk.rb b/db/migrate/20250214134117_add_merge_requests_approval_rules_users_user_fk.rb new file mode 100644 index 0000000000000000000000000000000000000000..5b0c1c1afa90ee36a0359df695bf7b928c74d69b --- /dev/null +++ b/db/migrate/20250214134117_add_merge_requests_approval_rules_users_user_fk.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AddMergeRequestsApprovalRulesUsersUserFk < Gitlab::Database::Migration[2.2] + milestone '17.10' + disable_ddl_transaction! + + def up + add_concurrent_foreign_key :merge_requests_approval_rules_approver_users, :users, column: :user_id, + on_delete: :cascade + end + + def down + with_lock_retries do + remove_foreign_key :merge_requests_approval_rules_approver_users, column: :user_id + end + end +end diff --git a/db/migrate/20250214134138_add_merge_requests_approval_rules_users_project_fk.rb b/db/migrate/20250214134138_add_merge_requests_approval_rules_users_project_fk.rb new file mode 100644 index 0000000000000000000000000000000000000000..7d6043024ad51e7334a72a24cbb4c92bc8b7a6e4 --- /dev/null +++ b/db/migrate/20250214134138_add_merge_requests_approval_rules_users_project_fk.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AddMergeRequestsApprovalRulesUsersProjectFk < Gitlab::Database::Migration[2.2] + milestone '17.10' + disable_ddl_transaction! + + def up + add_concurrent_foreign_key :merge_requests_approval_rules_approver_users, :projects, column: :project_id, + on_delete: :cascade + end + + def down + with_lock_retries do + remove_foreign_key :merge_requests_approval_rules_approver_users, column: :project_id + end + end +end diff --git a/db/migrate/20250214134202_add_merge_requests_approval_rules_users_approval_rule_fk.rb b/db/migrate/20250214134202_add_merge_requests_approval_rules_users_approval_rule_fk.rb new file mode 100644 index 0000000000000000000000000000000000000000..807affa8945512acf8da9b8bc6fd895096204162 --- /dev/null +++ b/db/migrate/20250214134202_add_merge_requests_approval_rules_users_approval_rule_fk.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AddMergeRequestsApprovalRulesUsersApprovalRuleFk < Gitlab::Database::Migration[2.2] + milestone '17.10' + disable_ddl_transaction! + + def up + add_concurrent_foreign_key :merge_requests_approval_rules_approver_users, :merge_requests_approval_rules, + column: :approval_rule_id, on_delete: :cascade + end + + def down + with_lock_retries do + remove_foreign_key :merge_requests_approval_rules_approver_users, column: :approval_rule_id + end + end +end diff --git a/db/migrate/20250225112059_add_merge_requests_approval_rules_users_group_fk.rb b/db/migrate/20250225112059_add_merge_requests_approval_rules_users_group_fk.rb new file mode 100644 index 0000000000000000000000000000000000000000..04bd8117d25285dd4f83206598971060f621abeb --- /dev/null +++ b/db/migrate/20250225112059_add_merge_requests_approval_rules_users_group_fk.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AddMergeRequestsApprovalRulesUsersGroupFk < Gitlab::Database::Migration[2.2] + milestone '17.10' + disable_ddl_transaction! + + def up + add_concurrent_foreign_key :merge_requests_approval_rules_approver_users, :namespaces, column: :group_id, + on_delete: :cascade + end + + def down + with_lock_retries do + remove_foreign_key :merge_requests_approval_rules_approver_users, column: :group_id + end + end +end diff --git a/db/migrate/20250225112409_add_merge_requests_approval_rules_users_multi_column_not_null_constraint.rb b/db/migrate/20250225112409_add_merge_requests_approval_rules_users_multi_column_not_null_constraint.rb new file mode 100644 index 0000000000000000000000000000000000000000..e7d408a90de5f598b3e7ca62a60039f701ca89b5 --- /dev/null +++ b/db/migrate/20250225112409_add_merge_requests_approval_rules_users_multi_column_not_null_constraint.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class AddMergeRequestsApprovalRulesUsersMultiColumnNotNullConstraint < Gitlab::Database::Migration[2.2] + milestone '17.10' + disable_ddl_transaction! + + def up + add_multi_column_not_null_constraint(:merge_requests_approval_rules_approver_users, :group_id, :project_id) + end + + def down + remove_multi_column_not_null_constraint(:merge_requests_approval_rules_approver_users, :group_id, :project_id) + end +end diff --git a/db/schema_migrations/20250123151841 b/db/schema_migrations/20250123151841 new file mode 100644 index 0000000000000000000000000000000000000000..9f18b9361428295c925a96ccced0da521dc81c18 --- /dev/null +++ b/db/schema_migrations/20250123151841 @@ -0,0 +1 @@ +3dddd1d5c9f162ebc7e1f1628dc0dbff5a6104587dbf3df962b15a1b47e44aff \ No newline at end of file diff --git a/db/schema_migrations/20250123151859 b/db/schema_migrations/20250123151859 new file mode 100644 index 0000000000000000000000000000000000000000..72ffdd36a09635e4eab629eb343c85ebb8472eb0 --- /dev/null +++ b/db/schema_migrations/20250123151859 @@ -0,0 +1 @@ +0231ed1f8496a8da0aa9e7941c188c15e94291d0462bcc4575c369ba7b5af2a5 \ No newline at end of file diff --git a/db/schema_migrations/20250214133158 b/db/schema_migrations/20250214133158 new file mode 100644 index 0000000000000000000000000000000000000000..6f782e65b76f3173df8700b2ff5132843491f5b5 --- /dev/null +++ b/db/schema_migrations/20250214133158 @@ -0,0 +1 @@ +71751d3c5b490ec202be7fc4370216c047944454284df1ce9e774ea218cb6cc1 \ No newline at end of file diff --git a/db/schema_migrations/20250214133235 b/db/schema_migrations/20250214133235 new file mode 100644 index 0000000000000000000000000000000000000000..110f55f6761fad7fde801174f2887adfa9f701cc --- /dev/null +++ b/db/schema_migrations/20250214133235 @@ -0,0 +1 @@ +0a852fc3ae3e8fc892dda967727b0ce7629b38c2ce84c050e4c5d886de6d43dd \ No newline at end of file diff --git a/db/schema_migrations/20250214134117 b/db/schema_migrations/20250214134117 new file mode 100644 index 0000000000000000000000000000000000000000..b3d95d79c3f60a2b4ea44d3f37f89910751754b3 --- /dev/null +++ b/db/schema_migrations/20250214134117 @@ -0,0 +1 @@ +af99cf986e829d045cf5e5ad11b72d40378cb90a956a97c1549db8806953a05a \ No newline at end of file diff --git a/db/schema_migrations/20250214134138 b/db/schema_migrations/20250214134138 new file mode 100644 index 0000000000000000000000000000000000000000..94829569314e5ce628e581fe188ca6e064a145ac --- /dev/null +++ b/db/schema_migrations/20250214134138 @@ -0,0 +1 @@ +3b18c1137fa082dddc82012f80750ec36266568d11bc8bd7160d8327d1153267 \ No newline at end of file diff --git a/db/schema_migrations/20250214134202 b/db/schema_migrations/20250214134202 new file mode 100644 index 0000000000000000000000000000000000000000..393f746b24b7a7dde30044d8142cf2a51fd2af86 --- /dev/null +++ b/db/schema_migrations/20250214134202 @@ -0,0 +1 @@ +fe84c9693c07d7b5b2b771094693597ed538dbc67c1f22d4204ae807f0fc9078 \ No newline at end of file diff --git a/db/schema_migrations/20250225112059 b/db/schema_migrations/20250225112059 new file mode 100644 index 0000000000000000000000000000000000000000..2c12efce18973cac4b9a82f39a785677e284fce1 --- /dev/null +++ b/db/schema_migrations/20250225112059 @@ -0,0 +1 @@ +f7604e3c541ec4b7b5e186c76365908c7c26035ea69f003cdf27d84d937e8180 \ No newline at end of file diff --git a/db/schema_migrations/20250225112409 b/db/schema_migrations/20250225112409 new file mode 100644 index 0000000000000000000000000000000000000000..447d5a5a211d7de054b3688c4226c8e52d062d32 --- /dev/null +++ b/db/schema_migrations/20250225112409 @@ -0,0 +1 @@ +68a2b468a90e4116867a7460660177301bd506107d2fafc41f0b63d18f7e5f8a \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 0f80bc724b0fd05b3ff88dc1a5ff8ff0b17b2fb3..28da8ed7bbf4d3a13526220e0b479a8da26cbd94 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -16404,6 +16404,43 @@ CREATE TABLE merge_requests_approval_rules ( CONSTRAINT check_c7c36145b7 CHECK ((char_length(name) <= 255)) ); +CREATE TABLE merge_requests_approval_rules_approver_groups ( + id bigint NOT NULL, + approval_rule_id bigint NOT NULL, + group_id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE merge_requests_approval_rules_approver_groups_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE merge_requests_approval_rules_approver_groups_id_seq OWNED BY merge_requests_approval_rules_approver_groups.id; + +CREATE TABLE merge_requests_approval_rules_approver_users ( + id bigint NOT NULL, + approval_rule_id bigint NOT NULL, + user_id bigint NOT NULL, + project_id bigint, + group_id bigint, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL, + CONSTRAINT check_ccdbd0e37e CHECK ((num_nonnulls(group_id, project_id) = 1)) +); + +CREATE SEQUENCE merge_requests_approval_rules_approver_users_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE merge_requests_approval_rules_approver_users_id_seq OWNED BY merge_requests_approval_rules_approver_users.id; + CREATE TABLE merge_requests_approval_rules_groups ( id bigint NOT NULL, approval_rule_id bigint NOT NULL, @@ -25829,6 +25866,10 @@ ALTER TABLE ONLY merge_requests ALTER COLUMN id SET DEFAULT nextval('merge_reque ALTER TABLE ONLY merge_requests_approval_rules ALTER COLUMN id SET DEFAULT nextval('merge_requests_approval_rules_id_seq'::regclass); +ALTER TABLE ONLY merge_requests_approval_rules_approver_groups ALTER COLUMN id SET DEFAULT nextval('merge_requests_approval_rules_approver_groups_id_seq'::regclass); + +ALTER TABLE ONLY merge_requests_approval_rules_approver_users ALTER COLUMN id SET DEFAULT nextval('merge_requests_approval_rules_approver_users_id_seq'::regclass); + ALTER TABLE ONLY merge_requests_approval_rules_groups ALTER COLUMN id SET DEFAULT nextval('merge_requests_approval_rules_groups_id_seq'::regclass); ALTER TABLE ONLY merge_requests_approval_rules_merge_requests ALTER COLUMN id SET DEFAULT nextval('merge_requests_approval_rules_merge_requests_id_seq'::regclass); @@ -28372,6 +28413,12 @@ ALTER TABLE ONLY merge_request_reviewers ALTER TABLE ONLY merge_request_user_mentions ADD CONSTRAINT merge_request_user_mentions_pkey PRIMARY KEY (id); +ALTER TABLE ONLY merge_requests_approval_rules_approver_groups + ADD CONSTRAINT merge_requests_approval_rules_approver_groups_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY merge_requests_approval_rules_approver_users + ADD CONSTRAINT merge_requests_approval_rules_approver_users_pkey PRIMARY KEY (id); + ALTER TABLE ONLY merge_requests_approval_rules_groups ADD CONSTRAINT merge_requests_approval_rules_groups_pkey PRIMARY KEY (id); @@ -33849,6 +33896,12 @@ CREATE INDEX index_merge_request_reviewers_on_user_id ON merge_request_reviewers CREATE UNIQUE INDEX index_merge_request_user_mentions_on_note_id ON merge_request_user_mentions USING btree (note_id) WHERE (note_id IS NOT NULL); +CREATE INDEX index_merge_requests_approval_rules_approver_groups_on_group_id ON merge_requests_approval_rules_approver_groups USING btree (group_id); + +CREATE INDEX index_merge_requests_approval_rules_approver_users_on_group_id ON merge_requests_approval_rules_approver_users USING btree (group_id); + +CREATE INDEX index_merge_requests_approval_rules_approver_users_on_user_id ON merge_requests_approval_rules_approver_users USING btree (user_id); + CREATE INDEX index_merge_requests_approval_rules_groups_on_group_id ON merge_requests_approval_rules_groups USING btree (group_id); CREATE INDEX index_merge_requests_approval_rules_on_group_id ON merge_requests_approval_rules USING btree (group_id); @@ -34029,18 +34082,24 @@ CREATE INDEX index_mr_metrics_on_target_project_id_merged_at_nulls_last ON merge CREATE INDEX index_mr_metrics_on_target_project_id_merged_at_time_to_merge ON merge_request_metrics USING btree (target_project_id, merged_at, created_at) WHERE (merged_at > created_at); +CREATE INDEX index_mrs_approval_rules_approver_users_on_project_id ON merge_requests_approval_rules_approver_users USING btree (project_id); + CREATE INDEX index_mrs_approval_rules_mrs_on_mr_id ON merge_requests_approval_rules_merge_requests USING btree (merge_request_id); CREATE INDEX index_mrs_approval_rules_mrs_on_project_id ON merge_requests_approval_rules_merge_requests USING btree (project_id); CREATE INDEX index_mrs_approval_rules_projects_on_project_id ON merge_requests_approval_rules_projects USING btree (project_id); +CREATE UNIQUE INDEX index_mrs_ars_approver_groups_on_ar_id_and_group_id ON merge_requests_approval_rules_approver_groups USING btree (approval_rule_id, group_id); + CREATE UNIQUE INDEX index_mrs_ars_groups_on_ar_id_and_group_id ON merge_requests_approval_rules_groups USING btree (approval_rule_id, group_id); CREATE UNIQUE INDEX index_mrs_ars_mrs_on_ar_id_and_mr_id ON merge_requests_approval_rules_merge_requests USING btree (approval_rule_id, merge_request_id); CREATE UNIQUE INDEX index_mrs_ars_projects_on_ar_id_and_project_id ON merge_requests_approval_rules_projects USING btree (approval_rule_id, project_id); +CREATE UNIQUE INDEX index_mrs_ars_users_on_ar_id_and_user_id ON merge_requests_approval_rules_approver_users USING btree (approval_rule_id, user_id); + CREATE INDEX index_namespace_admin_notes_on_namespace_id ON namespace_admin_notes USING btree (namespace_id); CREATE UNIQUE INDEX index_namespace_aggregation_schedules_on_namespace_id ON namespace_aggregation_schedules USING btree (namespace_id); @@ -39149,6 +39208,9 @@ ALTER TABLE ONLY zoekt_enabled_namespaces ALTER TABLE ONLY import_placeholder_memberships ADD CONSTRAINT fk_1f4659deee FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules_approver_groups + ADD CONSTRAINT fk_1f8729ebf4 FOREIGN KEY (approval_rule_id) REFERENCES merge_requests_approval_rules(id) ON DELETE CASCADE; + ALTER TABLE ONLY epics ADD CONSTRAINT fk_1fbed67632 FOREIGN KEY (start_date_sourcing_milestone_id) REFERENCES milestones(id) ON DELETE SET NULL; @@ -39428,6 +39490,9 @@ ALTER TABLE ONLY security_orchestration_policy_rule_schedules ALTER TABLE ONLY abuse_reports ADD CONSTRAINT fk_3fe6467b93 FOREIGN KEY (assignee_id) REFERENCES users(id) ON DELETE SET NULL; +ALTER TABLE ONLY merge_requests_approval_rules_approver_users + ADD CONSTRAINT fk_4025feea5b FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; + ALTER TABLE ONLY protected_environment_approval_rules ADD CONSTRAINT fk_405568b491 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE; @@ -39584,6 +39649,9 @@ ALTER TABLE ONLY abuse_report_notes ALTER TABLE ONLY approval_merge_request_rules ADD CONSTRAINT fk_5822f009ea FOREIGN KEY (security_orchestration_policy_configuration_id) REFERENCES security_orchestration_policy_configurations(id) ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules_approver_users + ADD CONSTRAINT fk_582e5f36e8 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; + ALTER TABLE ONLY deploy_keys_projects ADD CONSTRAINT fk_58a901ca7e FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; @@ -39704,6 +39772,9 @@ ALTER TABLE p_ci_builds ALTER TABLE ONLY routes ADD CONSTRAINT fk_679ff8213d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE NOT VALID; +ALTER TABLE ONLY merge_requests_approval_rules_approver_groups + ADD CONSTRAINT fk_67fa93ad4b FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE; + ALTER TABLE ONLY ai_conversation_messages ADD CONSTRAINT fk_68774ec148 FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE; @@ -39761,6 +39832,9 @@ ALTER TABLE ONLY packages_conan_package_references ALTER TABLE ONLY subscription_user_add_on_assignments ADD CONSTRAINT fk_724c2df9a8 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules_approver_users + ADD CONSTRAINT fk_725cca295c FOREIGN KEY (approval_rule_id) REFERENCES merge_requests_approval_rules(id) ON DELETE CASCADE; + ALTER TABLE ONLY zentao_tracker_data ADD CONSTRAINT fk_72a0e59cd8 FOREIGN KEY (instance_integration_id) REFERENCES instance_integrations(id) ON DELETE CASCADE; @@ -39914,6 +39988,9 @@ ALTER TABLE ONLY import_export_uploads ALTER TABLE ONLY packages_npm_metadata ADD CONSTRAINT fk_83625a27c0 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules_approver_users + ADD CONSTRAINT fk_836efc3006 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE; + ALTER TABLE ONLY push_rules ADD CONSTRAINT fk_83b29894de FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; diff --git a/ee/app/models/merge_requests/approval_rule.rb b/ee/app/models/merge_requests/approval_rule.rb index 8f002d21655a8e084036c2a4b5a9b99308d79e5f..5329815957c2b0ab3fc03e00df3e5894a8adb26e 100644 --- a/ee/app/models/merge_requests/approval_rule.rb +++ b/ee/app/models/merge_requests/approval_rule.rb @@ -28,6 +28,12 @@ class ApprovalRule < ApplicationRecord has_one :approval_rules_merge_request, inverse_of: :approval_rule has_one :merge_request, through: :approval_rules_merge_request + has_many :approval_rules_users + has_many :users, through: :approval_rules_users + + has_many :approval_rules_approver_groups + has_many :approver_groups, through: :approval_rules_approver_groups, source: :group + validate :ensure_single_sharding_key with_options validate: true do diff --git a/ee/app/models/merge_requests/approval_rules_approver_group.rb b/ee/app/models/merge_requests/approval_rules_approver_group.rb new file mode 100644 index 0000000000000000000000000000000000000000..3eaa95c5b1ce07d43c5a3d2ffcfbe4100ec73826 --- /dev/null +++ b/ee/app/models/merge_requests/approval_rules_approver_group.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module MergeRequests + class ApprovalRulesApproverGroup < ApplicationRecord + self.table_name = 'merge_requests_approval_rules_approver_groups' + + belongs_to :approval_rule, class_name: 'MergeRequests::ApprovalRule' + belongs_to :group + end +end diff --git a/ee/app/models/merge_requests/approval_rules_approver_user.rb b/ee/app/models/merge_requests/approval_rules_approver_user.rb new file mode 100644 index 0000000000000000000000000000000000000000..cbdd4e92a460e14c0b91fa1da46cc91a7043779c --- /dev/null +++ b/ee/app/models/merge_requests/approval_rules_approver_user.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module MergeRequests + class ApprovalRulesApproverUser < ApplicationRecord + self.table_name = 'merge_requests_approval_rules_approver_users' + + belongs_to :approval_rule, class_name: 'MergeRequests::ApprovalRule' + belongs_to :user + + before_validation :set_sharding_key + + private + + def set_sharding_key + return self.group_id = approval_rule.group_id if approval_rule.originates_from_group? + + self.project_id = approval_rule.project_id + end + end +end diff --git a/ee/spec/factories/merge_requests/approval_rules.rb b/ee/spec/factories/merge_requests/approval_rules.rb index a56d74503f402a283ff9c9d109b20fde33ba907f..0abcabbfbb6a3037bfd633a8e3ca08a6d4a9b0f8 100644 --- a/ee/spec/factories/merge_requests/approval_rules.rb +++ b/ee/spec/factories/merge_requests/approval_rules.rb @@ -5,10 +5,21 @@ sequence(:name) { |n| "Approval Rule #{n}" } approvals_required { 2 } rule_type { 0 } - origin { 0 } trait :with_source_rule do association :source_rule, factory: :merge_requests_approval_rule end + + trait :from_group do + origin { 0 } + end + + trait :from_project do + origin { 1 } + end + + trait :from_merge_request do + origin { 2 } + end end end diff --git a/ee/spec/factories/merge_requests/approval_rules_approver_groups.rb b/ee/spec/factories/merge_requests/approval_rules_approver_groups.rb new file mode 100644 index 0000000000000000000000000000000000000000..0dd53bb01d0312d7bcad3afe598974f500fc5ab7 --- /dev/null +++ b/ee/spec/factories/merge_requests/approval_rules_approver_groups.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :merge_requests_approval_rules_approver_group, class: 'MergeRequests::ApprovalRulesApproverGroup' do + association :approval_rule, factory: :merge_requests_approval_rule + association :group, factory: :group + end +end diff --git a/ee/spec/factories/merge_requests/approval_rules_approver_users.rb b/ee/spec/factories/merge_requests/approval_rules_approver_users.rb new file mode 100644 index 0000000000000000000000000000000000000000..dafce8ef10a4c0359acc1b638659e4daded5ed99 --- /dev/null +++ b/ee/spec/factories/merge_requests/approval_rules_approver_users.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :merge_requests_approval_rules_user, class: 'MergeRequests::ApprovalRulesApproverUser' do + association :approval_rule, factory: :merge_requests_approval_rule + association :user, factory: :user + end +end diff --git a/ee/spec/models/merge_requests/approval_rules_approver_group_spec.rb b/ee/spec/models/merge_requests/approval_rules_approver_group_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..0cb13db7288951fdd29670f5782026ee4c45bebb --- /dev/null +++ b/ee/spec/models/merge_requests/approval_rules_approver_group_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe MergeRequests::ApprovalRulesApproverGroup, type: :model, feature_category: :code_review_workflow do + describe 'associations' do + it { is_expected.to belong_to(:approval_rule) } + it { is_expected.to belong_to(:group) } + end +end diff --git a/ee/spec/models/merge_requests/approval_rules_approver_user_spec.rb b/ee/spec/models/merge_requests/approval_rules_approver_user_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..a2cae5d9ff450509617b50676b94f83652e2e87e --- /dev/null +++ b/ee/spec/models/merge_requests/approval_rules_approver_user_spec.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe MergeRequests::ApprovalRulesApproverUser, type: :model, feature_category: :code_review_workflow do + describe '#set_sharding_key' do + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group) } + let(:approval_rule) { create(:merge_requests_approval_rule, :from_group, group_id: group.id) } + + subject(:approval_rules_user) do + create(:merge_requests_approval_rules_user, user: user, approval_rule: approval_rule) + end + + describe '#set_sharding_key' do + context 'when approval rule origin is group' do + it 'sets the group_id' do + expect(approval_rules_user.group_id).to eq(group.id) + end + + it 'does not set the project_id' do + expect(approval_rules_user.project_id).to be_nil + end + end + + context 'when approval rule origin is not group' do + let_it_be(:project) { create(:project) } + let(:origin) { :from_project } + let(:approval_rule) { create(:merge_requests_approval_rule, origin, project_id: project.id) } + + context 'when approval rule origin is project' do + it 'sets the project_id' do + expect(approval_rules_user.project_id).to eq(project.id) + end + + it 'does not set the group_id' do + expect(approval_rules_user.group_id).to be_nil + end + end + + context 'when approval rule origin is merge request' do + let(:origin) { :from_merge_request } + + it 'sets the project_id' do + expect(approval_rules_user.project_id).to eq(project.id) + end + + it 'does not set the group_id' do + expect(approval_rules_user.group_id).to be_nil + end + end + end + end + end +end