【免费下载链接】claude-code-base-action
This repo is a mirror of the contents of base-action in https://github.com/anthropics/claude-code-action.
如果你想在 GitHub Actions 里跑 Claude Code,claude-code-base-action是最值得精读的一份源码:它用不到千行 TypeScript,把 Claude Agent SDK 从"库"变成了整个 CI 流水线里真正的"发动机"。本文带你完整走一遍它的执行链路——从action.yml的输入声明,到 src/index.ts 的编排入口,再到 src/run-claude-sdk.ts 中那个逐条消费 SDK 消息流的query()调用,看懂 Claude Agent SDK 是如何驱动整个 Action 运转的。
🧭 项目全景:三个文件看懂架构
这个项目是一个"薄封装"(thin wrapper):它自己不做信任边界,只负责安装环境 → 校验配置 → 组装参数 → 调用 SDK 执行 → 输出结果。理解它只需要抓住三层:
| 层次 | 文件 | 职责 |
|---|---|---|
| 声明层 | action.yml | 定义所有 inputs/outputs,并用 composite steps 装好 Node、Bun、Claude Code 可执行文件 |
| 编排层 | src/index.ts | 把 7 个模块按顺序串成流水线,最终设置 Action outputs |
| 引擎层 | src/run-claude-sdk.ts | 调用 Claude Agent SDK 的query(),消费消息流并判定成败 |
依赖极少,核心就一个:package.json 中的@anthropic-ai/claude-agent-sdk。这正是"SDK 驱动整个 Action"的题眼——没有spawnCLI 去解析终端输出,而是通过 SDK 的异步迭代器拿到结构化的消息流。
🔁 执行流程:从 Action 输入到 SDK 调用
先看 action.yml 的runs.steps,它是一个 composite action,依次做四件事:
- Setup Node.js(可缓存 npm 依赖)
- Install Bun(运行时,版本锁定 1.3.14)
- Install Dependencies:
bun install --production - Install Claude Code:安装官方 CLI 到
~/.local/bin/claude,内置 3 次重试与 120 秒超时
最后一步bun run ${GITHUB_ACTION_PATH}/src/index.ts才真正进入 TypeScript 世界。src/index.ts 的run()按固定顺序执行 6 个环节:
setupWorkloadIdentity()—— 若配置了身份联邦,先换取 OIDC token(src/workload-identity.ts)validateEnvironmentVariables()—— 按所选 Provider(直连 API / Bedrock / Vertex / Foundry)校验凭证,报错信息非常清晰,见 src/validate-env.tssetupClaudeCodeSettings()—— 把用户传入的settings(JSON 字符串或文件路径)合并进~/.claude/settings.json,见 src/setup-claude-code-settings.tsinstallPlugins()—— 逐个校验并安装插件市场与插件,见 src/install-plugins.tspreparePrompt()—— 统一提示词来源,见 src/prepare-prompt.tsrunClaude()—— 核心执行,解析参数后交给 SDK
注意第 1 步的注释逻辑:workload identity 必须在环境变量校验之前完成,因为 CLI 需要拿到身份 token 文件后才能认证。失败路径同样周到:catch里先补写execution_file输出再setFailed,finally里清理 token 材料,避免凭证残留。
🚀 核心引擎:run-claude-sdk.ts 如何消费 SDK 消息流
这是全文最关键的文件。看 src/run-claude.ts:它只是个 7 行的转发器——先parseSdkOptions(options),再调用runClaudeWithSdk()。真正的逻辑在 src/run-claude-sdk.ts 的runClaudeWithSdk()中,精华是这一段:
for await (const message of query({ prompt, options: sdkOptions })) { messages.push(message); // sanitizeSdkOutput 决定日志里打印什么 if (message.type === "result") break; }Claude Agent SDK 的query()是一个异步生成器,它会以SDKMessage序列"直播" Claude Code 会话的全过程:system.init(初始化)、assistant(回复与工具调用)、result(最终结果)。这个 Action 对消息流做了四件关键的事:
- 安全脱敏:
sanitizeSdkOutput()(L117-L160)默认只打印初始化和结果摘要,避免日志泄露密钥;仅当show_full_output: true时才输出完整 JSON - 收集全量消息:所有消息写入 execution-file.ts 生成的
claude-execution-output.json(位于RUNNER_TEMP),成为execution_file输出,供后续 step 解析 - 提取 session_id:从
system.init消息中取出,暴露为session_id输出,可用--resume续聊 - 严格判定成败:
subtype === "success" && !is_error才算成功;若超出maxTurns、或声明了--json-schema却没拿到structured_output,都会直接抛错让 CI 标红(L241-L278)
还有个耐人寻味的细节:拿到result后显式break(L198-L210)。注释解释了原因——某些 PR 触发的场景中 SDK 迭代器不会自行关闭,for-await会一直挂到 workflow 超时,导致"任务实际成功却被标为 cancelled"。这是典型的"读源码才知道的坑"。
⚙️ 参数工程:parse-sdk-options.ts 的隐藏功力
parse-sdk-options.ts 负责把用户写在claude_args里的 shell 字符串翻译成 SDK 的Options对象,细节很多:
- shell 元字符转义:
(、)、|、&等字符对shell-quote是控制符,直接解析会把--allowedTools Bash(gh:*)悄悄截成Bash,等于放大权限。源码用 Unicode 私用区字符做临时转义再还原(L35-L55) - 累积型 flag:
allowed-tools、mcp-config等支持多值,用\x00分隔累积 - 多 MCP 配置合并:内联 JSON 的
mcpServers会被 merge 成一份,见mergeMcpConfigs()(L67-L110) - 环境变量瘦身:主动删掉
ACTIONS_ID_TOKEN_REQUEST_URL等变量,防止 Claude 会话自己"签发" OIDC token(L286-L294) - 系统提示词策略:默认使用 SDK 内置的
claude_codepreset;用户可用--system-prompt全量替换,或用--append-system-prompt追加(L296-L312)
🔐 免密钥认证:workload-identity.ts 的优雅设计
不想在 secrets 里存 API key?这个模块给出了完整答案:它获取 GitHub OIDC token(JWT),写入RUNNER_TEMP下的文件并导出ANTHROPIC_IDENTITY_TOKEN_FILE,再由 Claude Code CLI 用联邦规则换取短生命周期访问令牌。两个工程亮点值得新手学习:
- 后台刷新:GitHub OIDC token 有效期短,所以每 4 分钟重写一次 token 文件,
stop()时清理(L178-L194) - 凭据缓存目录指纹:配置目录名内嵌联邦输入的 SHA-256 指纹,防止同一 job 里不同 step 误复用上一条链路的 token(L80-L109)
配套的指数退避重试封装在 src/retry.ts,默认 3 次、5 秒起步、20 秒封顶。
📤 四个 Outputs 如何被下游消费
action.yml 声明了 4 个输出,全部来自 src/index.ts 的core.setOutput:
| 输出 | 用途 |
|---|---|
conclusion | success/failure,决定后续 step 是否执行 |
execution_file | 执行日志 JSON 路径,可用jq或脚本提取 Claude 的最终答复 |
structured_output | 传了--json-schema时的结构化结果,适合机器读取 |
session_id | 用于--resume恢复会话 |
典型玩法见 README 的 PR 评审示例:先判断conclusion == 'success',再从execution_file里反向查找type === 'result'的消息拿到评审内容发评论。examples/issue-triage.yml 则展示了"issue 打开 → Claude 打标签"的完整场景,prompt_file里把任务拆成 5 步,并用allowed_tools精确圈定可用工具。
🧪 本地调试与测试入口
想动手验证?仓库自带完整测试设施:
./test-local.sh:基于act在本地模拟 GitHub Actions 跑整个 Action(需ANTHROPIC_API_KEY)bun test:单元/集成测试,覆盖参数解析、提示词准备、SDK 执行等,如 test/run-claude-sdk.test.ts 用mock.module伪造 SDK 消息流,验证"异常时仍会落盘执行日志"- test/mcp-test/:一个最小 MCP server(simple-mcp-server.ts),配合
test-mcp-local.sh调试 MCP 集成
架构约定可参考 CLAUDE.md(构建命令、Provider 认证矩阵),开发规范见 CONTRIBUTING.md。
🎯 小结:从这份源码能学到的 3 件事
- SDK 优先于 CLI 解析:用 Agent SDK 的异步消息流替代"跑 CLI + 正则解析 stdout",是构建可靠自动化最省心的路线
- 安全默认值:日志默认脱敏、环境变量主动瘦身、插件名白名单校验(src/install-plugins.ts)——防御性设计贯穿每个模块
- 失败也要留证据:无论 SDK 抛错还是流程中断,执行日志都会尽力落盘并通过
execution_file输出,让事后排查有迹可循
读完这一百多行的index.ts加上两百行的run-claude-sdk.ts,你不仅能彻底理解 Claude Agent SDK 如何驱动整个 Action,也拿到了一个可以照抄的"GitHub Action + AI SDK"工程模板。
【免费下载链接】claude-code-base-action
This repo is a mirror of the contents of base-action in https://github.com/anthropics/claude-code-action.
相关推荐
claude-code-base-action:集成 Claude Code 的强大工作流工具
claude code base action:集成 Claude Code 的强大工作流工具 项目介绍 在现代软件开发中,自动化工作流是提高效率、减少人为错误
Claude Code 跑进 CI:Anthropic 官方 claude-code-base-action 完全概览与核心能力
Claude Code 跑进 CI:Anthropic 官方 claude code base action 完全概览与核心能力 想在 GitHub Actio
Claude Code Security Reviewer:基于 Claude 的 AI 驱动 PR 安全审查 GitHub Action 完整指南
Claude Code Security Reviewer:基于 Claude 的 AI 驱动 PR 安全审查 GitHub Action 完整指南 Claud
应用安全SASTAI 应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考