关于 ship-it
指导维护者审查、修复、验证并合并 Pull Request 的技能。它要求重复进行代码审查、验证所推送提交的 CI、恢复工作区,并清理任务期间启动的进程。
主要功能
- 01PR 检查与分支处理
- 02基于阻塞项的审查决策
- 03迭代审查与修复
- 04测试和 CI 验证
- 05工作区及进程清理
- 06问题跟踪与完成报告
适用场景
- 01审查并完成 PR
- 02在维护者分支修复审查问题
- 03合并前验证 CI
- 04清理任务启动的服务与数据库
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ vectorize-io/ hindsight --skill ship-it安装后在 Claude Code 中输入/ship-it确认已加载。
详细介绍
发布
输入:PR 编号或 URL,也可以不输入——此时使用当前分支的 PR(不带参数运行 gh pr view 即可解析)。如果当前分支还没有 PR,就推送该分支并使用 gh pr create 创建 PR(仅限维护者分支),然后继续。目标:合并 PR,修复所有代码审查发现的问题,并确保 CI 通过。
0b. 如果变更有流程,描述中应配一张图
如果 PR 改变了某件事的流程——例如请求路径、后台任务,或某项功能逐步执行的过程——图片比差异内容更容易说明。使用 figure 技能:编写 JSON 规范,渲染一张动画 SVG,并将其放在 PR 描述顶部。无需上传或点击,图片就会在描述中播放。
请使用提交 SHA而非分支名引用图片,否则分支在合并时被删除后,图片也会失效:https://raw.githubusercontent.com/<owner>/<repo>/<sha>/<path>.svg。如果 SVG 本身不属于此次变更,就不要将它提交到仓库——先渲染;只有在它确实属于变更时才将其提交到 PR 分支,否则请确保描述中的图片固定引用包含该图片的提交。
对于没有流程变化的修复,请跳过此步骤,例如一行保护逻辑、依赖升级或拼写错误。
0. 阻塞项规则(适用于每个步骤)
阻塞项是指修复后会违背 PR 目标的问题——代码审查原则认为 PR 要实现的目标本身有误(例如,PR 的核心目标是使用原始 SQL 的处理程序、新增咨询锁、返回元组的 API、通过 SQL 断言的测试,或移除银行范围限定),或者修复它意味着要重写或移除该功能,而不是对其进行完善。
遇到阻塞项时:**立即停止。**不要推送、不要合并,也不要只修复一部分。告诉用户 PR 想要实现什么、与哪条原则冲突(引用 code-review 部分),并说明你看到的选项,然后使用 AskUserQuestion 请求确认。只有收到明确答复后才能继续。
其他所有问题(必须修复、应该修复、细枝末节)都不属于阻塞项:全部修复。
0c. 跟踪你启动的所有进程(适用于每个步骤)
无论你启动什么来验证 PR——API、worker、控制平面、文档服务或 pg0 实例——都必须在最后(步骤 7)自行停止,且不得影响他人的进程。其他 Hindsight 工作树、服务和 pytest 运行会共用这台机器。
- 启动后台进程时,确保能获取其 PID(使用
run_in_background,或运行cmd & echo $!),并逐一记录。记下你选用的端口。 - 需要数据库?请为它指定一个新的唯一 pg0 实例名(例如
HINDSIGHT_API_DATABASE_URL=pg0://ship-it-pr-<N>),并记录这是你创建的实例。如果要复用现有实例(先运行pg0 list检查),请记录它是共享实例。 - 绝不要运行
pkill -f hindsight、pkill -f pytest、killall,也不要未经检查 PID 是否属于你就按端口杀进程。这些操作会影响其他会话。
1. 加载 PR
阅读 PR——标题、正文、关联 issue 和差异内容——以了解其目标;阻塞项规则取决于此。如果 PR 状态为 CONFLICTING,请先将其变基到 origin/main:有冲突的 PR 会被静默地完全跳过 CI 运行。
确认作者是否为维护者(在仓库中拥有 write、maintain 或 admin 权限,例如 nicoloboschi)。
2. 检出 PR 分支
在当前工作树中操作——不要创建新工作树或克隆仓库。切换前,记录当前状态(当前分支/提交以及所有未提交的更改),以便在第 6 步恢复;使用 WIP 提交或带唯一标记的 stash 暂存未提交的工作(绝不要直接运行 git stash——所有工作树共用 stash 栈)。然后检出 PR 的分支(如果已经在该分支上,则跳过)。如果输入的是当前分支,且未提交的工作显然不属于此 PR,请询问用户。
- 维护者 PR: 修复提交并推送到此分支,也就是 PR 自身的 head。绝不要单独创建修复 PR。
- 外部(fork)PR: 如果维护者可以修改该分支,也要将更改推送到 fork 分支;否则停止并询问用户如何继续(提交后续 PR,还是联系贡献者)。
每次推送前,都要确认作者没有在这期间推送新内容。如果有,阅读他们的新提交,并将你的提交变基到他们的 head 上——绝不要强制推送覆盖你尚未阅读的工作。
3. 审查
阅读并遵循仓库中绝对路径为 <repo>/.claude/skills/code-review/SKILL.md 的代码审查 skill(<repo> = git rev-parse --show-toplevel),审查 PR 的更改(base = origin/<baseRefName>)。收集所有问题:必须修复、应该修复和小问题。
根据第 0 步对每项问题分类。任何阻塞项 → 停止并询问。
4. 修复所有问题
- 修复每一项问题,而不只是必须修复的问题。保持在 PR 范围内——不要重构审查未指出的相邻代码。
- 运行
./scripts/hooks/lint.sh,并运行覆盖所改代码的测试(测试命令见 CLAUDE.md)。如果更改需要,重新生成 OpenAPI/客户端/docs-skill。 - 循环直到没有问题。 一轮审查远远不够:修复可能引入新问题,而审查只会检查上一轮更改的内容。因此要重复执行——审查 → 修复所有问题 → 再审查——直到一轮完整的
code-review返回的各类问题(必须修复、应该修复、小问题)均为 零。不要在“只剩小问题”时停止,不要因为上一轮发现的问题更少就停止,也不要在没有实际重新运行审查的情况下宣布完成。唯一可以提前结束的情况是遇到阻塞项(第 0 步)→ 停止并询问。 - 后续工作要在这里完成,而不是留到以后。 如果 PR 需要更多工作才能完整——无论是审查或你发现的缺失内容、文档页面、客户端重新生成还是测试——都要在这个 ship-it 中、这个分支上完成。属于此更改的工作不能通过“后续 PR”处理。只有真正属于不同问题的工作才提交到 issue(第 7 步)。
- 提交时使用列明所修复内容的提交消息,然后推送到 PR 分支。
不要在维护者的 PR 上发表评论——在聊天回复和提交消息中说明问题。对于外部 PR,可以发表一条简短评论,概述你推送的修复。
5. 等待 CI 全部通过
此仓库没有必需的状态检查:gh pr merge --auto 会立即合并,而 gh pr checks 只会报告目前已注册的检查(若只有一个较早运行的 Strix 检查,它会显示为“green”)。应以针对已推送 head SHA 的 CI 工作流运行为准:
SHA=$(gh pr view <N> --json headRefOid --jq .headRefOid)
gh run list --branch <headRefName> --workflow CI --json databaseId,status,conclusion,headSha \
| jq --arg s "$SHA" 'map(select(.headSha==$s)) | .[0] // empty'
尚无运行 → 继续等待(若约 15 分钟后仍未开始,则放弃等待并报告)。运行一旦进入 completed 状态,按每项作业判断(gh run view <id> --json jobs):failure 数量必须为零。如果 PR 涉及 API/引擎,则 test-api (1..3/3)、Core LLM tests 和 LLM 验收矩阵必须为 success,不能是 skipped;对于这些路径以外的更改,变更筛选器跳过这些检查是合理的。已知 oracle-client 作业不稳定,可能会显示为 cancelled——忽略这些作业。
Fork PR 会跳过 test-api 和 LLM 作业(没有密钥)。合并前要在上游分支上运行完整测试套件——合并到 main 不会运行任何 CI:
git push origin HEAD:ci/pr-<N>-verify
gh workflow run CI --ref ci/pr-<N>-verify # exactly ONCE — a second dispatch cancels the first
由 PR/修复导致失败 → 修复、推送,然后返回第 5 步。已知的不稳定项(检查作业日志,确认没有涉及 PR 的代码)→ 等运行完成后,执行一次 gh run rerun <id> --failed。
如果 CI 仍因无法确定归因的原因而失败,请停止并报告——不要在 CI 未通过时合并。
6. 还原工作树,然后合并
首先将工作树还原到你接手时的状态:切回原始分支/提交,并重新应用所有暂存的工作(撤销 WIP 提交/应用后删除带标签的 stash)。如果因阻碍或失败而提前停止,也要执行相同操作。先还原还能避免 --delete-branch 尝试检出 main,因为另一个工作树可能正占用它。
gh pr merge <N> --squash --delete-branch
git push origin --delete ci/pr-<N>-verify # if you created it
7. 清理、提交 issue、报告
即使提前停止(遇到阻碍、CI 未通过),也要执行此步骤。
只停止你启动的进程。 结束你在步骤 0c 中记录的每个 PID(kill <pid>;确认进程已结束,只有在卡住时才使用 kill -9 <pid>)。结束进程前,用 ps -p <pid> -o command= 确认它仍是你启动的进程。对于每个 pg0 实例:
- 为本次 ship-it 创建的 →
pg0 drop --name <name> -f(停止实例并删除其数据)。 - 共享的/原本就存在的 → 不要动它。既不要停止,也不要删除。
然后检查是否还留有你启动的进程:对你使用的每个端口运行 lsof -nP -iTCP:<port> -sTCP:LISTEN。
为遇到的真实项目问题提交 issue。 在审查、测试或等待 CI 时,你可能会遇到不属于本 PR 工作范围、也不是本地环境问题的故障:不稳定的测试、附近代码中的 bug、损坏的脚本、错误的文档,或总是失败的 CI 作业。针对每个问题:
- 先搜索,避免重复:
gh issue list --state open --search "<keywords>"。 - 如果没有现成 issue,就创建一个:
gh issue create --title ... --body ...。正文应说明问题表现、复现方法(命令或步骤)、预期行为,以及问题所在的代码位置。内容简明即可。
本地问题(你的环境、缺少工具、端口被占用、过期的 .env)不属于 issue——只有在需要用户采取行动时,才在报告中提及。
报告:
- PR 链接,以及作为合并门槛的 CI 运行记录。
- 已修复的发现(每项一行),以及有意保留的问题和原因。
- 发现的项目 issue——使用清晰标记的章节,列出你创建的每个 issue(链接+一行说明),以及你找到的现有 issue(因此没有新建)。如果没有,请写“无”。
- 你停止和删除了什么,以及你没有动的共享 pg0 实例。
关于 gh pr edit 的说明
它在此仓库中会失败——GraphQL 中的“Projects (classic)”弃用错误会导致操作中止,且没有任何更改,过程不会给出提示。要编辑描述,请改用 REST API:
gh api -X PATCH repos/<owner>/<repo>/pulls/<N> -F [email protected]