FEATURE: Post deployment migrations. (#6406)

This moves us away from the delayed drops pattern which
was problematic on two counts. First, it uses a hardcoded "delay for"
duration which may be too short for certain deployment strategies.
Second, delayed drop doesn't ensure that it only runs after
the latest application code has been deployed. If the migration runs
and the application code fails to deploy, running the migration after
"delay for" has been met will cause the application to blow up.

The new strategy allows post deployment migrations to be skipped if the
env `SKIP_POST_DEPLOYMENT_MIGRATIONS` is provided.

```
SKIP_POST_DEPLOYMENT_MIGRATIONS=1 rake db:migrate
-> deploy app servers
SKIP_POST_DEPLOYMENT_MIGRATIONS=0 rake db:migrate
```

To aid with the generation of a post deployment migration, a generator
has been added. Simply run `rails generate post_migration`.
This commit is contained in:
Guo Xiang Tan
2018-10-08 15:47:38 +08:00
committed by GitHub
parent 9bbc1ae7b2
commit 40fa96777d
26 changed files with 260 additions and 738 deletions

View File

@@ -16,13 +16,33 @@ class Migration::SafeMigrate
end
def migrate(direction)
if direction == :up && version && version > UNSAFE_VERSION && @@enable_safe != false
if direction == :up &&
version && version > UNSAFE_VERSION &&
@@enable_safe != false &&
!is_post_deploy_migration?
Migration::SafeMigrate.enable!
end
super
ensure
Migration::SafeMigrate.disable!
end
private
def is_post_deploy_migration?
method =
if self.respond_to?(:up)
:up
elsif self.respond_to?(:change)
:change
end
self.method(method).source_location.first.include?(
Discourse::DB_POST_MIGRATE_PATH
)
end
end
module NiceErrors
@@ -90,7 +110,7 @@ class Migration::SafeMigrate
-------------------------------------------------------------------------------------
An attempt was made to drop or rename a table in a migration
SQL used was: '#{sql}'
Please use the deferred pattern using Migration::TableDropper in db/seeds to drop
Please generate a post deployment migration using `rails g post_migration` to drop
or rename the table.
This protection is in place to protect us against dropping tables that are currently
@@ -103,7 +123,8 @@ class Migration::SafeMigrate
-------------------------------------------------------------------------------------
An attempt was made to drop or rename a column in a migration
SQL used was: '#{sql}'
Please use the deferred pattern using Migration::ColumnDropper in db/seeds to drop
Please generate a post deployment migration using `rails g post_migration` to drop
or rename columns.
Note, to minimize disruption use self.ignored_columns = ["column name"] on your