Skip to content

feat: add strong_migrations gem to prevent unsafe migration deploys - #2774

Merged
mroderick merged 1 commit into
masterfrom
feature/strong-migrations
Aug 4, 2026
Merged

feat: add strong_migrations gem to prevent unsafe migration deploys#2774
mroderick merged 1 commit into
masterfrom
feature/strong-migrations

Conversation

@mroderick

@mroderick mroderick commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

What

Adds the strong_migrations gem to block dangerous migration patterns before they reach production.

Scope

  • Checks all migrations from 2026-01-01 onwards (start_after = 20260101000000)
  • Targets PostgreSQL 16 (Heroku production version)
  • Active in all environments including test (catches issues in CI)

Existing violations acknowledged

Six 2026 migrations already deployed contain patterns strong_migrations flags. Each is wrapped in safety_assured { ... } — no logic changes, just marking them as reviewed:

  • execute with DELETE for duplicate cleanup
  • update_all inside a schema migration for data backfill
  • add_index without algorithm: :concurrently
  • remove_index without algorithm: :concurrently
  • drop_table on meeting_talks
  • Data cleanup loops (delete_all) inside schema migrations

Reviewer hint: it's a lot easier to review this part of the PR, if you hide the whitespace changes 😄

What this prevents going forward

  • Adding non-nullable columns without defaults to existing tables
  • Adding indexes without algorithm: :concurrently on large tables
  • Data backfills inside schema migrations
  • drop_table / remove_column without a staged removal process
  • Raw execute SQL without review

@mroderick
mroderick force-pushed the feature/strong-migrations branch 2 times, most recently from 21b1648 to ad9b1eb Compare August 1, 2026 06:56
@mroderick
mroderick marked this pull request as ready for review August 1, 2026 07:10
@mroderick
mroderick requested a review from olleolleolle August 1, 2026 07:10
@mroderick

Copy link
Copy Markdown
Collaborator Author

@olleolleolle do you think it makes sense to fix all the existing migrations, going all the way back to the dawn of time?

@olleolleolle

olleolleolle commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

@mroderick At work, we ditch migration files we have used up, after some time. We rely on db/schema.rb instead, rather than a group of migration files in order.

So, a step could be: find a migration file that needs a fix, and remove it AND its predecessors.

@mroderick

Copy link
Copy Markdown
Collaborator Author

At work, we ditch migration files we have used up, after some time. We rely on db/schema.rb instead, rather than a group of migration files in order.

So, a step could be: find a migration file that needs a fix, and remove it AND its predecessors.

So, you keep the migrations around in case you need to run the down migration, and once you're confident that you don't, you remove them?

Do you use tools like squasher (unmaintained)?

@olleolleolle

Copy link
Copy Markdown
Collaborator

At work, we ditch migration files we have used up, after some time. We rely on db/schema.rb instead, rather than a group of migration files in order.
So, a step could be: find a migration file that needs a fix, and remove it AND its predecessors.

So, you keep the migrations around in case you need to run the down migration, and once you're confident that you don't, you remove them?

Yeah, something like that - we don’t have a schedule for these “lose the migration files” events. We do it when it “feels right”.

Do you use tools like squasher (unmaintained)?

We don’t use a squasher tool.

…oduction

Install strong_migrations 2.8.0 and configure it to analyze all
migrations from 2026-01-01 onwards. Target PostgreSQL 16 (Heroku
production version).

Wrap existing 2026 migrations that violate safety rules with
`safety_assured` blocks — these were already deployed and are
acknowledged as reviewed. No migration logic is changed.

Violations wrapped:
- execute SQL with DELETE (duplicate cleanup)
- update_all inside migration (sponsor backfill)
- add_index without algorithm: :concurrently
- remove_index without algorithm: :concurrently
- drop_table (meeting_talks removal)
- data cleanup loops inside schema migrations
@mroderick
mroderick force-pushed the feature/strong-migrations branch from ad9b1eb to 3118952 Compare August 4, 2026 08:04
@mroderick
mroderick merged commit cbf7d3c into master Aug 4, 2026
9 checks passed
@mroderick
mroderick deleted the feature/strong-migrations branch August 4, 2026 08:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants