Skip to content

TandaHQ/migration_signature

Repository files navigation

Migration Signature

Sign your Rails migrations with file content, so no untested migrations make it out of CI.

About

Have you ever had a migration like the following, which you've tested, run, and are sure behaves normally, which is committed on your branch, and ready to go to production.

class MyMigration < ActiveRecord::Migration[5.2]
  def change
    do_something_safe
  end
end

Then, right before you merge your branch you decide to swap out the method in your migration for another method, forgetting to rollback and run the migration again.

class MyMigration < ActiveRecord::Migration[5.2]
  def change
    do_something_dangerous
  end
end

Because the migration is already 'up' and changes to structure.sql or schema.rb are committed, it's unlikely your test environment will ever re-execute the code in the change method. So the first time your do_something_dangerous method gets executed will be when this migration is run in production.

To get around this issue, Tanda introduced migration 'signatures'. A hash of the migration's AST stored as a comment in the migration file itself.

When the migration file is initially created and run, a signature gets added automatically to the top of the file:

# migration_signature: 22e8a816f8db8d51cec29fca5e8c08f7

class MyMigration < ActiveRecord::Migration[5.2]
  def change
    do_something_safe
  end
end

If the contents of the migration change, the signature will become invalid, meaning we can pick up un-run migrations in CI before sending them to production.

Installation

Add this line to your application's Gemfile:

gem 'migration_signature', group: :development

And then execute:

bundle

Or install it yourself as:

gem install migration_signature

Usage

Migration signatures will automatically be prepended to migration files when the up migration is run. To check the generated signatures match the migration file contents, add the following to your CI pipeline or pre-commit hook:

bundle exec migration_signature check

This command will either exit successfully or exit with code 1 and an error message.

> bundle exec migration_signature check

Missing or invalid migration signature in migration: 20190621040327_my_migration.rb. Please re-run your migration to receive an updated signature.

Configuration

You may wish to ignore specific migration files based on age or other factors. You can configure which migration files get ignored by creating a .migration_signature.yml file in the root of your repo (or from whatever) the working directory is when the gem is invoked.

# .migration_signature.yml
ignore:
  - '/full/path/to/repo/db/migrate/20190621040327_my_migration_1.rb'
  - 'db/migrate/20190621040328_my_migration_2.rb'
  - !ruby/regexp /db\/migrate\/201[2-4].*$/ # ignore migrations from 2012 - 2014

About

Generate signatures for Rails migration files when they are run and check them in CI.

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published