Skip to content

Run migrations in reverse order in CI check [RUN ALL RSPEC]

Patrick Bair requested to merge pb-ci-check-reverse-migration-order into master

What does this MR do?

Fix the ordering when running migrations during the CI db:check-migrations job, to run in proper down order:

  1. Post-deployment migrations should be rolled back first, in reverse timestamp order
  2. Pre-deployment migrations should then be rolled back, also in reverse timestamp order

Example:

Two migrations, based on the scenario given here: !53181 (comment 504386852)

first migration:

# frozen_string_literal: true

class TestOne < ActiveRecord::Migration[6.0]
  include Gitlab::Database::MigrationHelpers

  DOWNTIME = false

  def up
    remove_foreign_key_if_exists :project_authorizations, column: :user_id
  end

  def down
    add_foreign_key :project_authorizations, :users, on_delete: :cascade
  end
end

second migration:

# frozen_string_literal: true

class TestTwo < ActiveRecord::Migration[6.0]
  include Gitlab::Database::MigrationHelpers

  DOWNTIME = false

  def up
    drop_table :project_authorizations
  end

  def down
    create_table :project_authorizations, primary_key: %i[user_id project_id access_level] do |t|
      t.references :user, type: :integer, null: false, index: false
      t.references :project, type: :integer, null: false, foreign_key: { on_delete: :cascade }
      t.integer :access_level, null: false
    end
  end
end

output:

➜  gitlab git:(pb-ci-check-reverse-migration-order) scripts/validate_migration_schema
$ git merge-base master HEAD
02d319763cb721574bb3b91d02e80eafb7ab339f

$ git diff --name-only --diff-filter=A 02d319763cb721574bb3b91d02e80eafb7ab339f -- db/migrate db/post_migrate
db/migrate/20210216193002_test_one.rb
db/post_migrate/20210216193019_test_two.rb

$ bin/rails db:migrate:down VERSION=20210216193019
== 20210216193019 TestTwo: reverting ==========================================
-- create_table(:project_authorizations, {:primary_key=>[:user_id, :project_id, :access_level]})
   -> 0.0091s
== 20210216193019 TestTwo: reverted (0.0091s) =================================


$ bin/rails db:migrate:down VERSION=20210216193002
== 20210216193002 TestOne: reverting ==========================================
-- add_foreign_key(:project_authorizations, :users, {:on_delete=>:cascade})
   -> 0.0049s
== 20210216193002 TestOne: reverted (0.0049s) =================================


$ git diff 02d319763cb721574bb3b91d02e80eafb7ab339f -- db/structure.sql

$ bin/rails db:migrate
== 20210216193002 TestOne: migrating ==========================================
-- foreign_keys(:project_authorizations)
   -> 0.0031s
-- remove_foreign_key(:project_authorizations, {:column=>:user_id})
   -> 0.0030s
== 20210216193002 TestOne: migrated (0.0061s) =================================

== 20210216193019 TestTwo: migrating ==========================================
-- drop_table(:project_authorizations)
   -> 0.0024s
== 20210216193019 TestTwo: migrated (0.0025s) =================================


$ git diff -- db/structure.sql

$ git add -A -n db/schema_migrations

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

Security

If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:

  • Label as security and @ mention @gitlab-com/gl-security/appsec
  • The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
  • Security reports checked/validated by a reviewer from the AppSec team
Edited by Albert Salim

Merge request reports