codebase-migrate

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Codebase Migrate

代码库迁移

Coordinate framework upgrades, API renames, config rewrites, and structural refactors across hundreds of files. Local edits are driven by the agent; the Composio CLI handles the surrounding ceremony: tracking issues, per-batch PRs, and CI verification.
跨数百个文件协调框架升级、API重命名、配置重写以及结构重构。本地编辑由Agent驱动;Composio CLI处理相关配套工作:问题跟踪、批量PR以及CI验证。

When to Use

适用场景

  • Framework upgrade (React 17 → 19, Node 18 → 22, Django 4 → 5).
  • API rename across a monorepo (e.g.,
    getUserById
    users.byId
    ).
  • Config/format migration (webpack → vite, eslint → biome, jest → vitest).
  • Any "change 200 files the same way" task that needs to ship in reviewable slices.
  • 框架升级(React 17 → 19、Node 18 → 22、Django 4 → 5)。
  • 单体仓库中的API重命名(例如:
    getUserById
    users.byId
    )。
  • 配置/格式迁移(webpack → vite、eslint → biome、jest → vitest)。
  • 任何需要拆分为可审查片段交付的“以相同方式修改200个文件”的任务。

Prereqs

前置条件

bash
curl -fsSL https://composio.dev/install | bash
composio login
composio link github        # for PRs + CI status
composio link linear        # or jira — for migration tracking
Local tools the agent will use directly:
git
,
rg
,
jscodeshift
/
ts-morph
/
comby
/
ast-grep
(language-appropriate), and your test runner.
bash
curl -fsSL https://composio.dev/install | bash
composio login
composio link github        # 用于PR与CI状态同步
composio link linear        # 或jira — 用于迁移进度跟踪
Agent将直接使用的本地工具:
git
rg
jscodeshift
/
ts-morph
/
comby
/
ast-grep
(根据语言选择合适工具),以及你的测试运行器。

Planning Phase

规划阶段

  1. Define the transform precisely. Bad: "migrate to vitest." Good: "replace
    jest.mock
    with
    vi.mock
    , swap
    jest.fn()
    for
    vi.fn()
    , rename
    jest.config.js
    vitest.config.ts
    using template X."
  2. Scope the blast radius:
    bash
    rg -l 'jest\.(mock|fn|spyOn)' | wc -l
    rg -l 'from "jest"' | sort
  3. File a tracking issue:
    bash
    composio execute LINEAR_CREATE_ISSUE -d '{
      "teamId":"TEAM_ID",
      "title":"Migrate test runner: jest → vitest",
      "description":"Batches of ~25 files. Checkpoint after each PR lands green."
    }'
  1. 精准定义转换规则。模糊表述:“迁移到vitest”。清晰表述:“将
    jest.mock
    替换为
    vi.mock
    ,将
    jest.fn()
    替换为
    vi.fn()
    ,使用模板X将
    jest.config.js
    重命名为
    vitest.config.ts
    。”
  2. 确定影响范围
    bash
    rg -l 'jest\.(mock|fn|spyOn)' | wc -l
    rg -l 'from "jest"' | sort
  3. 创建跟踪工单
    bash
    composio execute LINEAR_CREATE_ISSUE -d '{
      "teamId":"TEAM_ID",
      "title":"Migrate test runner: jest → vitest",
      "description":"Batches of ~25 files. Checkpoint after each PR lands green."
    }'

Execute in Reviewable Batches

分批次执行与审查

Loop: pick N files → transform → test → PR → wait for green → merge → next batch.
bash
undefined
循环流程:选择N个文件 → 转换 → 测试 → 创建PR → 等待CI通过 → 合并 → 下一批次。
bash
undefined

Batch helper: first 25 untouched files matching the pattern

批次辅助工具:选取前25个未处理的匹配文件

BATCH=$(rg -l 'jest.mock' | grep -v done.list | head -25) echo "$BATCH" > batch.list

The agent runs the codemod on `batch.list`, then:

```bash
git checkout -b migrate/vitest-batch-03
xargs < batch.list codemod-runner   # e.g. jscodeshift / ts-morph / comby
npm test -- --changed
git add -A && git commit -m "migrate(test): jest → vitest (batch 3)"
git push -u origin migrate/vitest-batch-03

composio execute GITHUB_CREATE_A_PULL_REQUEST -d '{
  "owner":"acme","repo":"app",
  "head":"migrate/vitest-batch-03","base":"main",
  "title":"migrate(test): jest → vitest (batch 3)",
  "body":"Part of LIN-482. 25 files. Codemod: `transforms/jest-to-vitest.ts`."
}'
Then poll CI and merge when green:
bash
composio execute GITHUB_LIST_WORKFLOW_RUNS_FOR_A_REPOSITORY \
  -d '{"owner":"acme","repo":"app","branch":"migrate/vitest-batch-03"}'
BATCH=$(rg -l 'jest.mock' | grep -v done.list | head -25) echo "$BATCH" > batch.list

Agent对`batch.list`中的文件运行代码修改工具,然后执行:

```bash
git checkout -b migrate/vitest-batch-03
xargs < batch.list codemod-runner   # 例如 jscodeshift / ts-morph / comby
npm test -- --changed
git add -A && git commit -m "migrate(test): jest → vitest (batch 3)"
git push -u origin migrate/vitest-batch-03

