关于 github-commit-pr
此技能引导 Agent 按单个 issue 提交更改、创建或更新 GitHub 拉取请求、监控 CI,并在检查通过后合并。流程包含混合更改与敏感文件检查,并保留用户确认环节。
主要功能
- 01每个 issue 单独提交和开 PR
- 02规范提交信息与分支命名
- 03暂存前检查敏感文件
- 04创建 PR 并关联 issue
- 05监控 CI 并按条件合并
适用场景
- 01提交对应单个 issue 的更改
- 02向现有拉取请求推送提交
- 03创建可关闭 GitHub issue 的 PR
- 04用 --no-merge 留待人工审查
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jablonkai/ skills --skill github-commit-pr安装后在 Claude Code 中输入/github-commit-pr确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/ci-and-merge.mdcommit-conventions.mdpr-body.mdsensitive-files.md详细介绍
github-commit-pr
用途
端到端工作流:提交更改、创建或更新 GitHub 拉取请求、监控 CI,并在 GitHub Actions 成功后合并 PR。支持关联 Issue 并使用自动关闭关键词、使用约定式提交消息、向现有 PR 推送新提交,以及在 CI 通过后自动合并并清理分支。
适用场景
- 提交更改、创建新 PR,并在 CI 通过后合并
- 向现有 PR 分支推送更多提交,并在 CI 通过后合并
- 创建引用并自动关闭 GitHub Issue 的 PR
- 合并多个已实现的 Issue——每个 Issue 运行一次此工作流,而不是针对整个工作树运行一次
- 如果希望由人工审核后再合并 PR,请传入
--no-merge跳过合并步骤
一个 Issue,一个提交,一个 PR
拉取请求是审核者阅读、维护者讨论以及撤销操作所针对的单元。当它恰好对应一个 Issue 时,这三件事都会很简单。一个关闭三个 Issue 的 PR 无法分开审核,也无法分开撤销,还会迫使只关心其中一个 Issue 的审核者阅读全部三个。因此,此工作流会为每个 Issue 创建一个提交和一个 PR——即使工作树中已经包含多个 Issue 的已完成工作。
最容易出错的环节是暂存:git add -A 会收集工作树中的所有内容,包括其他 Issue 的工作;一旦两个 Issue 共用一个提交,就只能手动拆分。暂存前,先确认此提交要处理的内容:
- 如果
$ARGUMENTS中有--issue <number>,或用户刚刚指定了某个 Issue,就可以据此确定:此提交和此 PR 归该 Issue 所属。 - 否则,查看
git status --porcelain,判断已更改的文件是否都围绕同一件事。来自无关模块的文件、第二个功能的测试,或遗留实验,都是工作树包含多个任务的信号。
如果确实包含多个任务,不要猜测,也不要捆绑——展示你看到的分组,并让用户确认:
The working tree looks like two separate jobs:
#12 — dark mode toggle: src/theme/*, src/components/Toggle.tsx
#13 — token refresh fix: src/auth/refresh.ts, tests/auth.test.ts
I'll commit #12 first and open its PR; #13 stays in the tree for the next run.
Which one should go first?
然后只暂存该 Issue 对应的路径(新建 PR 流程第 5 步),完成合并,再为下一个 Issue 运行此工作流。对审核者而言,审核两个较小的 PR 比审核一个混合 PR 更省力,因此额外往返正是目的,而非负担。
有两个例外,且都必须明确说明:用户表示这些更改确实属于同一项工作(例如多个 Issue 都要求的重构),或者在你说明代价后,用户仍知情并接受合并成一个 PR。由用户决定——照此执行,并在 PR 正文中列出所有 Issue,确保没有任何一个失去关联。
详细参考资料
在需要的步骤加载各项资料——不要一开始就全部阅读:
- references/sensitive-files.md — 暂存前的密钥扫描:始终包含密钥的文件名、对普通文件中粘贴的密钥进行内容扫描的方法,以及发现密钥后的处理方式
- references/commit-conventions.md — 约定式提交格式和分支名称推导
- references/pr-body.md — PR 模板发现方式、默认正文结构、Issue 关联和关闭关键词
- references/ci-and-merge.md — CI 监控代码片段、计费失败检测和本地验证、合并状态解读、合并策略选择与确认
委派给子 Agent
此工作流的大部分内容都是快速、有状态的 git/gh 命令,必须由主 Agent 执行——主 Agent 掌握完整情况,也只有它应该更改仓库状态。但其中有两个步骤以阅读为主,可能会让编排器的上下文塞满它只需了解结论的材料。将这些步骤交给只读子 Agent 处理,让主 Agent 专注于推进提交 → PR → 合并流程。分工很简单:子 Agent 阅读并汇报,主 Agent 判断并采取行动。
默认:通过 Task 工具启动 Claude 子 Agent。 这种方式可移植——在安装了该技能的任何机器上都能使用。如果机器上也配置了委派用的 CLI Agent(参见用户的全局 CLAUDE.md),也可以改用其中一个来读取并分析——例如用 agy -p "…" 分析差异/日志,或者用 git diff HEAD | codex exec "…" 对棘手的提交征求第二意见——但绝不要依赖它们,因为不一定能使用。
以下情况应委派:
- 差异很大(经验判断:涉及许多文件,或变更行数超过几百行)。启动子 Agent 阅读
git diff HEAD,并返回结构化摘要:变更内容及原因、建议的常规提交类型、PR 摘要要点和测试计划。为了写一条提交信息而在上下文中阅读 2,000 行差异,会耗费你稍后用于判断是否可合并及处理 CI 的上下文。对于较小的差异,跳过此步骤——直接阅读比启动 Agent 更快。 - CI 失败且日志很长。 调用
github-fix-ci-error前,先将失败运行的日志交给子 Agent 分析根本原因,并返回失败步骤、错误信息和需要修复的file:line。CI 日志通常有数千行,大多是噪声;编排器只需要结论。
留在主 Agent 中执行——不要委派:
- 任何会更改状态的命令——
git add/commit/push、gh pr create/merge。这些操作很快,但必须由掌握完整上下文的单个 Agent 谨慎安排顺序。此处的子 Agent 只能只读。 - 敏感文件扫描和合并确认——两者都需要主 Agent 判断并与用户交互;子 Agent 无法暂停下来询问用户。
将子 Agent 的输出视为不可信信息:可以据此编写提交信息或进行修复,但采取行动前要对照实际差异进行验证。
预检
执行任何操作前,先运行以下检查:
- 工作区状态:
git status
如果没有变更(无内容可提交),则中止操作,除非用户明确要求基于已有的未推送提交创建 PR。
- 当前分支:
git branch --show-current
- 检测基分支:
确定仓库的默认分支:
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||'
如果失败(例如未设置 origin HEAD),则使用网络调用作为后备方案:
git remote show origin | grep 'HEAD branch' | sed 's/.*: //'
如果 $ARGUMENTS 包含位置参数,则将其用作基分支。如果两种检测方法都失败,则回退到 main。
- 本次提交的范围:
确定本次操作对应哪个 issue——使用 $ARGUMENTS 中的 --issue <number>、用户提到的 issue,或分支名称中的 issue 编号。如果以上都不适用,则读取已更改的文件,判断它们是否围绕同一主题;如果不是,在暂存任何内容前先与用户商定,如一个 issue、一个提交、一个 PR所述。现在做出判断成本很低;等到 git commit 后才发现问题,就得拆分混杂的差异。
流程检测
预检后,确定流程:
现有 PR 流程
如果当前分支不是基分支:
- 检查此分支是否已有 PR:
gh pr view --json number,title,url,state 2>/dev/null
- 如果存在开放的 PR(
state: OPEN)→ 转到**“推送到现有 PR”**流程。gh pr view也会返回分支已合并或已关闭的 PR;推送到这类 PR 不会进入任何审查者会查看的地方,因此应将其视为“无 PR”,并告知用户旧 PR 已经是MERGED/CLOSED。 - 如果不存在 PR → 询问用户是继续使用此分支,还是创建新分支。如果选择继续,跳到“新建 PR 流程”的第 3 步(无需创建分支)。
新建 PR 流程
如果当前分支是基分支 → 执行完整的“新建 PR”流程(包括创建分支)。
新建 PR 流程
第 1 步:分析更改
git status
git diff HEAD
git log --oneline -5
如果差异较大,请委派读取,而不是将全部内容直接拉取到当前上下文中——参见委派给子 Agent。启动一个只读子 Agent 来总结 git diff HEAD,并返回提交类型、PR 摘要要点和测试计划,然后在第 3 步和第 7 步中复用该摘要。
第 2 步:检查敏感文件
暂存之前,检查更改文件的名称和新增的内容是否包含密钥——硬编码在普通源文件中的密钥不会出现在 git status 中。匹配模式、扫描命令和处理方式详见 references/sensitive-files.md。test_token.sh 这样的名称只是提示:先查看内容,再将其标记出来。如果发现任何真实密钥,先警告用户并征求同意;绝不要悄悄暂存密钥——“无需询问”的预先批准仅涵盖提交消息和合并,不包括发布凭据。
第 3 步:提出提交消息
根据差异撰写符合规范的提交消息,并提交给用户确认或修改——格式和规则详见 references/commit-conventions.md。
第 4 步:创建分支
根据提交消息推导分支名称并创建分支——参见 references/commit-conventions.md。
第 5 步:暂存并提交
如果整个工作树都属于同一个问题,请将全部内容暂存:
git add -A
如果工作树涉及多个问题(预检第 4 项),请只暂存属于此问题的路径,让其余内容留在工作树中,供各自的提交使用:
git add -- <path> <path> ...
git status --short # confirm the staged set is exactly this issue's work
提交前,先阅读 git status --short 的输出:任何已暂存但无法确认属于此问题的内容都应留给下一个 PR,因此请将其取消暂存(git restore --staged <path>),不要让它混入当前提交。
git commit -m "$(cat <<'EOF'
<type>: <summary>
<optional body>
EOF
)"
如果提交因预提交钩子而失败,请阅读钩子输出、修复问题、重新暂存,并创建一个新提交(不要 amend)。重新暂存相同范围的路径——此时习惯性地执行 git add -A,会让其他问题的工作混进来。
第 6 步:推送
git push -u origin <branch-name>
如果推送因远程拒绝而失败,请报告错误并停止——不要强制推送。
第 7 步:编写 PR 正文
检查仓库是否有 PR 模板,并根据差异上下文填写模板(或默认的“摘要/测试计划”结构);如果涉及问题,也要添加关闭问题的关键词——具体说明见 references/pr-body.md。
第 8 步:创建 PR
gh pr create --title "<summary>" --base "<base-branch>" --body "$(cat <<'EOF'
<PR body from Step 7>
EOF
)"
标题和基分支规则详见 references/pr-body.md——标题保留符合规范的 type(scope): 前缀,因为压缩合并会将其作为基分支上的提交主题。
步骤 9:监控 CI
等待推送触发的所有 GitHub Actions 运行结束,并按提交而非分支选择运行记录 — 相关命令片段和失败处理方法见 references/ci-and-merge.md。
- 如果所有运行都成功 → 继续执行步骤 10。
- 如果某次运行失败,先对失败进行分类:
- GitHub 账单 / 支出限额 — 作业没有执行任何步骤,并带有“job was not started … payments / spending limit / billing”注释。代码从未运行,因此无需修复:在本地运行工作流检查(以及仓库自身的 pre-commit 验证);如果全部通过,可据此合并 PR — 在合并确认和报告中说明 CI 未运行,以及改为在本地验证了什么。
- 其他情况 — 查明根本原因(日志较长时可委派处理),使用
github-fix-ci-error修复、推送并重新监控。重复此过程,直到所有检查通过或用户中止。
步骤 10:合并 PR
CI 已通过 — 用户调用此技能的目的是提交这项更改,因此除非 $ARGUMENTS 中传入了 --no-merge,否则继续合并。如果设置了 --no-merge,则跳到步骤 11。
按照 references/ci-and-merge.md 中的合并流程操作:确认是否可合并,选择仓库允许的策略(优先使用 --squash),向用户确认一次,然后使用 --delete-branch 合并并返回基础分支。如果分支保护、冲突或待处理的检查阻止了合并,则停止并报告 — 除非用户明确要求,否则绝不使用 --admin 绕过限制。
步骤 11:报告
输出 PR URL、最终 CI 状态(通过 / 因 GitHub 账单问题而跳过 — 已在本地使用 <commands> 验证),以及合并结果(已通过 squash 合并 / 按 --no-merge 跳过合并 / 合并受阻,原因是……)。
如果有意将更改留在工作树中以处理另一个问题,请说明这一点并指出接下来要处理什么 — 这些遗留差异是下一次运行要处理的内容,并非疏忽:
Landed #12 → <pr-url> (squash-merged, branch deleted).
Still in the tree: #13 — src/auth/refresh.ts, tests/auth.test.ts.
Say the word and I'll commit #13 as its own PR.
推送到现有 PR 的流程
当前分支已有 PR 时:
步骤 1:分析新增更改
git status
git diff HEAD
步骤 2:检查敏感文件
与新建 PR 流程的步骤 2 相同 — 参见 references/sensitive-files.md。
步骤 3:提出提交消息
遵循与新建 PR 流程的步骤 3 相同的约定 — 参见 references/commit-conventions.md。
步骤 4:暂存、提交并推送
按新建 PR 流程的步骤 5 暂存 — 如果工作树中的所有更改都属于此 PR,则全部暂存;否则仅暂存指定路径。已有 PR 关联了一个问题时,应保持其范围不变:将无关更改推入其中,会导致原本经过审查的 PR 事后变成混合内容。
git add -A # or: git add -- <this PR's paths>
git commit -m "$(cat <<'EOF'
<type>: <summary>
EOF
)"
git push
如果提交因 pre-commit 钩子而失败,请修复问题并创建一个新提交(不要 amend)。
如果推送因远程有新提交而失败,请先使用 rebase 拉取:
git pull --rebase origin <branch-name>
git push
如果 rebase 时出现冲突,请停止并报告 — 不要强制推送或自动解决冲突。
步骤 5:监控 CI
与新建 PR 流程的步骤 9 相同,包括账单问题导致失败时的处理方式 — 参见 references/ci-and-merge.md。此处最重要的是按提交选择运行记录:快速连续推送两次时,--branch ... --limit 1 恰好会返回较早的运行记录。
步骤 6:合并 PR
按照新建 PR 流程的步骤 10 中的合并流程操作,参见 references/ci-and-merge.md。如果 $ARGUMENTS 中传入了 --no-merge,则跳过此步骤。
步骤 7:报告
展示现有 PR URL、新提交摘要、最终 CI 状态和合并结果:
Pushed to PR #<number>: <pr-title>
New commit: <type>: <summary>
URL: <pr-url>
CI: <success|fixed after N attempts|not run (GitHub billing) — local: <commands> passed>
Merge: <merged via squash|skipped per --no-merge|blocked by required reviewers|declined by user>
不要创建新的 PR — 只需推送到现有 PR。 不要修改 PR 标题或正文。
错误处理
| 场景 | 检测方式 | 操作 |
|---|---|---|
未安装 gh | command -v gh 失败 | 引导用户访问 https://cli.github.com |
| 不在 Git 仓库中 | git rev-parse --show-toplevel 失败 | 中止并给出明确说明 |
| 没有要提交的更改 | git status 显示工作树干净 | 中止,除非要从现有提交创建 PR |
| 工作树涉及多个问题 | 更改的文件无法说明同一个问题;提及了多个问题 | 显示分组,只提交第一个问题的更改,其余更改保留在工作树中 |
| 暂存了无关文件 | git status --short 显示有路径不属于此问题的范围 | 提交前运行 git restore --staged <path> |
| 检测到敏感文件或机密信息 | 文件名本身表明文件敏感(.env、*.pem 等),或在差异 / 未跟踪文件中发现内容扫描命中项 | 告知用户文件和行号,并要求在暂存前排除或修复;如果无法询问用户,则不要提交任何包含此类内容的更改 |
| 提交前钩子失败 | git commit 以非零状态退出 | 阅读输出,修复问题,然后创建新提交 |
| 推送被拒绝 | git push 以非零状态退出 | 报告错误,不要强制推送 |
| 分支已存在 | git checkout -b 失败 | 追加数字后缀(例如 -2) |
| 创建 PR 失败 | gh pr create 以非零状态退出 | 报告错误(分支保护、权限等) |
| 远程分支领先(推送失败) | git push 因非快进更新被拒绝 | 运行 git pull --rebase,然后重试推送 |
| 变基冲突 | git pull --rebase 出现冲突 | 停止并报告,不要自动解决 |
| 分支保护阻止合并 | mergeStateStatus: BLOCKED,或 gh pr merge 因 405 / "not mergeable" 以非零状态退出 | 报告阻止合并的具体条件(必需审阅者、代码所有者、签名提交等),然后停止——除非用户要求,否则不要通过 --admin 绕过 |
| 分支落后于基分支 | mergeStateStatus: BEHIND | 提供运行 gh pr update-branch <number> 的选项,重新观察 CI,然后重试合并 |
| 与基分支存在合并冲突 | mergeable: CONFLICTING | 停止并请用户手动解决 |
| PR 收到修改请求 | reviewDecision: CHANGES_REQUESTED | 停止,让用户在合并前处理审阅意见 |
| GitHub 账单问题阻止 CI | 失败的作业运行了 0 个步骤;注释提及付款 / 支出限额 / 账单 | 在本地运行工作流检查;全部通过 → 经确认后合并,并说明 CI 未运行;有任何失败 → 修复,不要合并 |
| 必需检查阻止合并 | mergeStateStatus: BLOCKED,且有待处理或失败的必需检查 | 等待检查完成或修复问题;若因账单问题失败,则报告阻塞情况,由用户决定是否使用 --admin |
| 非必需检查失败或待处理 | mergeStateStatus: UNSTABLE | 指明检查项(gh pr checks),并在合并前征求确认 |
| 尚未计算是否可合并 | mergeable: UNKNOWN | 等待几秒后重新查询 |
| 分支的 PR 已合并或关闭 | gh pr view 返回 state: MERGED 或 CLOSED | 视为没有 PR;新建一个 |
| 用户拒绝合并确认 | 用户对合并提示回答“n” | 跳过合并,报告 PR URL 和 CI 状态,然后正常退出 |
约束
这些边界旨在保护用户的代码仓库和团队工作流:
- 绝不要直接提交到基准分支(例如
main)——始终遵循完整流程:先创建功能分支,然后提交 → 推送 → 创建 PR → 等待 CI 通过 → 压缩合并 → 删除分支。基准分支由多人共享,通常受到保护;直接提交到该分支会跳过评审和 CI,而这正是本技能要强制执行的关卡。预检发现当前分支就是基准分支时,必须先创建功能分支(新建 PR 流程第 4 步),然后才能暂存任何内容。 - 不要强制推送——这会重写共享历史,可能导致协作者丢失数据。
- 不要修改现有提交——应创建新提交,以便提交时间线保持透明且便于评审。
- 不要跳过 pre-commit 钩子(
--no-verify)——钩子负责执行项目级质量关卡,存在自有其原因。 - 不要提交
.env、凭据或机密信息——暂存前始终运行敏感文件检查,并在检测到任何此类内容时发出警告。 - 如果任何步骤失败,立即停止并报告错误——不要盲目继续,因为后续步骤依赖前面的步骤成功完成。
- 每个提交和每个 PR 只处理一个 issue——PR 是评审者阅读的内容,也是撤销操作的对象,因此应当精确对应一个 issue。只有用户在了解代价后明确提出要求,才可以合并处理;此时要在 PR 正文中列出每个 issue。
- 使用
git add -A暂存(完整变更提交流程),但必须先通过敏感文件检查,而且仅当整个工作树都属于此 issue 时才能这样做;否则只暂存此 issue 涉及的路径。 - 将其他 issue 的变更留在工作树中,不要因为“顺手”就一并提交——它们应在之后各自通过 PR 合并,这样评审者才能将其与提出这些变更的 issue 对应起来。
- PR 正文必须如实反映 diff 中的实际变更,不要使用套话——评审者要依靠它了解变更内容。
- issue 关闭关键词(
Closes #N)应放在 PR 正文中,而不是提交消息中——GitHub 只会处理默认分支上 PR 正文中的关闭关键词。 - 向现有 PR 推送时,不要修改 PR 标题或正文——只推送新提交。
- 在已监控的 GitHub Actions 运行实际通过之前,不要合并 PR——
gh run watch --exit-status是必经关卡,绝不能轻信仍在运行或待处理的状态。必须确认已监控的运行对应于刚推送的提交(gh run list --commit "$(git rev-parse HEAD)"),而不能只看分支上最新的运行。 - 唯一例外:如果 CI 失败仅仅是因为 GitHub 出于计费原因拒绝启动作业(未执行任何步骤,且出现计费注释),那么在工作流检查已在本地通过后,可以合并 PR——本地验证可以替代 CI,但绝不能跳过验证。用户猜测配额用尽并不构成依据;已运行并失败的作业就是真正的失败。
- 合并前始终先向用户确认一次——合并会改变共享状态,协作者都能看到,而且撤销操作很麻烦;确认是用户最后一次暂停操作的机会。
- 除非用户明确要求,否则不要使用
gh pr merge --admin绕过分支保护——保护规则旨在确保评审和质量关卡,悄悄绕过它们会破坏团队流程。 - 遵循
$ARGUMENTS中的--no-merge——启用时,只推送并报告,绝不调用gh pr merge,以便用户将 PR 交由人工评审。