在 claude-code-action 中配置 slash 命令:以 commit-and-pr 为例实现测试、提交、推送与建 PR 的一站式自动化

原创2026-10-13 16:38:161,450 阅读
文章标签:AI Agent代码智能体人工智能代码评审研发协作CI/CDMCP Clients开发工具

在 claude-code-action 中配置 slash 命令:以 commit-and-pr 为例实现测试、提交、推送与建 PR 的一站式自动化

本文围绕 claude-code-action 仓库中 .claude/commands/commit-and-pr.md 这一命令定义文件,讲解如何通过 Claude Code 的 slash 命令机制,把「运行测试与类型检查、格式化、提交、推送、创建 Pull Request」整条开发工作流压缩成一句指令。读完本文,你将掌握 slash 命令文件的结构与触发方式、命令所需工具的授权模式(allowed-tools 与 Bash 包装脚本),并能结合仓库源码理解命令如何被提取、分发与执行。

命令文件本体:一句话指令背后是完整的提交工作流

.claude/commands/commit-and-pr.md 全文只有一行指令式描述:

Let's commit the changes. Run tests, typechecks, and format checks. Then commit, push, and create a pull request.

它不是一个普通的 Markdown 文档,而是 Claude Code 的 slash 命令定义文件:只要在触发消息中写下 /commit-and-pr,Claude Code 就会读取该文件,把这句话作为任务指令,并按其中的顺序执行:

  1. 先做质量门禁:运行测试(bun test)、类型检查(bun run typecheck)、格式化检查(bun run format:check);
  2. 再完成交付:提交(commit)、推送(push)、创建 Pull Request。

需要注意的是,该文件没有使用 frontmatter 元数据(对比同目录下的 .claude/commands/label-issue.md 和 .claude/commands/review-pr.md,它们都带有 allowed-tools 与 description 头)。这意味着 /commit-and-pr 命令本身不额外声明工具授权,其可用的命令范围取决于 action 的 claude_args 配置与 tag 模式注入的默认工具集,这一点在下一节展开说明。

命令如何被识别与分发:从触发评论到 slash 命令解析

要理解 commit-and-pr.md 这类文件为什么能被调用,需要回到 action 的消息构造链路:

  • 在 tag 模式下,用户评论(例如 @claude /commit-and-pr)会被 src/utils/extract-user-request.ts 处理。该函数用字符串查找(而非正则,以规避大评论体的 ReDoS 风险)定位触发短语(默认 @claude),返回其后的内容——即 /commit-and-pr 这一请求文本;
  • 随后 src/create-prompt/index.ts 会把提取出的请求单独写入 claude-user-request.txt,与完整上下文提示词并存;
  • 执行端 base-action/src/run-claude-sdk.ts 检测到该文件存在时,会构造一个「多块消息」(multi-block message):先发送完整的指令与 GitHub 上下文,最后发送用户请求块,从而让 CLI 能够识别并处理 slash 命令。

这一链路在 test/extract-user-request.test.ts 中有明确验证,例如 @claude /review-pr please check the auth module 会被提取为 /review-pr please check the auth module,而 @claude /commit-and-pr(含多余空格)也会被正确解析。因此,任何放入仓库 .claude/commands/ 目录的命令文件,只要名字合法,都可以通过 @claude /命令名 触发。

命令可用的工具:授权边界决定命令能否执行

commit-and-pr.md 要求 Claude 运行测试、提交并推送代码,这些动作依赖一组特定工具,授权方式有两种:

方式一:tag 模式默认注入的 git 工具集

在 tag 模式下,src/modes/tag/index.ts 会为 Claude 注入基础工具:Glob、Grep、LS、Read、评论更新 MCP 工具、CI 状态 MCP 工具,并在未启用 API 签名提交时追加四个受约束的 Bash git 命令:

Bash(git add:*)
Bash(git commit:*)
Bash(<GITHUB_ACTION_PATH>/scripts/git-push.sh:*)
Bash(git rm:*)

