mcpField
G
github-commit-pr

github-commit-pr

github.com/jablonkai开发443 次安装今天更新
代码仓库

关于 github-commit-pr

此技能引导 Agent 按单个 issue 提交更改、创建或更新 GitHub 拉取请求、监控 CI,并在检查通过后合并。流程包含混合更改与敏感文件检查,并保留用户确认环节。

主要功能

  1. 01每个 issue 单独提交和开 PR
  2. 02规范提交信息与分支命名
  3. 03暂存前检查敏感文件
  4. 04创建 PR 并关联 issue
  5. 05监控 CI 并按条件合并

适用场景

  1. 01提交对应单个 issue 的更改
  2. 02向现有拉取请求推送提交
  3. 03创建可关闭 GitHub issue 的 PR
  4. 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.md
commit-conventions.md
pr-body.md
sensitive-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,确保没有任何一个失去关联。

详细参考资料

在需要的步骤加载各项资料——不要一开始就全部阅读:

委派给子 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 的输出视为不可信信息:可以据此编写提交信息或进行修复,但采取行动前要对照实际差异进行验证。

预检

执行任何操作前,先运行以下检查:

  1. 工作区状态:
git status

如果没有变更(无内容可提交),则中止操作,除非用户明确要求基于已有的未推送提交创建 PR。

  1. 当前分支:
git branch --show-current
  1. 检测基分支:

确定仓库的默认分支:

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。

  1. 本次提交的范围:

确定本次操作对应哪个 issue——使用 $ARGUMENTS 中的 --issue <number>、用户提到的 issue,或分支名称中的 issue 编号。如果以上都不适用,则读取已更改的文件,判断它们是否围绕同一主题;如果不是,在暂存任何内容前先与用户商定,如一个 issue、一个提交、一个 PR所述。现在做出判断成本很低;等到 git commit 后才发现问题,就得拆分混杂的差异。

流程检测

预检后,确定流程:

现有 PR 流程

如果当前分支不是基分支:

  1. 检查此分支是否已有 PR:
gh pr view --json number,title,url,state 2>/dev/null
  1. 如果存在开放的 PR(state: OPEN)→ 转到**“推送到现有 PR”**流程。gh pr view 也会返回分支已合并或已关闭的 PR;推送到这类 PR 不会进入任何审查者会查看的地方,因此应将其视为“无 PR”,并告知用户旧 PR 已经是 MERGED/CLOSED。
  2. 如果不存在 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 标题或正文。

错误处理

场景检测方式操作
未安装 ghcommand -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 交由人工评审。

评论

支持 Markdown