diff --git a/db/docs/merge_requests_approval_rules.yml b/db/docs/merge_requests_approval_rules.yml new file mode 100644 index 0000000000000000000000000000000000000000..fc3ebd5900c59b062f6f3b2cfe05297767c47bfb --- /dev/null +++ b/db/docs/merge_requests_approval_rules.yml @@ -0,0 +1,13 @@ +--- +table_name: merge_requests_approval_rules +classes: + - MergeRequests::ApprovalRule +feature_categories: + - code_review_workflow +description: Main table that stores information about approval rules v2. +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/179839 +milestone: '17.9' +gitlab_schema: gitlab_main_cell +sharding_key: + group_id: namespaces + project_id: projects diff --git a/db/docs/merge_requests_approval_rules_groups.yml b/db/docs/merge_requests_approval_rules_groups.yml new file mode 100644 index 0000000000000000000000000000000000000000..cdc7d0a6fd580a513e5bbe0c062b4d8908f4f07a --- /dev/null +++ b/db/docs/merge_requests_approval_rules_groups.yml @@ -0,0 +1,12 @@ +--- +table_name: merge_requests_approval_rules_groups +classes: + - MergeRequests::ApprovalRulesGroup +feature_categories: + - code_review_workflow +description: Stores relationship between approval rules v2 and groups +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/179257 +milestone: '17.9' +gitlab_schema: gitlab_main_cell +sharding_key: + group_id: namespaces diff --git a/db/docs/merge_requests_approval_rules_merge_requests.yml b/db/docs/merge_requests_approval_rules_merge_requests.yml new file mode 100644 index 0000000000000000000000000000000000000000..d4c33aa7b67731e4166afc59aa735253c333dd4f --- /dev/null +++ b/db/docs/merge_requests_approval_rules_merge_requests.yml @@ -0,0 +1,19 @@ +--- +table_name: merge_requests_approval_rules_merge_requests +classes: + - MergeRequests::ApprovalRulesMergeRequest +feature_categories: + - code_review_workflow +description: Stores relationship between approval rules v2 and merge requests +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/179257 +milestone: '17.9' +gitlab_schema: gitlab_main_cell +desired_sharding_key: + project_id: + references: projects + backfill_via: + parent: + foreign_key: merge_request_id + table: merge_requests + sharding_key: target_project_id + belongs_to: merge_request diff --git a/db/docs/merge_requests_approval_rules_projects.yml b/db/docs/merge_requests_approval_rules_projects.yml new file mode 100644 index 0000000000000000000000000000000000000000..97c93a5b8a97278d745fbf805bd9614ddf722d3c --- /dev/null +++ b/db/docs/merge_requests_approval_rules_projects.yml @@ -0,0 +1,12 @@ +--- +table_name: merge_requests_approval_rules_projects +classes: + - MergeRequests::ApprovalRulesProject +feature_categories: + - code_review_workflow +description: Stores relationship between approval rules v2 and projects +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/179257 +milestone: '17.9' +gitlab_schema: gitlab_main_cell +sharding_key: + project_id: projects diff --git a/db/docs/merge_requests_approval_rules_protected_branches.yml b/db/docs/merge_requests_approval_rules_protected_branches.yml new file mode 100644 index 0000000000000000000000000000000000000000..df48dd43f10b3c49610b452181b4d1d18a225020 --- /dev/null +++ b/db/docs/merge_requests_approval_rules_protected_branches.yml @@ -0,0 +1,27 @@ +--- +table_name: merge_requests_approval_rules_protected_branches +classes: + - MergeRequests::ApprovalRulesProtectedBranch +feature_categories: + - code_review_workflow +description: Stores relationship between approval rules v2 and protected branches +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/179257 +milestone: '17.9' +gitlab_schema: gitlab_main_cell +desired_sharding_key: + project_id: + references: projects + backfill_via: + parent: + foreign_key: approval_rule_id + table: merge_requests_approval_rules + sharding_key: project_id + belongs_to: approval_rule + namespace_id: + references: namespaces + backfill_via: + parent: + foreign_key: approval_rule_id + table: merge_requests_approval_rules + sharding_key: group_id + belongs_to: approval_rule diff --git a/db/docs/merge_requests_approval_rules_security_policy_links.yml b/db/docs/merge_requests_approval_rules_security_policy_links.yml new file mode 100644 index 0000000000000000000000000000000000000000..7c2fcfc47f247bf906a927ba488411ac01d8708e --- /dev/null +++ b/db/docs/merge_requests_approval_rules_security_policy_links.yml @@ -0,0 +1,27 @@ +--- +table_name: merge_requests_approval_rules_security_policy_links +classes: + - MergeRequests::ApprovalRulesSecurityPolicyLink +feature_categories: + - code_review_workflow +description: Stores relationship between approval rules v2 and security policies +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/179257 +milestone: '17.9' +gitlab_schema: gitlab_main_cell +desired_sharding_key: + project_id: + references: projects + backfill_via: + parent: + foreign_key: approval_rule_id + table: merge_requests_approval_rules + sharding_key: project_id + belongs_to: approval_rule + namespace_id: + references: namespaces + backfill_via: + parent: + foreign_key: approval_rule_id + table: merge_requests_approval_rules + sharding_key: group_id + belongs_to: approval_rule diff --git a/db/docs/merge_requests_approval_rules_user_groups.yml b/db/docs/merge_requests_approval_rules_user_groups.yml new file mode 100644 index 0000000000000000000000000000000000000000..679ad73da157fbe639ee98fc6578235dfd58f9c1 --- /dev/null +++ b/db/docs/merge_requests_approval_rules_user_groups.yml @@ -0,0 +1,28 @@ +--- +table_name: merge_requests_approval_rules_user_groups +classes: +- MergeRequests::ApprovalRulesUserGroup +- MergeRequests::ApprovalRulesUserGroups +feature_categories: +- code_review_workflow +description: Stores approval groups for approval rules v2 +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/179257 +milestone: '17.9' +gitlab_schema: gitlab_main_cell +desired_sharding_key: + project_id: + references: projects + backfill_via: + parent: + foreign_key: approval_rule_id + table: merge_requests_approval_rules + sharding_key: project_id + belongs_to: approval_rule + namespace_id: + references: namespaces + backfill_via: + parent: + foreign_key: approval_rule_id + table: merge_requests_approval_rules + sharding_key: group_id + belongs_to: approval_rule diff --git a/db/docs/merge_requests_approval_rules_users.yml b/db/docs/merge_requests_approval_rules_users.yml new file mode 100644 index 0000000000000000000000000000000000000000..db893f32ff0bcc45806d00861b79a6caaa4bc611 --- /dev/null +++ b/db/docs/merge_requests_approval_rules_users.yml @@ -0,0 +1,27 @@ +--- +table_name: merge_requests_approval_rules_users +classes: + - MergeRequests::ApprovalRulesUser +feature_categories: + - code_review_workflow +description: Stores approval users for approval rules v2 +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/179257 +milestone: '17.9' +gitlab_schema: gitlab_main_cell +desired_sharding_key: + project_id: + references: projects + backfill_via: + parent: + foreign_key: approval_rule_id + table: merge_requests_approval_rules + sharding_key: project_id + belongs_to: approval_rule + namespace_id: + references: namespaces + backfill_via: + parent: + foreign_key: approval_rule_id + table: merge_requests_approval_rules + sharding_key: group_id + belongs_to: approval_rule diff --git a/db/migrate/20250123151650_create_merge_requests_approval_rules.rb b/db/migrate/20250123151650_create_merge_requests_approval_rules.rb new file mode 100644 index 0000000000000000000000000000000000000000..2a099bb854fef6c55f7896dd6f63e8f0d03c8647 --- /dev/null +++ b/db/migrate/20250123151650_create_merge_requests_approval_rules.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +class CreateMergeRequestsApprovalRules < Gitlab::Database::Migration[2.2] + milestone '17.9' + + def change + create_table :merge_requests_approval_rules do |t| + t.integer :approvals_required, null: false, default: 0 + t.text :name, limit: 255, null: false + t.integer :rule_type, null: false, default: 0, limit: 2 + t.integer :origin, null: false, default: 0, limit: 2 + t.belongs_to( + :project, + foreign_key: { to_table: :projects, on_delete: :cascade }, + null: true + ) + t.belongs_to( + :group, + foreign_key: { to_table: :namespaces, on_delete: :cascade }, + null: true + ) + t.belongs_to( + :source_rule, + foreign_key: { to_table: :merge_requests_approval_rules, on_delete: :nullify }, + index: { name: 'index_approval_rules_on_source_rule_id' }, + null: true + ) + t.timestamps_with_timezone null: false + end + end +end diff --git a/db/migrate/20250123151708_create_merge_requests_approval_rules_groups.rb b/db/migrate/20250123151708_create_merge_requests_approval_rules_groups.rb new file mode 100644 index 0000000000000000000000000000000000000000..3185c73255bdd3591672eead5d7abb36382a54bb --- /dev/null +++ b/db/migrate/20250123151708_create_merge_requests_approval_rules_groups.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +class CreateMergeRequestsApprovalRulesGroups < Gitlab::Database::Migration[2.2] + milestone '17.9' + + def change + create_table :merge_requests_approval_rules_groups do |t| # -- Some Reason + t.belongs_to( + :approval_rule, + foreign_key: { to_table: :merge_requests_approval_rules }, + index: { name: 'index_approval_rules_groups_on_approval_rule_id' }, + null: false + ) + t.belongs_to( + :group, + foreign_key: { to_table: :namespaces, on_delete: :cascade }, + null: false + ) + + t.timestamps_with_timezone null: false + end + end +end diff --git a/db/migrate/20250123151726_create_merge_requests_approval_rules_merge_requests.rb b/db/migrate/20250123151726_create_merge_requests_approval_rules_merge_requests.rb new file mode 100644 index 0000000000000000000000000000000000000000..6a952fd65eb209d6fb078b51f749101da4938ff3 --- /dev/null +++ b/db/migrate/20250123151726_create_merge_requests_approval_rules_merge_requests.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class CreateMergeRequestsApprovalRulesMergeRequests < Gitlab::Database::Migration[2.2] + milestone '17.9' + + def change + create_table :merge_requests_approval_rules_merge_requests do |t| # -- Some Reason + t.belongs_to( + :approval_rule, + foreign_key: { to_table: :merge_requests_approval_rules }, + index: { name: 'index_approval_rules_merge_requests_on_approval_rule_id' }, + null: false + ) + + t.belongs_to( + :merge_request, + foreign_key: { to_table: :merge_requests, on_delete: :cascade }, + index: { name: 'index_approval_rules_merge_requests_on_merge_request_id' }, + null: false + ) + + t.timestamps_with_timezone null: false + end + end +end diff --git a/db/migrate/20250123151745_create_merge_requests_approval_rules_projects.rb b/db/migrate/20250123151745_create_merge_requests_approval_rules_projects.rb new file mode 100644 index 0000000000000000000000000000000000000000..691772767fe62ca9c3ec16874ab998f5883c91d4 --- /dev/null +++ b/db/migrate/20250123151745_create_merge_requests_approval_rules_projects.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class CreateMergeRequestsApprovalRulesProjects < Gitlab::Database::Migration[2.2] + milestone '17.9' + + def change + create_table :merge_requests_approval_rules_projects do |t| # -- Some Reason + t.belongs_to( + :approval_rule, + foreign_key: { to_table: :merge_requests_approval_rules }, + index: { name: 'index_approval_rules_project_on_approval_rule_id' }, + null: false + ) + t.belongs_to( + :project, + foreign_key: { to_table: :projects, on_delete: :cascade }, + index: { name: 'index_approval_rules_project_on_project_id' }, + null: false + ) + + t.timestamps_with_timezone null: false + end + end +end diff --git a/db/migrate/20250123151804_create_merge_requests_approval_rules_protected_branches.rb b/db/migrate/20250123151804_create_merge_requests_approval_rules_protected_branches.rb new file mode 100644 index 0000000000000000000000000000000000000000..c338ab2e0ec20430735bcba4d598f5b1dee0d849 --- /dev/null +++ b/db/migrate/20250123151804_create_merge_requests_approval_rules_protected_branches.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class CreateMergeRequestsApprovalRulesProtectedBranches < Gitlab::Database::Migration[2.2] + milestone '17.9' + + def change + create_table :merge_requests_approval_rules_protected_branches do |t| # -- Some Reason + t.belongs_to( + :approval_rule, + foreign_key: { to_table: :merge_requests_approval_rules }, + index: { name: 'index_approval_rules_pb_on_approval_rule_id' }, + null: false + ) + t.belongs_to( + :protected_branch, + foreign_key: { to_table: :protected_branches, on_delete: :cascade }, + index: { name: 'index_mr_approval_rules_pb_on_protected_branch_id' }, + null: false + ) + + t.timestamps_with_timezone null: false + end + end +end diff --git a/db/migrate/20250123151822_create_merge_requests_approval_rules_security_policy_links.rb b/db/migrate/20250123151822_create_merge_requests_approval_rules_security_policy_links.rb new file mode 100644 index 0000000000000000000000000000000000000000..6183db992fd78b3419d9ae95b2c0d5d35f0c2554 --- /dev/null +++ b/db/migrate/20250123151822_create_merge_requests_approval_rules_security_policy_links.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class CreateMergeRequestsApprovalRulesSecurityPolicyLinks < Gitlab::Database::Migration[2.2] + milestone '17.9' + + def change + create_table :merge_requests_approval_rules_security_policy_links do |t| # -- Some Reason + t.belongs_to( + :approval_rule, + foreign_key: { to_table: :merge_requests_approval_rules }, + index: { name: 'index_approval_rules_sp_on_approval_rule_id' }, + null: false + ) + t.belongs_to( + :security_policy, + foreign_key: { to_table: :security_policies, on_delete: :cascade }, + index: { name: 'index_approval_rules_on_approval_rule_sp_id' }, + null: false + ) + + t.timestamps_with_timezone null: false + end + end +end diff --git a/db/migrate/20250123151841_create_merge_requests_approval_rules_user_groups.rb b/db/migrate/20250123151841_create_merge_requests_approval_rules_user_groups.rb new file mode 100644 index 0000000000000000000000000000000000000000..84bf42b2a5651759fcd10feff157dee7f1ea51c2 --- /dev/null +++ b/db/migrate/20250123151841_create_merge_requests_approval_rules_user_groups.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +class CreateMergeRequestsApprovalRulesUserGroups < Gitlab::Database::Migration[2.2] + milestone '17.9' + + def change + create_table :merge_requests_approval_rules_user_groups do |t| # -- Some Reason + t.belongs_to( + :approval_rule, + foreign_key: { to_table: :merge_requests_approval_rules }, + index: { name: 'index_approval_rules_user_groups_on_approval_rule_id' }, + null: false + ) + t.belongs_to( + :group, + foreign_key: { to_table: :namespaces, on_delete: :cascade }, + null: false + ) + + t.timestamps_with_timezone null: false + end + end +end diff --git a/db/migrate/20250123151859_create_merge_requests_approval_rules_users.rb b/db/migrate/20250123151859_create_merge_requests_approval_rules_users.rb new file mode 100644 index 0000000000000000000000000000000000000000..2636d4a4ddc7d84c785ed1064ff3ba6a674da2b1 --- /dev/null +++ b/db/migrate/20250123151859_create_merge_requests_approval_rules_users.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +class CreateMergeRequestsApprovalRulesUsers < Gitlab::Database::Migration[2.2] + milestone '17.9' + + def change + create_table :merge_requests_approval_rules_users do |t| # -- Some Reason + t.belongs_to( + :approval_rule, + foreign_key: { to_table: :merge_requests_approval_rules, on_delete: :cascade }, + index: { name: 'index_approval_rules_users_on_approval_rule_id' }, + null: false + ) + t.belongs_to( + :user, + foreign_key: { to_table: :users, on_delete: :cascade }, + null: false + ) + + t.timestamps_with_timezone null: false + end + end +end diff --git a/db/migrate/20250130110721_add_merge_requests_approval_rules_multi_column_not_null_constraint.rb b/db/migrate/20250130110721_add_merge_requests_approval_rules_multi_column_not_null_constraint.rb new file mode 100644 index 0000000000000000000000000000000000000000..24e0e203b532c4a95da4da62d2d45dbea803d904 --- /dev/null +++ b/db/migrate/20250130110721_add_merge_requests_approval_rules_multi_column_not_null_constraint.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class AddMergeRequestsApprovalRulesMultiColumnNotNullConstraint < Gitlab::Database::Migration[2.2] + milestone '17.9' + + disable_ddl_transaction! + + def up + add_multi_column_not_null_constraint(:merge_requests_approval_rules, :group_id, :project_id) + end + + def down + remove_multi_column_not_null_constraint(:merge_requests_approval_rules, :group_id, :project_id) + end +end diff --git a/db/schema_migrations/20250123151650 b/db/schema_migrations/20250123151650 new file mode 100644 index 0000000000000000000000000000000000000000..6fbb499a26496d4b1f800227a9761a6fc305859c --- /dev/null +++ b/db/schema_migrations/20250123151650 @@ -0,0 +1 @@ +d149047a5d5fa4fa8242fde7f0d266cebef8d56e0db282d745c6da6e0f9f1c1d \ No newline at end of file diff --git a/db/schema_migrations/20250123151708 b/db/schema_migrations/20250123151708 new file mode 100644 index 0000000000000000000000000000000000000000..87a1ad0236b30a48f7ae9437fdd1c5b81800bad7 --- /dev/null +++ b/db/schema_migrations/20250123151708 @@ -0,0 +1 @@ +620def37e032e7fa463c4f1ecff0aacde33a5b9bd7a56c2f6ead418b3f4ce828 \ No newline at end of file diff --git a/db/schema_migrations/20250123151726 b/db/schema_migrations/20250123151726 new file mode 100644 index 0000000000000000000000000000000000000000..c0ffd2672253f42760cd8c1f495b0d8a9de757a9 --- /dev/null +++ b/db/schema_migrations/20250123151726 @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +e5a26f1a31603cf3ac570824874afbeac3bb970ca079bdaaebbf9cbe13155230 diff --git a/db/schema_migrations/20250123151745 b/db/schema_migrations/20250123151745 new file mode 100644 index 0000000000000000000000000000000000000000..420e8e7a97d2ab24280854bc6c1b7d11ad11b294 --- /dev/null +++ b/db/schema_migrations/20250123151745 @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +d6fc925f97583a4509894202b2e529ae64138f2cceef76e0d0c4dcaafe70f45a diff --git a/db/schema_migrations/20250123151804 b/db/schema_migrations/20250123151804 new file mode 100644 index 0000000000000000000000000000000000000000..01fb1b7bd3cfdfb8521e039542f0e07bbb6b080a --- /dev/null +++ b/db/schema_migrations/20250123151804 @@ -0,0 +1 @@ +c20c181bfad469e12cf79864fadb0e6ddef236530131d4a65f066c65ec5c0d7a \ No newline at end of file diff --git a/db/schema_migrations/20250123151822 b/db/schema_migrations/20250123151822 new file mode 100644 index 0000000000000000000000000000000000000000..b33904f99b523702f9fc475b31589971cce34de6 --- /dev/null +++ b/db/schema_migrations/20250123151822 @@ -0,0 +1 @@ +ad70887d503966368727be650a629bdf92d6206c7b63d79526a0402ffd5ddb16 \ No newline at end of file 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/20250130110721 b/db/schema_migrations/20250130110721 new file mode 100644 index 0000000000000000000000000000000000000000..7a1e2fbe886aeb3af3dd7c0b6edaf383bfbd131e --- /dev/null +++ b/db/schema_migrations/20250130110721 @@ -0,0 +1 @@ +4804fd7719ef467850550e1a488d544ec412f83e51335a367eca119ba550161c \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 54b4fd5cd898e802546261c11cb894fddf079641..315a7a3d330bc2e7c32071e76f8d04d101468129 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -3986,7 +3986,7 @@ PARTITION BY LIST (partition_id); CREATE TABLE p_ci_finished_build_ch_sync_events ( build_id bigint NOT NULL, - partition bigint DEFAULT 1 NOT NULL, + partition bigint DEFAULT 4 NOT NULL, build_finished_at timestamp without time zone NOT NULL, processed boolean DEFAULT false NOT NULL, project_id bigint NOT NULL @@ -3996,7 +3996,7 @@ PARTITION BY LIST (partition); CREATE TABLE p_ci_finished_pipeline_ch_sync_events ( pipeline_id bigint NOT NULL, project_namespace_id bigint NOT NULL, - partition bigint DEFAULT 1 NOT NULL, + partition bigint DEFAULT 5 NOT NULL, pipeline_finished_at timestamp without time zone NOT NULL, processed boolean DEFAULT false NOT NULL ) @@ -15851,6 +15851,149 @@ CREATE TABLE merge_requests ( CONSTRAINT check_970d272570 CHECK ((lock_version IS NOT NULL)) ); +CREATE TABLE merge_requests_approval_rules ( + id bigint NOT NULL, + approvals_required integer DEFAULT 0 NOT NULL, + name text NOT NULL, + rule_type smallint DEFAULT 0 NOT NULL, + origin smallint DEFAULT 0 NOT NULL, + project_id bigint, + group_id bigint, + source_rule_id bigint, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL, + CONSTRAINT check_ba7b03c61a CHECK ((num_nonnulls(group_id, project_id) = 1)), + CONSTRAINT check_c7c36145b7 CHECK ((char_length(name) <= 255)) +); + +CREATE TABLE merge_requests_approval_rules_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_groups_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE merge_requests_approval_rules_groups_id_seq OWNED BY merge_requests_approval_rules_groups.id; + +CREATE SEQUENCE merge_requests_approval_rules_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE merge_requests_approval_rules_id_seq OWNED BY merge_requests_approval_rules.id; + +CREATE TABLE merge_requests_approval_rules_merge_requests ( + id bigint NOT NULL, + approval_rule_id bigint NOT NULL, + merge_request_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_merge_requests_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE merge_requests_approval_rules_merge_requests_id_seq OWNED BY merge_requests_approval_rules_merge_requests.id; + +CREATE TABLE merge_requests_approval_rules_projects ( + id bigint NOT NULL, + approval_rule_id bigint NOT NULL, + project_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_projects_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE merge_requests_approval_rules_projects_id_seq OWNED BY merge_requests_approval_rules_projects.id; + +CREATE TABLE merge_requests_approval_rules_protected_branches ( + id bigint NOT NULL, + approval_rule_id bigint NOT NULL, + protected_branch_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_protected_branches_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE merge_requests_approval_rules_protected_branches_id_seq OWNED BY merge_requests_approval_rules_protected_branches.id; + +CREATE TABLE merge_requests_approval_rules_security_policy_links ( + id bigint NOT NULL, + approval_rule_id bigint NOT NULL, + security_policy_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_security_policy_links_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE merge_requests_approval_rules_security_policy_links_id_seq OWNED BY merge_requests_approval_rules_security_policy_links.id; + +CREATE TABLE merge_requests_approval_rules_user_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_user_groups_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE merge_requests_approval_rules_user_groups_id_seq OWNED BY merge_requests_approval_rules_user_groups.id; + +CREATE TABLE merge_requests_approval_rules_users ( + id bigint NOT NULL, + approval_rule_id bigint NOT NULL, + user_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_users_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE merge_requests_approval_rules_users_id_seq OWNED BY merge_requests_approval_rules_users.id; + CREATE TABLE merge_requests_closing_issues ( id bigint NOT NULL, merge_request_id bigint NOT NULL, @@ -25025,6 +25168,22 @@ ALTER TABLE ONLY merge_request_user_mentions ALTER COLUMN id SET DEFAULT nextval ALTER TABLE ONLY merge_requests ALTER COLUMN id SET DEFAULT nextval('merge_requests_id_seq'::regclass); +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_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); + +ALTER TABLE ONLY merge_requests_approval_rules_projects ALTER COLUMN id SET DEFAULT nextval('merge_requests_approval_rules_projects_id_seq'::regclass); + +ALTER TABLE ONLY merge_requests_approval_rules_protected_branches ALTER COLUMN id SET DEFAULT nextval('merge_requests_approval_rules_protected_branches_id_seq'::regclass); + +ALTER TABLE ONLY merge_requests_approval_rules_security_policy_links ALTER COLUMN id SET DEFAULT nextval('merge_requests_approval_rules_security_policy_links_id_seq'::regclass); + +ALTER TABLE ONLY merge_requests_approval_rules_user_groups ALTER COLUMN id SET DEFAULT nextval('merge_requests_approval_rules_user_groups_id_seq'::regclass); + +ALTER TABLE ONLY merge_requests_approval_rules_users ALTER COLUMN id SET DEFAULT nextval('merge_requests_approval_rules_users_id_seq'::regclass); + ALTER TABLE ONLY merge_requests_closing_issues ALTER COLUMN id SET DEFAULT nextval('merge_requests_closing_issues_id_seq'::regclass); ALTER TABLE ONLY merge_requests_compliance_violations ALTER COLUMN id SET DEFAULT nextval('merge_requests_compliance_violations_id_seq'::regclass); @@ -27567,6 +27726,30 @@ 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_groups + ADD CONSTRAINT merge_requests_approval_rules_groups_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY merge_requests_approval_rules_merge_requests + ADD CONSTRAINT merge_requests_approval_rules_merge_requests_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY merge_requests_approval_rules + ADD CONSTRAINT merge_requests_approval_rules_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY merge_requests_approval_rules_projects + ADD CONSTRAINT merge_requests_approval_rules_projects_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY merge_requests_approval_rules_protected_branches + ADD CONSTRAINT merge_requests_approval_rules_protected_branches_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY merge_requests_approval_rules_security_policy_links + ADD CONSTRAINT merge_requests_approval_rules_security_policy_links_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY merge_requests_approval_rules_user_groups + ADD CONSTRAINT merge_requests_approval_rules_user_groups_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY merge_requests_approval_rules_users + ADD CONSTRAINT merge_requests_approval_rules_users_pkey PRIMARY KEY (id); + ALTER TABLE ONLY merge_requests_closing_issues ADD CONSTRAINT merge_requests_closing_issues_pkey PRIMARY KEY (id); @@ -30930,6 +31113,28 @@ CREATE INDEX index_approval_rule_on_protected_environment_id ON protected_enviro CREATE INDEX index_approval_rules_code_owners_rule_type ON approval_merge_request_rules USING btree (merge_request_id) WHERE (rule_type = 2); +CREATE INDEX index_approval_rules_groups_on_approval_rule_id ON merge_requests_approval_rules_groups USING btree (approval_rule_id); + +CREATE INDEX index_approval_rules_merge_requests_on_approval_rule_id ON merge_requests_approval_rules_merge_requests USING btree (approval_rule_id); + +CREATE INDEX index_approval_rules_merge_requests_on_merge_request_id ON merge_requests_approval_rules_merge_requests USING btree (merge_request_id); + +CREATE INDEX index_approval_rules_on_approval_rule_sp_id ON merge_requests_approval_rules_security_policy_links USING btree (security_policy_id); + +CREATE INDEX index_approval_rules_on_source_rule_id ON merge_requests_approval_rules USING btree (source_rule_id); + +CREATE INDEX index_approval_rules_pb_on_approval_rule_id ON merge_requests_approval_rules_protected_branches USING btree (approval_rule_id); + +CREATE INDEX index_approval_rules_project_on_approval_rule_id ON merge_requests_approval_rules_projects USING btree (approval_rule_id); + +CREATE INDEX index_approval_rules_project_on_project_id ON merge_requests_approval_rules_projects USING btree (project_id); + +CREATE INDEX index_approval_rules_sp_on_approval_rule_id ON merge_requests_approval_rules_security_policy_links USING btree (approval_rule_id); + +CREATE INDEX index_approval_rules_user_groups_on_approval_rule_id ON merge_requests_approval_rules_user_groups USING btree (approval_rule_id); + +CREATE INDEX index_approval_rules_users_on_approval_rule_id ON merge_requests_approval_rules_users USING btree (approval_rule_id); + CREATE INDEX index_approvals_on_merge_request_id_and_created_at ON approvals USING btree (merge_request_id, created_at); CREATE UNIQUE INDEX index_approvals_on_user_id_and_merge_request_id ON approvals USING btree (user_id, merge_request_id); @@ -32894,6 +33099,16 @@ 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_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); + +CREATE INDEX index_merge_requests_approval_rules_on_project_id ON merge_requests_approval_rules USING btree (project_id); + +CREATE INDEX index_merge_requests_approval_rules_user_groups_on_group_id ON merge_requests_approval_rules_user_groups USING btree (group_id); + +CREATE INDEX index_merge_requests_approval_rules_users_on_user_id ON merge_requests_approval_rules_users USING btree (user_id); + CREATE INDEX index_merge_requests_closing_issues_on_issue_id ON merge_requests_closing_issues USING btree (issue_id); CREATE INDEX index_merge_requests_closing_issues_on_merge_request_id ON merge_requests_closing_issues USING btree (merge_request_id); @@ -33056,6 +33271,8 @@ CREATE INDEX index_ml_models_on_user_id ON ml_models USING btree (user_id); CREATE UNIQUE INDEX index_mr_approval_metrics_on_project_id_and_mr_id ON merge_request_approval_metrics USING btree (target_project_id, merge_request_id); +CREATE INDEX index_mr_approval_rules_pb_on_protected_branch_id ON merge_requests_approval_rules_protected_branches USING btree (protected_branch_id); + CREATE UNIQUE INDEX index_mr_blocks_on_blocking_and_blocked_mr_ids ON merge_request_blocks USING btree (blocking_merge_request_id, blocked_merge_request_id); CREATE INDEX index_mr_cleanup_schedules_timestamps_status ON merge_request_cleanup_schedules USING btree (scheduled_at) WHERE ((completed_at IS NULL) AND (status = 0)); @@ -39674,6 +39891,9 @@ ALTER TABLE ONLY automation_rules ALTER TABLE ONLY incident_management_oncall_participants ADD CONSTRAINT fk_rails_032b12996a FOREIGN KEY (oncall_rotation_id) REFERENCES incident_management_oncall_rotations(id) ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules + ADD CONSTRAINT fk_rails_03983bf729 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE; + ALTER TABLE ONLY events ADD CONSTRAINT fk_rails_0434b48643 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; @@ -39695,6 +39915,9 @@ ALTER TABLE ONLY security_policies ALTER TABLE ONLY subscription_user_add_on_assignment_versions ADD CONSTRAINT fk_rails_091e013a61 FOREIGN KEY (organization_id) REFERENCES organizations(id); +ALTER TABLE ONLY merge_requests_approval_rules_groups + ADD CONSTRAINT fk_rails_094b4086a3 FOREIGN KEY (approval_rule_id) REFERENCES merge_requests_approval_rules(id); + ALTER TABLE ONLY trending_projects ADD CONSTRAINT fk_rails_09feecd872 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; @@ -39872,6 +40095,9 @@ ALTER TABLE ONLY project_ci_feature_usages ALTER TABLE ONLY packages_tags ADD CONSTRAINT fk_rails_1dfc868911 FOREIGN KEY (package_id) REFERENCES packages_packages(id) ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules_security_policy_links + ADD CONSTRAINT fk_rails_1ea772f06d FOREIGN KEY (approval_rule_id) REFERENCES merge_requests_approval_rules(id); + ALTER TABLE ONLY boards_epic_board_positions ADD CONSTRAINT fk_rails_1ecfd9f2de FOREIGN KEY (epic_id) REFERENCES epics(id) ON DELETE CASCADE; @@ -40175,6 +40401,9 @@ ALTER TABLE ONLY merge_request_assignees ALTER TABLE ONLY packages_dependency_links ADD CONSTRAINT fk_rails_4437bf4070 FOREIGN KEY (dependency_id) REFERENCES packages_dependencies(id) ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules_projects + ADD CONSTRAINT fk_rails_451a9dfe93 FOREIGN KEY (approval_rule_id) REFERENCES merge_requests_approval_rules(id); + ALTER TABLE p_ci_builds ADD CONSTRAINT fk_rails_4540ead625_p FOREIGN KEY (upstream_pipeline_partition_id, upstream_pipeline_id) REFERENCES p_ci_pipelines(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE; @@ -40307,6 +40536,9 @@ ALTER TABLE ONLY incident_management_timeline_event_tag_links ALTER TABLE ONLY packages_debian_project_architectures ADD CONSTRAINT fk_rails_5808663adf FOREIGN KEY (distribution_id) REFERENCES packages_debian_project_distributions(id) ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules_groups + ADD CONSTRAINT fk_rails_59068f09e5 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE; + ALTER TABLE ONLY analytics_cycle_analytics_group_stages ADD CONSTRAINT fk_rails_5a22f40223 FOREIGN KEY (start_event_label_id) REFERENCES labels(id) ON DELETE CASCADE; @@ -40355,6 +40587,9 @@ ALTER TABLE ONLY ci_stages ALTER TABLE ONLY epic_issues ADD CONSTRAINT fk_rails_5d942936b4 FOREIGN KEY (epic_id) REFERENCES epics(id) ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules_merge_requests + ADD CONSTRAINT fk_rails_5ddc4a2f7b FOREIGN KEY (approval_rule_id) REFERENCES merge_requests_approval_rules(id); + ALTER TABLE ONLY packages_nuget_symbols ADD CONSTRAINT fk_rails_5df972da14 FOREIGN KEY (package_id) REFERENCES packages_packages(id) ON DELETE SET NULL; @@ -40400,6 +40635,9 @@ ALTER TABLE ONLY status_page_published_incidents ALTER TABLE ONLY group_ssh_certificates ADD CONSTRAINT fk_rails_61f9eafcdf FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules_user_groups + ADD CONSTRAINT fk_rails_62b95a2502 FOREIGN KEY (approval_rule_id) REFERENCES merge_requests_approval_rules(id); + ALTER TABLE ONLY container_repository_states ADD CONSTRAINT fk_rails_63436c99ce FOREIGN KEY (container_repository_id) REFERENCES container_repositories(id) ON DELETE CASCADE; @@ -40505,6 +40743,9 @@ ALTER TABLE ONLY project_compliance_framework_settings ALTER TABLE ONLY users_security_dashboard_projects ADD CONSTRAINT fk_rails_6f6cf8e66e FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules_protected_branches + ADD CONSTRAINT fk_rails_6feb548ad1 FOREIGN KEY (approval_rule_id) REFERENCES merge_requests_approval_rules(id); + ALTER TABLE ONLY analytics_dashboards_pointers ADD CONSTRAINT fk_rails_7027b7eaa9 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; @@ -40541,6 +40782,9 @@ ALTER TABLE ONLY merge_request_context_commit_diff_files ALTER TABLE ONLY audit_events_streaming_http_group_namespace_filters ADD CONSTRAINT fk_rails_74a28d2432 FOREIGN KEY (external_audit_event_destination_id) REFERENCES audit_events_external_audit_event_destinations(id) ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules_merge_requests + ADD CONSTRAINT fk_rails_74e3466397 FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE; + ALTER TABLE ONLY group_crm_settings ADD CONSTRAINT fk_rails_74fdf2f13d FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE; @@ -40595,6 +40839,9 @@ ALTER TABLE ONLY operations_scopes ALTER TABLE ONLY milestone_releases ADD CONSTRAINT fk_rails_7ae0756a2d FOREIGN KEY (milestone_id) REFERENCES milestones(id) ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules + ADD CONSTRAINT fk_rails_7af76dbd21 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; + ALTER TABLE ONLY scan_execution_policy_rules ADD CONSTRAINT fk_rails_7be2571ecf FOREIGN KEY (security_policy_id) REFERENCES security_policies(id) ON DELETE CASCADE; @@ -41009,9 +41256,18 @@ ALTER TABLE ONLY pipl_users ALTER TABLE ONLY pool_repositories ADD CONSTRAINT fk_rails_af3f8c5d62 FOREIGN KEY (shard_id) REFERENCES shards(id) ON DELETE RESTRICT; +ALTER TABLE ONLY merge_requests_approval_rules_projects + ADD CONSTRAINT fk_rails_af4078336f FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; + +ALTER TABLE ONLY merge_requests_approval_rules_protected_branches + ADD CONSTRAINT fk_rails_b07dde4b2a FOREIGN KEY (protected_branch_id) REFERENCES protected_branches(id) ON DELETE CASCADE; + ALTER TABLE ONLY resource_label_events ADD CONSTRAINT fk_rails_b126799f57 FOREIGN KEY (label_id) REFERENCES labels(id) ON DELETE SET NULL; +ALTER TABLE ONLY merge_requests_approval_rules_users + ADD CONSTRAINT fk_rails_b12b222020 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; + ALTER TABLE ONLY webauthn_registrations ADD CONSTRAINT fk_rails_b15c016782 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; @@ -41060,6 +41316,9 @@ ALTER TABLE ONLY abuse_trust_scores ALTER TABLE ONLY virtual_registries_packages_maven_registry_upstreams ADD CONSTRAINT fk_rails_b991fff0be FOREIGN KEY (registry_id) REFERENCES virtual_registries_packages_maven_registries(id) ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules_security_policy_links + ADD CONSTRAINT fk_rails_b9ad04b2a2 FOREIGN KEY (security_policy_id) REFERENCES security_policies(id) ON DELETE CASCADE; + ALTER TABLE ONLY dora_configurations ADD CONSTRAINT fk_rails_b9b8d90ddb FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; @@ -41252,6 +41511,9 @@ ALTER TABLE ONLY subscriptions ALTER TABLE ONLY operations_strategies ADD CONSTRAINT fk_rails_d183b6e6dd FOREIGN KEY (feature_flag_id) REFERENCES operations_feature_flags(id) ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules_users + ADD CONSTRAINT fk_rails_d1c23df23f FOREIGN KEY (approval_rule_id) REFERENCES merge_requests_approval_rules(id) ON DELETE CASCADE; + ALTER TABLE ONLY cluster_agent_tokens ADD CONSTRAINT fk_rails_d1d26abc25 FOREIGN KEY (agent_id) REFERENCES cluster_agents(id) ON DELETE CASCADE; @@ -41378,6 +41640,9 @@ ALTER TABLE p_catalog_resource_component_usages ALTER TABLE ONLY cluster_platforms_kubernetes ADD CONSTRAINT fk_rails_e1e2cf841a FOREIGN KEY (cluster_id) REFERENCES clusters(id) ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules_user_groups + ADD CONSTRAINT fk_rails_e1e7c6423f FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE; + ALTER TABLE p_ci_builds_execution_configs ADD CONSTRAINT fk_rails_e214655a86_p FOREIGN KEY (partition_id, pipeline_id) REFERENCES p_ci_pipelines(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE; @@ -41561,6 +41826,9 @@ ALTER TABLE ONLY merge_requests_closing_issues ALTER TABLE p_ci_job_artifact_reports ADD CONSTRAINT fk_rails_f9b8550174 FOREIGN KEY (partition_id, job_artifact_id) REFERENCES p_ci_job_artifacts(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE; +ALTER TABLE ONLY merge_requests_approval_rules + ADD CONSTRAINT fk_rails_fa5b38e373 FOREIGN KEY (source_rule_id) REFERENCES merge_requests_approval_rules(id) ON DELETE SET NULL; + ALTER TABLE ONLY banned_users ADD CONSTRAINT fk_rails_fa5bb598e5 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; diff --git a/ee/app/models/ee/group.rb b/ee/app/models/ee/group.rb index 71b5f3f66d91e3943d7d07385bc1ca6344246598..72d3274052c77275cbca20f31762358f6624ab92 100644 --- a/ee/app/models/ee/group.rb +++ b/ee/app/models/ee/group.rb @@ -97,6 +97,10 @@ module Group has_many :security_exclusions, class_name: 'Security::GroupSecurityExclusion' + has_many :v2_approval_rules_from_group_origin, class_name: 'MergeRequests::ApprovalRule', inverse_of: :source_group + has_many :v2_approval_group_rules, class_name: 'MergeRequests::ApprovalRulesGroup', inverse_of: :group + has_many :v2_approval_rules, through: :v2_approval_group_rules, class_name: 'MergeRequests::ApprovalRule', source: :approval_rule + delegate :deleting_user, :marked_for_deletion_on, to: :deletion_schedule, allow_nil: true delegate :repository_read_only, diff --git a/ee/app/models/ee/merge_request.rb b/ee/app/models/ee/merge_request.rb index 114423aa987fe7a060a89cf1ffd9a54f5f5f7864..5d426078ea20a63bf08e704ca1de8fb9cd20ce6f 100644 --- a/ee/app/models/ee/merge_request.rb +++ b/ee/app/models/ee/merge_request.rb @@ -99,6 +99,11 @@ def set_applicable_when_copying_rules(applicable_ids) has_many :merge_request_stage_events, class_name: 'Analytics::CycleAnalytics::MergeRequestStageEvent' + has_many :v2_approval_merge_request_rules, class_name: 'MergeRequests::ApprovalRulesMergeRequest', + inverse_of: :merge_request + has_many :v2_approval_rules, through: :v2_approval_merge_request_rules, + class_name: 'MergeRequests::ApprovalRule', source: :approval_rule + delegate :sha, to: :head_pipeline, prefix: :head_pipeline, allow_nil: true delegate :sha, to: :base_pipeline, prefix: :base_pipeline, allow_nil: true delegate :wrapped_approval_rules, :invalid_approvers_rules, to: :approval_state diff --git a/ee/app/models/ee/project.rb b/ee/app/models/ee/project.rb index 10b954f052e072e26483da33e7fe8ebe10dd9a63..9a430a10083c780d89532abc08210e6696cbce37 100644 --- a/ee/app/models/ee/project.rb +++ b/ee/app/models/ee/project.rb @@ -217,6 +217,10 @@ def lock_for_confirmation!(id) has_many :project_control_compliance_statuses, class_name: 'ComplianceManagement::ComplianceFramework::ProjectControlComplianceStatus' + has_many :v2_approval_rules_from_project_origin, class_name: 'MergeRequests::ApprovalRule', inverse_of: :source_project + has_many :v2_approval_project_rules, class_name: 'MergeRequests::ApprovalRulesProject', inverse_of: :project + has_many :v2_approval_rules, through: :v2_approval_project_rules, class_name: 'MergeRequests::ApprovalRule', source: :approval_rule + elastic_index_dependant_association :issues, on_change: :visibility_level elastic_index_dependant_association :issues, on_change: :archived elastic_index_dependant_association :work_items, on_change: :visibility_level diff --git a/ee/app/models/merge_requests/approval_rule.rb b/ee/app/models/merge_requests/approval_rule.rb new file mode 100644 index 0000000000000000000000000000000000000000..cd0e4447dce5d6045a350d04ad24b0a5f32863c6 --- /dev/null +++ b/ee/app/models/merge_requests/approval_rule.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module MergeRequests + class ApprovalRule < ApplicationRecord + self.table_name = 'merge_requests_approval_rules' + + # source group or project. Only 1 should be supplied for sharding purposes. + belongs_to :source_group, foreign_key: 'group_id', class_name: 'Group', + inverse_of: :v2_approval_rules_from_group_origin + belongs_to :source_project, foreign_key: 'project_id', class_name: 'Project', + inverse_of: :v2_approval_rules_from_project_origin + + # If we allow overriding in subgroups we can add groups association + has_many :approval_rules_groups + has_many :groups, through: :approval_rules_groups + + # When this originated_from_group there are multiple projects + has_many :approval_rules_projects + has_many :projects, through: :approval_rules_projects + + # When this originated_from_merge_request there's only one merge_request + has_one :approval_rules_merge_request, inverse_of: :approval_rule + has_one :merge_request, through: :approval_rules_merge_request + + # When this originated_from_project there are multiple merge_requests + has_many :approval_rules_merge_requests + has_many :merge_requests, through: :approval_rules_merge_requests + + validate :source_group_or_project_present + + with_options validate: true do + enum :rule_type, { regular: 0, code_owner: 1, report_approver: 2, any_approver: 3 }, default: :regular + enum :origin, { group: 0, project: 1, merge_request: 2 }, prefix: :originates_from + end + + private + + def source_group_or_project_present + if source_group.blank? && source_project.blank? + errors.add(:base, "Must have either a source group or source project") + elsif source_group.present? && source_project.present? + errors.add(:base, "Cannot have both a source group and source project") + end + end + end +end diff --git a/ee/app/models/merge_requests/approval_rules_group.rb b/ee/app/models/merge_requests/approval_rules_group.rb new file mode 100644 index 0000000000000000000000000000000000000000..c2d524c77aea9f63b23336cf3d1f470d19d33dd5 --- /dev/null +++ b/ee/app/models/merge_requests/approval_rules_group.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module MergeRequests + class ApprovalRulesGroup < ApplicationRecord + self.table_name = 'merge_requests_approval_rules_groups' + + belongs_to :approval_rule, class_name: 'MergeRequests::ApprovalRule' + belongs_to :group + end +end diff --git a/ee/app/models/merge_requests/approval_rules_merge_request.rb b/ee/app/models/merge_requests/approval_rules_merge_request.rb new file mode 100644 index 0000000000000000000000000000000000000000..6ba10a234ac04bdf2bc23b9e19ed1109fdecd869 --- /dev/null +++ b/ee/app/models/merge_requests/approval_rules_merge_request.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module MergeRequests + class ApprovalRulesMergeRequest < ApplicationRecord + self.table_name = 'merge_requests_approval_rules_merge_requests' + + belongs_to :approval_rule, class_name: 'MergeRequests::ApprovalRule' + belongs_to :merge_request + end +end diff --git a/ee/app/models/merge_requests/approval_rules_project.rb b/ee/app/models/merge_requests/approval_rules_project.rb new file mode 100644 index 0000000000000000000000000000000000000000..cebfec1e6b354c4aa61c196201e4ea35243b7efc --- /dev/null +++ b/ee/app/models/merge_requests/approval_rules_project.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module MergeRequests + class ApprovalRulesProject < ApplicationRecord + self.table_name = 'merge_requests_approval_rules_projects' + + belongs_to :approval_rule, class_name: 'MergeRequests::ApprovalRule' + belongs_to :project + end +end diff --git a/ee/app/models/merge_requests/approval_rules_protected_branch.rb b/ee/app/models/merge_requests/approval_rules_protected_branch.rb new file mode 100644 index 0000000000000000000000000000000000000000..fa3744abe54cba9741a00bef645513b9747b1873 --- /dev/null +++ b/ee/app/models/merge_requests/approval_rules_protected_branch.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module MergeRequests + class ApprovalRulesProtectedBranch < ApplicationRecord + self.table_name = 'merge_requests_approval_rules_protected_branches' + + belongs_to :approval_rule, class_name: 'MergeRequests::ApprovalRule' + belongs_to :protected_branch + end +end diff --git a/ee/app/models/merge_requests/approval_rules_security_policy_link.rb b/ee/app/models/merge_requests/approval_rules_security_policy_link.rb new file mode 100644 index 0000000000000000000000000000000000000000..d780108f39be727c97f8a295d544657914e73fa5 --- /dev/null +++ b/ee/app/models/merge_requests/approval_rules_security_policy_link.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module MergeRequests + class ApprovalRulesSecurityPolicyLink < ApplicationRecord + self.table_name = 'merge_requests_approval_rules_security_policy_links' + + belongs_to :approval_rule, class_name: 'MergeRequests::ApprovalRule' + belongs_to :security_policy, class_name: 'Security::Policy' + end +end diff --git a/ee/app/models/merge_requests/approval_rules_user.rb b/ee/app/models/merge_requests/approval_rules_user.rb new file mode 100644 index 0000000000000000000000000000000000000000..24b182423254a0c0ebeb9c87dda6fdf8783ea7cd --- /dev/null +++ b/ee/app/models/merge_requests/approval_rules_user.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module MergeRequests + class ApprovalRulesUser < ApplicationRecord + self.table_name = 'merge_requests_approval_rules_users' + + belongs_to :approval_rule, class_name: 'MergeRequests::ApprovalRule' + belongs_to :user + end +end diff --git a/ee/app/models/merge_requests/approval_rules_user_group.rb b/ee/app/models/merge_requests/approval_rules_user_group.rb new file mode 100644 index 0000000000000000000000000000000000000000..05c209c314a34303d9a8d460ee188dbea48ea1d4 --- /dev/null +++ b/ee/app/models/merge_requests/approval_rules_user_group.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module MergeRequests + class ApprovalRulesUserGroup < ApplicationRecord + self.table_name = 'merge_requests_approval_rules_user_groups' + + belongs_to :approval_rule, class_name: 'MergeRequests::ApprovalRule' + belongs_to :group + end +end diff --git a/ee/spec/factories/merge_requests/approval_rules.rb b/ee/spec/factories/merge_requests/approval_rules.rb new file mode 100644 index 0000000000000000000000000000000000000000..f6d150880cf2c84b965835f7f002aa5e1870b599 --- /dev/null +++ b/ee/spec/factories/merge_requests/approval_rules.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :merge_requests_approval_rule, class: 'MergeRequests::ApprovalRule' do + trait :with_source_group do + association :source_group, factory: :group + end + + trait :with_source_project do + association :source_project, factory: :project + end + end +end diff --git a/ee/spec/factories/merge_requests/approval_rules_groups.rb b/ee/spec/factories/merge_requests/approval_rules_groups.rb new file mode 100644 index 0000000000000000000000000000000000000000..fb8212dd5ea6cce4a3284bf88a2db073cdfb04eb --- /dev/null +++ b/ee/spec/factories/merge_requests/approval_rules_groups.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :merge_requests_approval_rules_group, class: 'MergeRequests::ApprovalRulesGroup' 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_merge_requests.rb b/ee/spec/factories/merge_requests/approval_rules_merge_requests.rb new file mode 100644 index 0000000000000000000000000000000000000000..b221902638aaa6cacc2f30682e4d69005cadf3b6 --- /dev/null +++ b/ee/spec/factories/merge_requests/approval_rules_merge_requests.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :merge_requests_approval_rules_merge_request, class: 'MergeRequests::ApprovalRulesMergeRequest' do + association :approval_rule, factory: :merge_requests_approval_rule + association :merge_request, factory: :merge_request + end +end diff --git a/ee/spec/factories/merge_requests/approval_rules_projects.rb b/ee/spec/factories/merge_requests/approval_rules_projects.rb new file mode 100644 index 0000000000000000000000000000000000000000..de9d478f357fffcd592a0c795ae95a6c29d63eff --- /dev/null +++ b/ee/spec/factories/merge_requests/approval_rules_projects.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :merge_requests_approval_rules_project, class: 'MergeRequests::ApprovalRulesProject' do + association :approval_rule, factory: :merge_requests_approval_rule + association :project, factory: :project + end +end diff --git a/ee/spec/factories/merge_requests/approval_rules_protected_branches.rb b/ee/spec/factories/merge_requests/approval_rules_protected_branches.rb new file mode 100644 index 0000000000000000000000000000000000000000..be050456f1e9e6408d64200b21a5dea38ab1b816 --- /dev/null +++ b/ee/spec/factories/merge_requests/approval_rules_protected_branches.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :merge_requests_approval_rules_protected_branch, class: 'MergeRequests::ApprovalRulesProtectedBranch' do # rubocop:disable Lint/EmptyBlock -- block is required by factorybot + end +end diff --git a/ee/spec/factories/merge_requests/approval_rules_security_policy_links.rb b/ee/spec/factories/merge_requests/approval_rules_security_policy_links.rb new file mode 100644 index 0000000000000000000000000000000000000000..537ed9b86b0dabe6a38a8efede255853ecf59f9c --- /dev/null +++ b/ee/spec/factories/merge_requests/approval_rules_security_policy_links.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :merge_requests_approval_rules_security_policy_link, class: 'MergeRequests::ApprovalRulesSecurityPolicyLink' do # rubocop:disable Lint/EmptyBlock -- block is required by factorybot + end +end diff --git a/ee/spec/factories/merge_requests/approval_rules_user_groups.rb b/ee/spec/factories/merge_requests/approval_rules_user_groups.rb new file mode 100644 index 0000000000000000000000000000000000000000..49ed05055d12504328439b5797ea6bba5112d817 --- /dev/null +++ b/ee/spec/factories/merge_requests/approval_rules_user_groups.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :merge_requests_approval_rules_user_group, class: 'MergeRequests::ApprovalRulesUserGroup' 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_users.rb b/ee/spec/factories/merge_requests/approval_rules_users.rb new file mode 100644 index 0000000000000000000000000000000000000000..545576397c3f6ad7ee452ea3cd212042c5bca4d1 --- /dev/null +++ b/ee/spec/factories/merge_requests/approval_rules_users.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :merge_requests_approval_rules_user, class: 'MergeRequests::ApprovalRulesUser' do + association :approval_rule, factory: :merge_requests_approval_rule + association :user, factory: :user + end +end diff --git a/ee/spec/models/merge_requests/approval_rule_spec.rb b/ee/spec/models/merge_requests/approval_rule_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..73721d2dc4fdf8b6955aa38db366e0a21ba6f508 --- /dev/null +++ b/ee/spec/models/merge_requests/approval_rule_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe MergeRequests::ApprovalRule, type: :model, feature_category: :code_review_workflow do + subject(:rule) { build(:merge_requests_approval_rule, *traits) } + + let(:traits) { [] } + + describe 'associations' do + context 'when associated with a source_group' do + let(:traits) { [:with_source_group] } + + it { is_expected.to belong_to(:source_group) } + end + + context 'when associated with a source_project' do + let(:traits) { [:with_source_project] } + + it { is_expected.to belong_to(:source_project) } + end + end + + describe 'validations' do + context 'when associated with a source_group' do + let(:traits) { [:with_source_group] } + + it { is_expected.to be_valid } + end + + context 'when associated with a source_project' do + let(:traits) { [:with_source_project] } + + it { is_expected.to be_valid } + end + + context 'when not associated with either source_group or source_project' do + it { is_expected.not_to be_valid } + + it 'has the correct error message' do + rule.valid? + expect(rule.errors[:base]).to include("Must have either a source group or source project") + end + end + + context 'when associated with both source_group and source_project' do + let(:traits) { [:with_source_group, :with_source_project] } + + it { is_expected.not_to be_valid } + + it 'has the correct error message' do + rule.valid? + expect(rule.errors[:base]).to include("Cannot have both a source group and source project") + end + end + end +end diff --git a/ee/spec/models/merge_requests/approval_rules_group_spec.rb b/ee/spec/models/merge_requests/approval_rules_group_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..b86fa692d113073fd0badffb739c44e9ec8dc7cb --- /dev/null +++ b/ee/spec/models/merge_requests/approval_rules_group_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe MergeRequests::ApprovalRulesGroup, 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_merge_request_spec.rb b/ee/spec/models/merge_requests/approval_rules_merge_request_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..4b9037cb93489cbb5e8cd98c00cfd5c7eb367729 --- /dev/null +++ b/ee/spec/models/merge_requests/approval_rules_merge_request_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe MergeRequests::ApprovalRulesMergeRequest, 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(:merge_request) } + end +end diff --git a/ee/spec/models/merge_requests/approval_rules_project_spec.rb b/ee/spec/models/merge_requests/approval_rules_project_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..cd8575ef2ea18a25ae689c76a981ddc82c5ffd93 --- /dev/null +++ b/ee/spec/models/merge_requests/approval_rules_project_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe MergeRequests::ApprovalRulesProject, 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(:project) } + end +end diff --git a/ee/spec/models/merge_requests/approval_rules_protected_branch_spec.rb b/ee/spec/models/merge_requests/approval_rules_protected_branch_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..dc181f0b86d919255f30e577381d3bde18a9d6f2 --- /dev/null +++ b/ee/spec/models/merge_requests/approval_rules_protected_branch_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe MergeRequests::ApprovalRulesProtectedBranch, 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(:protected_branch) } + end +end diff --git a/ee/spec/models/merge_requests/approval_rules_security_policy_link_spec.rb b/ee/spec/models/merge_requests/approval_rules_security_policy_link_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..33c150297a2d92a11af710286fa6ea8143265e5b --- /dev/null +++ b/ee/spec/models/merge_requests/approval_rules_security_policy_link_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe MergeRequests::ApprovalRulesSecurityPolicyLink, 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(:security_policy) } + end +end diff --git a/ee/spec/models/merge_requests/approval_rules_user_group_spec.rb b/ee/spec/models/merge_requests/approval_rules_user_group_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..b23612507e66a2c71ce181a231278ea67e443c8b --- /dev/null +++ b/ee/spec/models/merge_requests/approval_rules_user_group_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe MergeRequests::ApprovalRulesUserGroup, 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_user_spec.rb b/ee/spec/models/merge_requests/approval_rules_user_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..7ed2582f0d2ba349c59bdfa37d6e3bf75278d1c1 --- /dev/null +++ b/ee/spec/models/merge_requests/approval_rules_user_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe MergeRequests::ApprovalRulesUser, 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(:user) } + end +end diff --git a/spec/lib/gitlab/database/sharding_key_spec.rb b/spec/lib/gitlab/database/sharding_key_spec.rb index 399c1f258fd34c66340104876c82f7ebd3008133..526f2a7183d69a936de6652f3ae7f04540d5e1d1 100644 --- a/spec/lib/gitlab/database/sharding_key_spec.rb +++ b/spec/lib/gitlab/database/sharding_key_spec.rb @@ -14,7 +14,12 @@ 'ml_model_metadata', # has a desired sharding key instead. 'p_ci_pipeline_variables', # has a desired sharding key instead 'sbom_occurrences_vulnerabilities', # has desired sharding key instead - 'web_hook_logs_daily' # temporary copy of web_hook_logs + 'web_hook_logs_daily', # temporary copy of web_hook_logs + 'merge_requests_approval_rules_merge_requests', # has desired sharding key instead + 'merge_requests_approval_rules_protected_branches', # has desired sharding key instead + 'merge_requests_approval_rules_security_policy_links', # has desired sharding key instead + 'merge_requests_approval_rules_user_groups', # has desired sharding key instead + 'merge_requests_approval_rules_users' # has desired sharding key instead ] end diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index b2bff3b96eda89d48f6f0cf2f0cbc15a81fb407a..5f69fc24d7c7d0faad13b3bae0e90463d8296fec 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -255,6 +255,10 @@ merge_requests: - approver_users - approver_groups - approved_by_users +- v2_approval_rules +- v2_approval_project_rules +- v2_approval_rules_from_project_origin +- v2_approval_merge_request_rules - draft_notes - merge_train_car - blocks_as_blocker @@ -769,6 +773,9 @@ project: - approval_merge_request_rules - approval_merge_request_rule_sources - approval_project_rules +- v2_approval_project_rules +- v2_approval_rules_from_project_origin +- v2_approval_merge_request_rules - approvers - approver_users - audit_events