也就是说,git add、git commit、推送与删除都由白名单放行,但 git push 本身并不直接开放,而是被替换为仓库提供的 scripts/git-push.sh 包装脚本。该脚本只接受 origin <ref> 两个参数、拒绝任何以 - 开头的参数,并校验 ref 合法性后执行 git push origin "$REF"。这样设计是为了防御 --receive-pack/--exec 这类可注入任意 shell 的 RCE 攻击向量(脚本注释中明确标注了 H1 #3556799 漏洞背景)。

方式二:通过 claude_args 显式追加

如果你的命令还需要运行 npm install、npm run build 等其它命令(例如测试前需要先安装依赖),就需要在 workflow 的 claude_args 中显式放行,见 docs/configuration.md:

- uses: anthropics/claude-code-action@v1
  with:
    claude_args: |
      --allowedTools "Bash(npm install),Bash(npm run test),Edit,Replace,NotebookEditCell"
      --disallowedTools "TaskOutput,KillTask"

claude_args 中用户传入的部分会与 tag 模式默认工具集合并(src/modes/tag/index.ts 会先从用户的 claude_args 中过滤出 mcp__github_ 前缀的 MCP 工具),最终统一拼进 --allowedTools。

其它命令文件的授权示例

作为对照,.claude/commands/label-issue.md 通过 frontmatter 显式声明了 allowed-tools: Bash(./scripts/gh.sh:*),Bash(./scripts/edit-issue-labels.sh:*),将 Claude 的能力严格限定在 scripts/gh.sh(只允许 issue view、issue list、search issues、label list 及四个受限 flag)与打标签脚本上,且明确禁止向 issue 发评论。而 .claude/commands/review-pr.md 则放行 gh pr comment:*、gh pr diff:*、gh pr view:*,并调用 .claude/agents 目录下的五个子代理(代码质量、性能、测试覆盖、文档准确性、安全)完成分领域审查。这种「命令文件声明最小工具集」的模式,是编写 commit-and-pr 类命令时的推荐参照。

质量门禁从何而来:仓库自带的测试、类型检查与格式化脚本

命令要求「Run tests, typechecks, and format checks」,这些检查在该仓库中都有现成脚本支撑,也解释了 Claude 在本地执行这些命令时具体会跑什么:

  • bun test:Bun 运行全部单元测试(package.json 中 "test": "bun test");
  • bun run typecheck:tsc --noEmit 全量类型检查,且项目开启了 noUnusedLocals 与 noUnusedParameters(见 CLAUDE.md 的说明),未使用的变量会直接导致类型检查失败;
  • bun run format:check:Prettier 检查(prettier --check .),而 bun run format 用于自动格式化。

仓库还把这些检查固化进了 git 钩子,与命令的目标互为印证:scripts/pre-commit 与 base-action/scripts/pre-push 都会按「格式化检查 → 类型检查 → 测试」的顺序执行,并在格式化产生未提交改动时中止。通过 scripts/install-hooks.sh 可将 pre-commit 钩子安装到 .git/hooks/。

此外,.claude/settings.json 中配置了 PostToolUse 钩子:每当 Claude 使用 Edit|Write|MultiEdit 修改文件后,会自动运行 bunx prettier@3.5.3 --no-config --write . 进行格式化,这与命令「先格式化检查再提交」的要求相互衔接,保证推送到分支的代码始终是格式化过的。

提交、推送与创建 PR:源码中的完整流程

命令的最后一步是「commit, push, and create a pull request」,对应源码中 tag 模式的提交指令模板 getCommitInstructions()(src/create-prompt/index.ts),它按场景给出不同策略:

触发场景 提交与推送策略 建 PR 方式
在 issue 上触发(tag 模式会新建分支) 先 git add,再用带描述信息的 git commit -m,最后 git-push.sh origin <分支名> 生成 compare 链接(base...branch,三点分隔),带预填的 title 与 body,并建议正文包含改动说明、关联 issue 引用与 "Generated with Claude Code" 签名
在 PR 上触发 直接推送到现有 PR 分支,禁止新建分支 无需新建 PR,仅更新评论
关闭/合并的 PR 上触发 新建分支后推送 同上生成 compare 链接

模板还会在提交信息中追加 Co-authored-by 尾注(当触发用户可识别且非 "Unknown" 时),并在最终评论中附上 job 运行链接。这些规则最终通过 generateDefaultPrompt 写入提示词,约束 Claude 在行动时严格遵守(src/create-prompt/index.ts 给出了完整的 git 命令清单与 PR diff 基线说明——diff 应基于 origin/<base_branch> 而非 main/master)。

在自有仓库中启用 commit-and-pr 命令的完整步骤

要在你自己的仓库中复刻这一能力,需要完成以下配置(仓库为只读,以下均为本地/工作流配置操作):

  1. 放置命令文件:在仓库根目录创建 .claude/commands/commit-and-pr.md,内容即本文开头那一行指令。如需限定工具,可仿照 .claude/commands/label-issue.md 添加 allowed-tools frontmatter;
  2. 配置 workflow 触发 tag 模式:参照 examples/claude.yml,监听 issue_comment(types: created)等事件,并在 job 的 if 条件中判断评论包含 @claude;提供 anthropic_api_key,按需设置 trigger_phrase(默认 @claude)与 claude_args(如 --max-turns、--allowedTools);
  3. 放行所需 Bash 命令:若命令运行测试时需要安装依赖或执行构建,在 claude_args 中追加对应的 Bash(...) 白名单;git 四件套(add/commit/推送包装脚本/rm)在 tag 模式下已默认放行;
  4. 在 issue/PR 评论中触发:发表 @claude /commit-and-pr,Claude 会先运行测试、类型检查与格式化检查,通过后提交、推送并给出预填好的 PR 创建链接。

对于 issue 触发场景,action 会自动创建分支、配置 git 认证并生成跟踪评论;对于需要在外部参与者创建的 issue 上执行自动化任务的场景,可参考 examples/issue-triage.yml 中 allowed_non_write_users: "*" 与 github_token 的组合用法——这也是 slash 命令在自动化运维中最常见的权限前置条件。

小结

.claude/commands/commit-and-pr.md 用一句话把「质量门禁 + git 交付 + PR 创建」串成了可复用的 slash 命令。它的背后是 claude-code-action 一整套工程化支撑:命令文件驱动的工具授权边界、对 git push 的包装加固、tag 模式默认注入的受控 git 工具集、多块消息触发的 slash 命令解析,以及仓库自带的测试/类型检查/格式化脚本与 git 钩子。理解了这条链路,你就能仿照 .claude/commands 目录下的既有命令,为自己的仓库定制更多「一句话完成一件事」的自动化工作流。

登录后查看全文
claude-code-action