Skip to main content

在每个 PR 中强制执行迁移检查清单

构建一个仓库技能,让 Devin 在每次 PR(拉取请求)涉及数据库迁移时,捕获破坏性操作、验证回滚安全性,并校验架构更改。
AuthorCognition
Category核心 Devin
FeaturesSkills
1

创建迁移核对清单技能

仓库技能是一个 markdown 文件,你需要将其提交到任意仓库中的 .agents/skills/<your-skill>/ 目录下。Devin 能看到所有已连接仓库中的所有技能——你可以手动触发它们,或者当 Devin 检测到相关情况时自动触发。这个技能会精确告知 Devin 在打开或更新 PR 之前应该如何审查数据库迁移,从而捕捉到常规代码审查通常会遗漏的错误。在你的代码仓库中提交 .agents/skills/migration-checklist/migration-checklist.md 文件:
# 迁移安全检查清单

## 描述
在开启或更新拉取请求(PR)之前,检查当前 PR 中的每个数据库迁移是否存在安全问题。

## 使用时机
当 PR 差异中包含 `db/migrate/`(Rails)、`migrations/`(Django)或 `prisma/migrations/`(Prisma)中新增或修改的文件时,调用此技能。

## 检查清单

### 1. 检测破坏性操作
扫描每个迁移文件,查找以下内容:
- `DROP TABLE``drop_table`
- `DROP COLUMN``remove_column` 或列删除操作
- `TRUNCATE`
- 导致精度损失的数据类型变更(例如 `text``varchar(50)`

如发现上述任何情况,在 PR 中添加评论,标记该操作并确认迁移中是否包含数据备份步骤。

### 2. 验证外键索引
对于每个 `add_reference``add_foreign_key` 或以 `_id` 结尾的新列,确认存在对应的索引。如果不存在,请在提交前将其添加到迁移中。

### 3. 检查回滚安全性
- 在测试数据库上运行 `bin/rails db:migrate:rollback STEP=<n>`(其中 n 为新迁移的数量)。
- 如果回滚失败,添加 `down` 方法或可逆块后重试。
- 在 PR 描述中报告所有不可逆的迁移。

### 4. 验证 schema 文件是否为最新版本
运行迁移后,将 `db/schema.rb`(或 `structure.sql`)与 PR 中的版本进行差异比较。如果存在差异,请重新生成 schema 文件并将其包含在提交中。

### 5. 运行模型测试
执行 `bin/rails test test/models/`,捕获因 schema 变更导致验证或关联失效的问题。所有测试必须通过后方可开启 PR。
一旦这个文件被提交,Devin 就会将其视为一项可用技能。每当当前会话涉及此代码库中的迁移文件时,Devin 都可以自动触发该检查清单,或者你也可以在任何时候手动执行它。
2

在实际迁移中查看该技能的触发方式

当 Devin 处理会添加或修改迁移文件的任务时,它会读取 diff,匹配迁移检查清单技能,并在打开 PR 之前按照检查清单执行操作。实际执行过程如下:
  1. 扫描 diff — Devin 看到 db/migrate/ 中有新文件,并激活迁移检查清单技能
  2. 标记破坏性操作 — 该迁移移除了 legacy_email 列。Devin 添加了一条 PR 评论:
    remove_column :users, :legacy_email 是一个破坏性操作。 已验证:迁移包含数据备份步骤,会在删除前将值复制到 user_archives 中。
  3. 补充缺失索引 — 该迁移向 invoices 表添加了 account_id 列,但没有索引。Devin 将 add_index :invoices, :account_id 追加到迁移文件中
  4. 执行回滚 — Devin 在测试数据库上执行 bin/rails db:migrate:rollback STEP=1。回滚执行成功
  5. 重新生成 schema — Devin 运行 bin/rails db:schema:dump,检测到 db/schema.rb 中的 diff,并在提交中包含更新后的文件
  6. 运行模型测试 — 所有模型测试均通过。Devin 打开 PR,并附上每项检查结果的摘要
PR 描述中包含一个检查清单,展示哪些检查通过了、哪些是 Devin 修复的,这样审阅者就可以将精力集中在业务逻辑上,而不是迁移实现细节上。
3

将该技能适配到你的 ORM 和技术栈

上面的检查清单主要针对 Rails,但同样的结构适用于任何 ORM。请让 Devin 按你的技术栈重写这个技能:
4

逐步扩展检查清单

每一次迁移事故都能暴露出清单未覆盖的空白。每发生一次事故,就补充一条规则——只需要向 skill 文件提交一行更改。下面是团队在真实事故后常见的补充内容:
### 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.
由于 skill 文件位于你的代码仓库中,这些规则会走代码评审流程——整个团队共同决定要检查的内容,并且它始终与迁移工具保持同步。