Add database and model support for "Group-level Protected Branches"
What does this MR do and why?
Related to #372815 (closed), this MR is basic database support for the feature "Group-level Protected Branches". There are three changes:
- Add a column
namespace_idto the tableprotected_branches. - Update the constraint in
protected_branches, check that eitherproject_idornamespace_idexist. - Update the model
validationandassociationto accommodate database changes.
How to set up and validate locally
- Open a Rails console in GitLab project.
- Add a protected branch into group:
ProtectedBranch.last.update!(project: nil, group: Group.last) - Get all protected branches of the last group:
Group.last.protected_branches
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.
Migration outout logs
$ bundle exec rake db:drop db:create db:schema:load db:migrate
Dropped database 'gitlabhq_test'
Dropped database 'gitlabhq_test_ci'
Dropped database 'gitlabhq_geo_test'
Created database 'gitlabhq_test'
Created database 'gitlabhq_test_ci'
Created database 'gitlabhq_geo_test'
==> 'bundle exec rake db:drop db:create db:schema:load db:migrate' succeeded in 37 seconds.
$ setup_db_praefect
SELECT pg_catalog.set_config('search_path', '', false);
CREATE DATABASE praefect_test ENCODING 'UTF8';
==> 'setup_db_praefect' succeeded in 0 seconds.
$ git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:$CI_MERGE_REQUEST_TARGET_BRANCH_NAME --depth 20
From https://gitlab.com/gitlab-jh/jh-team/gitlab
* [new branch] master -> master
* [new branch] master -> origin/master
$ scripts/validate_migration_schema
$ git diff --name-only --diff-filter=A master -- db/migrate db/post_migrate
db/migrate/20220613112029_add_namespace_id_to_protected_branches.rb
db/migrate/20220613112030_add_namespace_id_indexes_foreign_key_to_protected_branches.rb
db/migrate/20220613112031_add_group_or_project_constraint_in_protected_branches.rb
db/migrate/20220613112032_change_project_id_null_in_protected_branches.rb
$ scripts/db_tasks db:migrate:down VERSION=20220613112032
main: == 20220613112032 ChangeProjectIdNullInProtectedBranches: reverting ===========
main: -- change_column_null(:protected_branches, :project_id, false)
main: -> 0.0038s
main: == 20220613112032 ChangeProjectIdNullInProtectedBranches: reverted (0.0065s) ==
$ scripts/db_tasks db:schema:dump
$ scripts/db_tasks db:migrate:down VERSION=20220613112031
main: == 20220613112031 AddGroupOrProjectConstraintInProtectedBranches: reverting ===
main: -- transaction_open?()
main: -> 0.0000s
main: -- transaction_open?()
main: -> 0.0000s
main: -- execute("ALTER TABLE protected_branches\nDROP CONSTRAINT IF EXISTS protected_branches_project_id_namespace_id_any_not_null\n")
main: -> 0.0013s
main: == 20220613112031 AddGroupOrProjectConstraintInProtectedBranches: reverted (0.0140s)
$ scripts/db_tasks db:schema:dump
$ scripts/db_tasks db:migrate:down VERSION=20220613112030
main: == 20220613112030 AddNamespaceIdIndexesForeignKeyToProtectedBranches: reverting
main: -- transaction_open?()
main: -> 0.0000s
main: -- remove_foreign_key(:protected_branches, {:column=>:namespace_id})
main: -> 0.0196s
main: -- transaction_open?()
main: -> 0.0000s
main: -- index_exists?(:protected_branches, :namespace_id, {:name=>"index_protected_branches_namespace_id", :algorithm=>:concurrently})
main: -> 0.0066s
main: -- execute("SET statement_timeout TO 0")
main: -> 0.0006s
main: -- remove_index(:protected_branches, {:name=>"index_protected_branches_namespace_id", :algorithm=>:concurrently, :column=>:namespace_id})
main: -> 0.0066s
main: -- execute("RESET statement_timeout")
main: -> 0.0007s
main: == 20220613112030 AddNamespaceIdIndexesForeignKeyToProtectedBranches: reverted (0.0609s)
$ scripts/db_tasks db:schema:dump
$ scripts/db_tasks db:migrate:down VERSION=20220613112029
main: == 20220613112029 AddNamespaceIdToProtectedBranches: reverting ================
main: -- remove_column(:protected_branches, :namespace_id, :bigint)
main: -> 0.0025s
main: == 20220613112029 AddNamespaceIdToProtectedBranches: reverted (0.0060s) =======
$ scripts/db_tasks db:schema:dump
$ git diff master -- db/structure.sql
$ scripts/db_tasks db:migrate
main: == 20220613112029 AddNamespaceIdToProtectedBranches: migrating ================
main: -- add_column(:protected_branches, :namespace_id, :bigint)
main: -> 0.0021s
main: == 20220613112029 AddNamespaceIdToProtectedBranches: migrated (0.0031s) =======
main: == 20220613112030 AddNamespaceIdIndexesForeignKeyToProtectedBranches: migrating
main: -- transaction_open?()
main: -> 0.0000s
main: -- index_exists?(:protected_branches, :namespace_id, {:name=>"index_protected_branches_namespace_id", :where=>"namespace_id IS NOT NULL", :algorithm=>:concurrently})
main: -> 0.0073s
main: -- execute("SET statement_timeout TO 0")
main: -> 0.0006s
main: -- add_index(:protected_branches, :namespace_id, {:name=>"index_protected_branches_namespace_id", :where=>"namespace_id IS NOT NULL", :algorithm=>:concurrently})
main: -> 0.0024s
main: -- execute("RESET statement_timeout")
main: -> 0.0005s
main: -- transaction_open?()
main: -> 0.0000s
main: -- foreign_keys(:protected_branches)
main: -> 0.0052s
main: -- transaction_open?()
main: -> 0.0000s
main: -- execute("ALTER TABLE protected_branches\nADD CONSTRAINT fk_de9216e774\nFOREIGN KEY (namespace_id)\nREFERENCES namespaces (id)\nON DELETE CASCADE\nNOT VALID;\n")
main: -> 0.0020s
main: -- execute("ALTER TABLE protected_branches VALIDATE CONSTRAINT fk_de9216e774;")
main: -> 0.0025s
main: == 20220613112030 AddNamespaceIdIndexesForeignKeyToProtectedBranches: migrated (0.0347s)
main: == 20220613112031 AddGroupOrProjectConstraintInProtectedBranches: migrating ===
main: -- transaction_open?()
main: -> 0.0000s
main: -- current_schema()
main: -> 0.0006s
main: -- transaction_open?()
main: -> 0.0000s
main: -- execute(" ALTER TABLE protected_branches\n ADD CONSTRAINT protected_branches_project_id_namespace_id_any_not_null\n CHECK ( (project_id IS NULL) <> (namespace_id IS NULL)\n)\n NOT VALID;\n")
main: -> 0.0010s
main: -- current_schema()
main: -> 0.0004s
main: -- execute("ALTER TABLE protected_branches VALIDATE CONSTRAINT protected_branches_project_id_namespace_id_any_not_null;")
main: -> 0.0008s
main: == 20220613112031 AddGroupOrProjectConstraintInProtectedBranches: migrated (0.0102s)
main: == 20220613112032 ChangeProjectIdNullInProtectedBranches: migrating ===========
main: -- change_column_null(:protected_branches, :project_id, true)
main: -> 0.0009s
main: == 20220613112032 ChangeProjectIdNullInProtectedBranches: migrated (0.0011s) ==
/cc @daveliu
Edited by Song Huang