关于 ship-it
ship-it 是面向代码项目的交付工作流技能,从变更审查推进到 PR 就绪,由人工负责合并。它按 prod 或 wip 等级执行不同步骤,并可在中断后根据分支、提交和 PR 状态恢复。
主要功能
- 01按顺序执行代码交付流程
- 02支持 prod 与 wip 等级
- 03涵盖审查、测试、文档和 lint
- 04提交推送并创建或更新 PR
- 05依据仓库状态恢复流程
适用场景
- 01将已完成的功能推进到 PR
- 02为生产项目执行完整交付检查
- 03从已有分支或 PR 状态继续工作
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ frappe/ skills --skill ship-it安装后在 Claude Code 中输入/ship-it确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
review/ask.mdcorrectness.mdtaste.mdverdict.mdscripts/watch-pr.shsteps/ci.mdintent.mdpr.mdreview.mdtest.md详细介绍
发布
你负责从“代码已完成”到“PR 已准备好交由人工合并”的整个流程。按顺序运行各个步骤。每个步骤都要对自己的修改负责,流程只向前推进。始终由人工合并。
级别
默认使用 prod 级别。级别参数(/ship-it wip 或 /ship-it prod)用于设置本次运行的级别。恢复运行时如果未提供级别参数,则使用 ## Review 标记中的级别(见“恢复运行”)。
- prod:已投入生产的项目。运行所有步骤。
- wip:个人项目或进行中的项目。跳过标记为 – 的步骤。
流程
| # | 步骤 | prod | wip | 详情 |
|---|---|---|---|---|
| 1 | 意图 | 用户确认 | 已记录,未确认 | steps/intent.md |
| 2 | Rebase | ✓ | ✓ | 下文 |
| 3 | Review | 正确性 + 品味 | 仅检查正确性和阻塞问题 | steps/review.md |
| 4 | 测试 | ✓ | – | steps/test.md |
| 5 | 文档 | ✓ | – | 下文 |
| 6 | Lint | ✓ | ✓ | 下文 |
| 7 | 提交并推送 | ✓ | ✓ | 下文 |
| 8 | PR | 完整正文 | Summary、Intent、Review | steps/pr.md |
| 9 | CI 和机器人 | CI,然后运行机器人循环 | 仅 CI | steps/ci.md |
到达某一步时再阅读该步骤的详情文件,不要提前阅读。
步骤 4 到 9 可能会在 Review 之后新增提交:测试修复、文档、Lint、CI 修复和机器人修复。在步骤 8 创建或更新 PR 之前,以及报告完成之前,将 HEAD 与最后一次 Review 的 sha 进行比较。如果之后有提交,按 steps/review.md 中的说明重新 Review <sha>..HEAD。然后在 ## Review 标记中填入新的 reviewed sha。在 prod 级别,如果这些提交改变了实时场景所涉及的行为,则按 steps/test.md 中的说明重新运行该场景,并在报告完成前替换 PR 正文中的证据。
完成表示:PR 已开启且准备就绪(不是草稿),## Review 标记指向 HEAD,CI 已通过,并且在 prod 级别下,机器人循环已按规则停止。向用户汇报并请其 Review 和合并。到此为止。
恢复运行
没有状态文件。分支、提交和 PR 就是记录。每次运行时,找到第一个未完成的步骤:
- 相对于基准分支没有领先的提交,且没有未提交的更改 → 没有需要发布的内容。说明这一点。
- 有属于此意图的未提交更改 → 先按步骤 7 的说明,将更改按逻辑分组并附上提交消息后提交。不要推送。混有其他工作的更改 → 按“运行位置”中的说明先询问。
- 阅读此分支的 PR(
gh pr view --json number,body,headRefOid,isDraft)。- 没有 PR → 从步骤 1 开始。
- PR 正文中有
## Intent→ 这就是该意图。除非用户提供了新意图,否则跳过步骤 1。 ## Review中的 `` 标记指向最后一次 Review 的提交。其后的提交(本地或已推送)→ 仅针对<sha>..HEAD重新运行 Review,然后继续向前。
- 本次运行的级别为 prod,且标记写明
tier=wip→ 步骤 1。Wip 未确认意图,只进行了部分 Review,并跳过了测试和文档步骤。步骤 3 需要再次 Review 全部更改,步骤 8 则编写完整的 prod 正文并将标记设为tier=prod。 - 其他情况:有尚未推送的提交 → 步骤 7。PR 是草稿 → 步骤 8。CI 失败或仍在运行 → 步骤 9。CI 已通过 → 执行步骤 9 的机器人循环(prod 级别)或完成(wip 级别)。
用一行告诉用户你从哪一步继续,以及原因。
运行位置
- 原地运行:检出的是功能分支或工作树,并且所有未提交的更改都属于此意图时。
- 先询问:当前位于默认分支,或未提交的更改混杂了此项工作和其他工作时。提出将此项工作移至新的工作树。只有用户同意后才创建。
- Frappe 应用位于 bench 中:普通的
git worktree对 bench 不可见。原地运行。
子代理
每位审查者和每位修复者都是全新的子代理,之前从未见过此对话。其提示词包含所需的一切信息:意图、记录的决策、差异范围,以及需要遵循的审查文件。修复者绝不能是报告问题的审查者,重新审查时也要使用新的子代理。
| Agent | 启动方式 |
|---|---|
| Claude Code | 使用 Agent 工具。 |
| Codex | 使用 spawn_agent。Codex 只有在收到指示后才会启动,因此要明确调用。 |
T3 Code(存在 t3-code MCP 工具时) | 使用 delegate_task,并设置 mode: "wait"。从 orchestrator_capabilities 中选择提供商和模型。 |
每个子代理都使用可用的最强模型。如果 Agent 能够使用其他提供商的模型,请将该模型交给正确性审查者:不同的模型系列能够发现第一个模型与作者共同犯下的错误。
问题与用户
审查者按 review/verdict.md 中的格式返回问题。无需询问即可修复 auto-fix 问题。收集某一步中的所有 ask-user 问题,并按照 review/ask.md 中的格式,在一条消息中询问用户。用户的答复会成为决策,执行过程中不得推翻这些决策。
内联步骤
2. 变基
运行 git fetch origin。如果存在 origin/<branch>,记录其 sha 供第 7 步使用,并纳入本地历史中缺少的远程提交。查找此克隆最后一次推送的提交:git reflog show --format='%H %gs' origin/<branch> | grep -m1 'update by push'。仅当本地分支自己的 reflog 中包含该 sha 时才使用它(git reflog show --format=%H <branch> | grep -qx <sha>);这表明该分支曾处于该提交。直到该提交为止的所有提交都已在本地历史中,可能已被较早的变基改写。其后的提交 <pushed sha>..origin/<branch> 是其他人推送的:逐个纳入,例如使用 git cherry-pick。如果该 sha 不是 origin/<branch> 的祖先(git merge-base --is-ancestor <sha> origin/<branch> 失败),则说明有人在你推送后改写了远程分支:停止并询问用户。如果没有这样的 sha,则纳入 HEAD..origin/<branch>。跳过其更改已包含在 HEAD 中的提交。然后变基到 origin/<base> 上。根据双方的意图解决冲突。如果冲突需要产品决策,请询问用户。变基后如果相对于基分支的差异为空,则停止:没有内容需要交付。
5. 文档(prod)
找出此次更改导致哪些内容过时:README、文档页面、AGENTS.md、更改附近的代码注释、示例。将每条过时信息修正在唯一的权威位置。将无法解决的问题报告为 ask-user 问题。
6. Lint
使用仓库自身的格式化工具和检查工具,并启用修复模式:查看 package.json 脚本、pyproject.toml、.pre-commit-config.yaml 和 CI 工作流,了解 CI 会运行哪些检查。最多尝试修复 3 次。如果仓库未配置检查工具,则跳过。
7. 提交并推送
按逻辑分组提交,并使用约定式提交消息(feat:、fix:、refactor:、docs:、test:、chore:)。审查修复遵循 steps/review.md 中修复循环的提交规则。将 tidy: 提交与行为变更分开。提交消息只描述变更。
安全推送:
- 如果本次运行尚未记录
origin/<branch>的 sha(即从步骤 7 恢复运行),请先获取远程更新、记录 sha,并按步骤 2 纳入远程工作。否则,执行git fetch origin。 - 将
origin/<branch>与记录的 sha 比较。如果远程分支有变动,则表示你尚未纳入远程工作:返回步骤 2。 - 如果
origin/<branch>不存在,或它是HEAD的祖先,则直接推送。否则,HEAD在本次运行或更早的运行中重写了已推送的提交:使用--force-with-lease=<branch>:<recorded sha>推送。 - 如果推送因获取更新后远程发生变化而被拒绝(
non-fast-forward、fetch first或stale info),返回步骤 2。其他任何拒绝原因(权限、分支保护、服务器端钩子)都不会因变基而改变。停止并向用户显示错误。 - 推送后,将已推送的 sha 记录为新的记录值,以便之后步骤 9 的推送与之比较。
- 记录推送时间。 steps/ci.md 中的机器人循环会用到它。