composio execute GITHUB_CREATE_A_PULL_REQUEST -d '{
  "owner":"acme","repo":"app",
  "head":"migrate/vitest-batch-03","base":"main",
  "title":"migrate(test): jest → vitest (batch 3)",
  "body":"Part of LIN-482. 25 files. Codemod: `transforms/jest-to-vitest.ts`."
}'
然后轮询CI状态,待通过后合并:
bash
composio execute GITHUB_LIST_WORKFLOW_RUNS_FOR_A_REPOSITORY \
  -d '{"owner":"acme","repo":"app","branch":"migrate/vitest-batch-03"}'

Workflow Script

工作流脚本

scripts/migrate-batch.ts
, run per batch via
composio run --file scripts/migrate-batch.ts -- --batch 3
:
ts
const batch = process.argv[process.argv.indexOf("--batch") + 1];

const pr = await execute("GITHUB_CREATE_A_PULL_REQUEST", {
  owner: "acme", repo: "app",
  head: `migrate/vitest-batch-${batch}`, base: "main",
  title: `migrate(test): jest → vitest (batch ${batch})`,
  body: `Part of LIN-482. See transforms/jest-to-vitest.ts.`
});

await execute("LINEAR_CREATE_COMMENT", {
  issueId: "LIN-482",
  body: `Opened PR #${pr.number}: ${pr.html_url}`
});
scripts/migrate-batch.ts
,通过
composio run --file scripts/migrate-batch.ts -- --batch 3
逐批次运行:
ts
const batch = process.argv[process.argv.indexOf("--batch") + 1];

const pr = await execute("GITHUB_CREATE_A_PULL_REQUEST", {
  owner: "acme", repo: "app",
  head: `migrate/vitest-batch-${batch}`, base: "main",
  title: `migrate(test): jest → vitest (batch ${batch})`,
  body: `Part of LIN-482. See transforms/jest-to-vitest.ts.`
});

await execute("LINEAR_CREATE_COMMENT", {
  issueId: "LIN-482",
  body: `Opened PR #${pr.number}: ${pr.html_url}`
});

Safety Rails

安全保障措施

  • One transform per PR. Never mix a rename with a format change.
  • Keep a
    done.list
    of files already migrated so the next batch skips them.
  • Run the full test suite on the last batch, even if per-batch PRs ran
    --changed
    .
  • Codemod first, hand-edit second. If the codemod misses 3 files, patch them manually and note it in the PR body.
  • Roll back per-batch, not globally. Each PR should revert cleanly.
  • 每个PR仅包含一项转换。切勿将重命名与格式修改混在一起。
  • 维护
    done.list
    文件
    :记录已完成迁移的文件,以便下一批次跳过它们。
  • 最后一批次运行完整测试套件:即使单批次PR已运行
    --changed
    测试。
  • 先使用代码修改工具,再手动编辑:如果代码修改工具遗漏了3个文件,手动修复并在PR描述中注明。
  • 按批次回滚,而非全局回滚:每个PR都应能干净地回退。

Verification Loop

验证循环

After each merge:
bash
rg 'jest\.(mock|fn|spyOn)' | wc -l     # should trend to 0
npm test                                # full suite
composio execute GITHUB_LIST_WORKFLOW_RUNS_FOR_A_REPOSITORY \
  -d '{"owner":"acme","repo":"app","branch":"main","event":"push"}' \
  | jq '.workflow_runs[0].conclusion'
每次合并后:
bash
rg 'jest\.(mock|fn|spyOn)' | wc -l     # 数值应逐渐趋近于0
npm test                                # 完整测试套件
composio execute GITHUB_LIST_WORKFLOW_RUNS_FOR_A_REPOSITORY \
  -d '{"owner":"acme","repo":"app","branch":"main","event":"push"}' \
  | jq '.workflow_runs[0].conclusion'

Troubleshooting

故障排查

  • Codemod regex catches too much → switch to AST-based tooling (
    ast-grep
    ,
    ts-morph
    ) for structural matches.
  • Tests pass locally, CI fails → pin Node/Python version parity; check
    .nvmrc
    /
    pyproject.toml
    .
  • PR too big to review → cut batch size in half; maintainers won't review 800-line diffs.
  • Conflicts between batches → rebase the open batch before merging the current one; never force-push merged batches.
Full CLI reference: docs.composio.dev/docs/cli
  • 代码修改工具的正则匹配范围过大 → 切换到基于AST的工具(
    ast-grep
    ts-morph
    )进行结构化匹配。
  • 本地测试通过,但CI失败 → 固定Node/Python版本保持一致;检查
    .nvmrc
    /
    pyproject.toml
  • PR过大难以审查 → 将批次大小减半;维护者不会审查800行的差异。
  • 批次间存在冲突 → 在合并当前批次前,重新基于主分支变基未合并的批次;切勿强制推送已合并的批次。
完整CLI参考文档:docs.composio.dev/docs/cli