Skip to main content

Enforce a Migration Checklist on Every PR

Build a repo skill that makes Devin catch destructive operations, verify rollback safety, and validate schema changes whenever a PR touches database migrations.
AuthorCognition
CategoryCore Devin
FeaturesSkills
1

Create the migration checklist skill

A repository skill is a markdown file you commit to .agents/skills/<your-skill>/ in any of your repos. Devin sees all skills across all connected repositories — you can trigger them manually or Devin can choose to trigger them automatically when it detects a relevant situation. This skill tells Devin exactly how to review database migrations before opening or updating a PR — catching the mistakes that code review usually misses.Commit .agents/skills/migration-checklist/migration-checklist.md to your repository:
# Migration Safety Checklist

## Description
Review every database migration in the current PR for safety issues
before opening or updating the pull request.

## When to use
Invoke this skill whenever the PR diff includes new or modified files
in `db/migrate/` (Rails), `migrations/` (Django), or
`prisma/migrations/` (Prisma).

## Checklist

### 1. Detect destructive operations
Scan each migration file for:
- `DROP TABLE` or `drop_table`
- `DROP COLUMN`, `remove_column`, or column removal
- `TRUNCATE`
- Data-type changes that lose precision (e.g. `text``varchar(50)`)

If any are found, add a PR comment flagging the operation and
confirming whether a data backup step exists in the migration.

### 2. Verify foreign-key indexes
For every `add_reference`, `add_foreign_key`, or new column ending
in `_id`, confirm a matching index exists. If not, add one to the
migration before committing.

### 3. Check rollback safety
- Run `bin/rails db:migrate:rollback STEP=<n>` (where n = number of
  new migrations) against the test database.
- If rollback fails, add a `down` method or reversible block and
  retry.
- Report any irreversible migrations in the PR description.

### 4. Validate schema file is up-to-date
After running migrations, diff `db/schema.rb` (or `structure.sql`)
against the version in the PR. If they differ, regenerate the schema
file and include it in the commit.

### 5. Run model tests
Execute `bin/rails test test/models/` to catch validations or
associations broken by schema changes. All tests must pass before
the PR is opened.
Once this file is committed, Devin sees it as an available skill. Whenever a session touches migration files in this repo, Devin can trigger the checklist automatically — or you can invoke it manually at any point.
2

See the skill trigger on a real migration

When Devin works on a task that adds or modifies a migration file, it reads the diff, matches the migration checklist skill, and follows the checklist before opening the PR. Here’s what that looks like in practice:
  1. Scans the diff — Devin sees a new file in db/migrate/ and activates the migration checklist skill
  2. Flags a destructive operation — The migration removes a legacy_email column. Devin adds a PR comment:
    remove_column :users, :legacy_email is a destructive operation. Verified: migration includes a data backup step copying values to user_archives before removal.
  3. Adds a missing index — The migration adds account_id to the invoices table but has no index. Devin appends add_index :invoices, :account_id to the migration file
  4. Runs rollback — Devin executes bin/rails db:migrate:rollback STEP=1 against the test database. It passes
  5. Regenerates the schema — Devin runs bin/rails db:schema:dump, detects a diff in db/schema.rb, and includes the updated file in the commit
  6. Runs model tests — All model tests pass. Devin opens the PR with a summary of each check
The PR description includes a checklist showing what passed and what Devin fixed, so reviewers can focus on the business logic instead of the migration mechanics.
3

Adapt the skill for your ORM and stack

The checklist above targets Rails, but the same structure works for any ORM. Ask Devin to rewrite the skill for your stack:
4

Extend the checklist over time

Every migration incident reveals a gap the checklist didn’t cover. After each one, add a rule — it’s a one-line commit to the skill file.Here are common additions teams make after real incidents:
### 6. Enforce migration naming conventions
Reject migrations that don't follow the pattern
`YYYYMMDDHHMMSS_verb_noun.rb` (e.g. `add_index_to_invoices`).
Rename the file if needed.

### 7. Check for long-running locks
Flag any `add_column` on tables with >1M rows that doesn't use
`disable_ddl_transaction!` (Postgres) or `ALGORITHM=INPLACE`
(MySQL). Large tables need non-blocking migrations.

### 8. Require a migration test
Ensure a corresponding test file exists at
`test/migrations/YYYYMMDDHHMMSS_migration_name_test.rb`.
If missing, generate a skeleton test that runs the migration
up and down.
Because the skill file lives in your repo, these rules go through code review — your entire team agrees on what gets checked, and it’s always in sync with your migration tooling.