Skip to content

Instantly share code, notes, and snippets.

@anujbiyani
Last active April 16, 2024 23:04
Show Gist options
  • Select an option

  • Save anujbiyani/25f3d3096fe76f91fe271b2a722b4cc0 to your computer and use it in GitHub Desktop.

Select an option

Save anujbiyani/25f3d3096fe76f91fe271b2a722b4cc0 to your computer and use it in GitHub Desktop.

Revisions

  1. anujbiyani revised this gist Jan 22, 2021. 3 changed files with 0 additions and 68 deletions.
    24 changes: 0 additions & 24 deletions step_1.rb
    Original file line number Diff line number Diff line change
    @@ -1,24 +0,0 @@
    common_ancestor_sha = `git merge-base HEAD origin/master`.strip

    commit_messages = `git log --pretty=format:"%B" #{common_ancestor_sha}..HEAD`
    if commit_messages.include?("[skip schema checks]")
    puts "Found [skip schema checks] tag, skipping db migration check."
    exit
    end

    changed_files = `git diff --name-only HEAD #{common_ancestor_sha}`.split("\n")
    migration_files = changed_files.select { |path| File.dirname(path) == "db/migrate" }
    schema_file = changed_files.detect { |path| path.include?("db/schema.rb") }

    if schema_file && migration_files.none?
    puts "DB schema file changed, but no migration files are present. All changes to the schema should be driven by a migration file."
    puts "If you really mean to change the schema without a migration, e.g. you are fixing a bad schema, then please disable this check in this PR and re-enable it after this PR is merged."
    puts "Failing."

    exit 1
    end

    unless migration_files.any?
    puts "Did not find any migration files in the list of files changed. Exiting."
    exit
    end
    25 changes: 0 additions & 25 deletions step_2.rb
    Original file line number Diff line number Diff line change
    @@ -1,25 +0,0 @@
    versions = migration_files.map { |path| Pathname.new(path).basename.to_s.split("_").first }.sort

    human_formatted_versions = versions.join(", ")
    puts "Testing migrations <#{human_formatted_versions}>"

    puts "First step: rolling back each migration and checking the DB schema file."
    versions.reverse_each do |version|
    success = system("bundle exec rake db:migrate:down VERSION=#{version}")
    unless success
    puts "When rolling back the migration <#{version}>, the command failed."
    exit 1
    end
    end

    diff = `git diff #{common_ancestor_sha} -- db/schema.rb`
    if diff.empty?
    puts "Rolling back migrations resulted in the same DB schema file as master."
    else
    raise <<~MSG
    When rolling back the migrations <#{human_formatted_versions}>, the DB schema file did not match master. We observed the following differences:
    #{diff}
    Please ensure reversing your migrations results in the same db/schema.rb file as master.
    MSG
    end
    19 changes: 0 additions & 19 deletions step_3.rb
    Original file line number Diff line number Diff line change
    @@ -1,19 +0,0 @@
    puts "Last step: running each migration forwards, and checking the DB schema file and missing annotations."
    versions.each do |version|
    success = system("bundle exec rake MISC_TEST=true db:migrate:up VERSION=#{version}")
    unless success
    puts "When running migration <#{version}> forward, the command failed."
    exit 1
    end
    end

    if `git status --porcelain`.empty?
    puts "Running migrations forwards resulted in no changes, so your DB schema file is stable and annotations have been checked-in."
    else
    raise <<~MSG
    Running migrations forwards resulted in the following changes:
    #{`git diff`}
    Either your DB schema file is not stable (aka if you were to merge this branch to master and another dev pulled your changes and ran migrations, their schema file would differ) or you have not checked in annotations.
    MSG
    end
  2. anujbiyani revised this gist Jan 22, 2021. 3 changed files with 68 additions and 0 deletions.
    24 changes: 24 additions & 0 deletions step_1.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    common_ancestor_sha = `git merge-base HEAD origin/master`.strip

    commit_messages = `git log --pretty=format:"%B" #{common_ancestor_sha}..HEAD`
    if commit_messages.include?("[skip schema checks]")
    puts "Found [skip schema checks] tag, skipping db migration check."
    exit
    end

    changed_files = `git diff --name-only HEAD #{common_ancestor_sha}`.split("\n")
    migration_files = changed_files.select { |path| File.dirname(path) == "db/migrate" }
    schema_file = changed_files.detect { |path| path.include?("db/schema.rb") }

    if schema_file && migration_files.none?
    puts "DB schema file changed, but no migration files are present. All changes to the schema should be driven by a migration file."
    puts "If you really mean to change the schema without a migration, e.g. you are fixing a bad schema, then please disable this check in this PR and re-enable it after this PR is merged."
    puts "Failing."

    exit 1
    end

    unless migration_files.any?
    puts "Did not find any migration files in the list of files changed. Exiting."
    exit
    end
    25 changes: 25 additions & 0 deletions step_2.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,25 @@
    versions = migration_files.map { |path| Pathname.new(path).basename.to_s.split("_").first }.sort

    human_formatted_versions = versions.join(", ")
    puts "Testing migrations <#{human_formatted_versions}>"

    puts "First step: rolling back each migration and checking the DB schema file."
    versions.reverse_each do |version|
    success = system("bundle exec rake db:migrate:down VERSION=#{version}")
    unless success
    puts "When rolling back the migration <#{version}>, the command failed."
    exit 1
    end
    end

    diff = `git diff #{common_ancestor_sha} -- db/schema.rb`
    if diff.empty?
    puts "Rolling back migrations resulted in the same DB schema file as master."
    else
    raise <<~MSG
    When rolling back the migrations <#{human_formatted_versions}>, the DB schema file did not match master. We observed the following differences:
    #{diff}
    Please ensure reversing your migrations results in the same db/schema.rb file as master.
    MSG
    end
    19 changes: 19 additions & 0 deletions step_3.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,19 @@
    puts "Last step: running each migration forwards, and checking the DB schema file and missing annotations."
    versions.each do |version|
    success = system("bundle exec rake MISC_TEST=true db:migrate:up VERSION=#{version}")
    unless success
    puts "When running migration <#{version}> forward, the command failed."
    exit 1
    end
    end

    if `git status --porcelain`.empty?
    puts "Running migrations forwards resulted in no changes, so your DB schema file is stable and annotations have been checked-in."
    else
    raise <<~MSG
    Running migrations forwards resulted in the following changes:
    #{`git diff`}
    Either your DB schema file is not stable (aka if you were to merge this branch to master and another dev pulled your changes and ran migrations, their schema file would differ) or you have not checked in annotations.
    MSG
    end
  3. anujbiyani created this gist Jan 22, 2021.
    74 changes: 74 additions & 0 deletions ensure_stable_schema_migrations.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,74 @@
    #!/usr/bin/env ruby

    require "pathname"

    common_ancestor_sha = `git merge-base HEAD origin/master`.strip

    commit_messages = `git log --pretty=format:"%B" #{common_ancestor_sha}..HEAD`
    if commit_messages.include?("[skip schema checks]")
    puts "Found [skip schema checks] tag, skipping db migration check."
    exit
    end

    changed_files = `git diff --name-only HEAD #{common_ancestor_sha}`.split("\n")
    migration_files = changed_files.select { |path| File.dirname(path) == "db/migrate" }
    schema_file = changed_files.detect { |path| path.include?("db/schema.rb") }

    if schema_file && migration_files.none?
    puts "DB schema file changed, but no migration files are present. All changes to the schema should be driven by a migration file."
    puts "If you really mean to change the schema without a migration, e.g. you are fixing a bad schema, then please disable this check in this PR and re-enable it after this PR is merged."
    puts "Failing."

    exit 1
    end

    unless migration_files.any?
    puts "Did not find any migration files in the list of files changed. Exiting."
    exit
    end

    versions = migration_files.map { |path| Pathname.new(path).basename.to_s.split("_").first }.sort

    human_formatted_versions = versions.join(", ")
    puts "Testing migrations <#{human_formatted_versions}>"

    puts "First step: rolling back each migration and checking the DB schema file."
    versions.reverse_each do |version|
    success = system("bundle exec rake db:migrate:down VERSION=#{version}")
    unless success
    puts "When rolling back the migration <#{version}>, the command failed."
    exit 1
    end
    end

    diff = `git diff #{common_ancestor_sha} -- db/schema.rb`
    if diff.empty?
    puts "Rolling back migrations resulted in the same DB schema file as master."
    else
    raise <<~MSG
    When rolling back the migrations <#{human_formatted_versions}>, the DB schema file did not match master. We observed the following differences:
    #{diff}
    Please ensure reversing your migrations results in the same db/schema.rb file as master.
    MSG
    end

    puts "Last step: running each migration forwards, and checking the DB schema file and missing annotations."
    versions.each do |version|
    success = system("bundle exec rake MISC_TEST=true db:migrate:up VERSION=#{version}")
    unless success
    puts "When running migration <#{version}> forward, the command failed."
    exit 1
    end
    end

    if `git status --porcelain`.empty?
    puts "Running migrations forwards resulted in no changes, so your DB schema file is stable and annotations have been checked-in."
    else
    raise <<~MSG
    Running migrations forwards resulted in the following changes:
    #{`git diff`}
    Either your DB schema file is not stable (aka if you were to merge this branch to master and another dev pulled your changes and ran migrations, their schema file would differ) or you have not checked in annotations.
    MSG
    end