Files
claude-code/docs/outline-output/user/11-ci-integration.md
2026-06-15 16:51:29 +08:00

371 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 第十一章:自动化与 CI 集成 —— 把 Claude 嵌入流水线
> 不想每次都手动对话?让 Claude 在脚本、CI 和容器里自动干活。
## Pipe 模式:一句话调用,拿结果就走
Pipe 模式(也叫 headless / print 模式)是 Claude Code 最直接的自动化入口。不需要 TTY不需要交互传入提示词拿回结果进程退出。它在 `src/main.tsx` 里注册为 `-p, --print` 选项,描述原文是 "Print response and exit (useful for pipes)"。
最基本的用法:
```bash
# 把结果直接输出到终端
claude -p "解释当前目录的 package.json 依赖关系"
# 管道传入提示词
echo "列出 src/ 下所有 .ts 文件" | claude -p
# 把结果存到文件
claude -p "给 src/utils/hash.ts 写单元测试" > hash.test.ts
```
Pipe 模式有几个值得注意的行为。第一,**信任对话框被跳过**——命令行帮助文本明确写了 "The workspace trust dialog is skipped when Claude is run with the -p mode. Only use this flag in directories you trust." 意味着 Claude 会直接在当前目录操作文件,不会先问你是否信任它。所以只在可信目录用 `-p`
第二,支持结构化输出。配合 `--output-format json` 可以拿到 JSON 格式的结果,方便脚本解析:
```bash
claude -p "列出 3 个最常见的 TypeScript 性能问题" --output-format json
```
第三,支持流式 JSON 输出(`--output-format stream-json`),适合需要实时处理中间结果的场景。
第四,可以限制工具白名单。在 CI 环境中,你可能不想让 Claude 随意执行任意命令。通过 `--allowed-tools` 参数可以精确控制:
```bash
claude -p "检查 package.json 里有没有废弃依赖" \
--allowed-tools Bash(npm audit:*) Bash(cat:*) Read
```
`--allowed-tools` 的值支持 glob 风格匹配,比如 `Bash(git:*)` 匹配所有 git 命令,`Bash(npm install:*)` 只允许 npm install 相关命令。
## Headless 模式的环境差异
Pipe 模式的底层走的是 headless 路径。在 `src/main.tsx`headless 模式会在启动时创建一个轻量级的 `headlessStore`Zustand store跳过 Ink UI 渲染、MCP 交互式认证等需要 TTY 的步骤。
在无 TTY 的环境CI runner、Docker 容器、cron 任务Claude Code 会自动检测并进入 headless 行为。但有一个常见坑:**嵌套 bun 启动时 TTY 检测可能出错**。比如你的脚本用 bun 调用另一个 bun 进程时,子进程可能误判自己有 TTY。
解决方案是设置环境变量 `CLAUDE_CODE_FORCE_INTERACTIVE`
```bash
# 在 CI 脚本中,如果 Claude 意外进入了交互模式(卡住等待输入),
# 反过来设置这个变量让 stdin/stdout/stderr 的 isTTY 被强制标记为 true
CLAUDE_CODE_FORCE_INTERACTIVE=1 claude -p "你的提示词"
```
这个环境变量的处理逻辑在 `src/entrypoints/cli.tsx` 的顶层,在 main() 函数之前就生效。它会把 `process.stdin``process.stdout``process.stderr``isTTY` 属性强行覆写为 `true`。代码注释说这是 "Best-effort dev-only override for nested bun launch on Windows",但实际上在任何嵌套场景都可能用到。
`--bare` 模式是更激进的 headless 变体。它设置 `CLAUDE_CODE_SIMPLE=1`,跳过 hooks、LSP、plugin sync、attribution、auto-memory、background prefetches、keychain reads 和 CLAUDE.md 自动发现。适合只需要最原始能力的 CI 场景:
```bash
claude --bare -p "解释这个函数的作用" --system-prompt "你是一个代码审查助手"
```
注意 `--bare` 模式下 OAuth 和 keychain 认证不会被读取,只能通过 `ANTHROPIC_API_KEY` 环境变量或 `--settings` 参数提供凭证。
## 容器环境与 `CLAUDE_CODE_REMOTE`
在 Docker 容器或远程 CI 环境里跑 Claude Code 时内存管理是个实际问题。Bun/JSC 的内存行为和 Node.js/V8 不同(详见设计篇),在大代码库上可能消耗较多内存。
`src/entrypoints/cli.tsx` 顶层有一段专门处理容器环境的逻辑:
```typescript
if (process.env.CLAUDE_CODE_REMOTE === 'true') {
const existing = process.env.NODE_OPTIONS || '';
process.env.NODE_OPTIONS = existing
? `${existing} --max-old-space-size=8192`
: '--max-old-space-size=8192';
}
```
设置 `CLAUDE_CODE_REMOTE=true` 后,会自动给 `NODE_OPTIONS` 追加 `--max-old-space-size=8192`8GB 上限)。这对 Node.js 运行时的构建产物生效——V8 引擎会尊重这个限制。容器通常有 16GB 内存配额8GB 上限留足余量。
在 Docker Compose 或 CI 配置中这样用:
```yaml
# docker-compose.yml
services:
claude-worker:
image: your-claude-image
environment:
- CLAUDE_CODE_REMOTE=true
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
working_dir: /app
command: ["node", "dist/cli.js", "-p", "运行测试并报告结果"]
```
```yaml
# GitHub Actions workflow
env:
CLAUDE_CODE_REMOTE: true
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
```
## GitHub Actions 集成:`install-github-app`
Claude Code 内置了一套完整的 GitHub Actions 自动配置流程,通过 `/install-github-app` 命令触发。这个命令是 `local-jsx` 类型(交互式 React 组件),会引导你一步步完成配置。
整个流程大致如下:
1. 检查 GitHub CLI (`gh`) 是否安装
2. 选择目标仓库(默认检测当前 git 仓库)
3. 选择 API Key 认证方式(已有 key / 新建 key / OAuth
4. 选择要安装的 workflowPR 助手 `claude.yml` / 代码审查 `claude-code-review.yml`,可多选)
5. 自动创建分支、写入 workflow 文件、设置 secret、打开浏览器创建 PR
安装完成后,你的仓库里会多两个 workflow 文件。
**PR 助手 workflow** (`.github/workflows/claude.yml`):监听 PR/Issue 评论中包含 `@claude` 的事件,自动触发 Claude 执行任务:
```yaml
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]
jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
...
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
```
配置成功后,在 PR 评论中 `@claude 修复这个测试失败`Claude 就会在 GitHub Actions runner 里自动分析、修改代码、提交。
**代码审查 workflow** (`.github/workflows/claude-code-review.yml`):在 PR 创建或更新时自动触发代码审查,使用 `code-review` 插件生成结构化的审查报告。
前置条件:
- 安装 GitHub CLI`brew install gh`macOS或参考 [cli.github.com](https://cli.github.com/)
- `gh` 已登录并有目标仓库的 admin 权限
- 准备好 Anthropic API KeyOAuth token 也支持)
如果不想用交互式命令,`setupGitHubActions.ts` 里暴露了完整的 API 级流程。`install-github-app` 命令本质上就是对这个 API 的 UI 包装。
## `/commit-push-pr`:一键提交、推送、开 PR
`/commit-push-pr` 是一个 prompt 类型命令(不是交互式命令),适合在 CI 或自动化流程中调用。它会分析当前分支相对于默认分支的所有变更(不是只看最新 commit自动生成 commit message、推送到远程、创建 PR。
它内置了一个允许工具白名单,严格限制只能执行 git 和 gh 命令:
```typescript
const ALLOWED_TOOLS = [
'Bash(git checkout --branch:*)',
'Bash(git checkout -b:*)',
'Bash(git add:*)',
'Bash(git status:*)',
'Bash(git push:*)',
'Bash(git commit:*)',
'Bash(gh pr create:*)',
'Bash(gh pr edit:*)',
'Bash(gh pr view:*)',
'Bash(gh pr merge:*)',
'SearchExtraTools',
'mcp__slack__send_message',
'mcp__claude_ai_Slack__slack_send_message',
]
```
在交互式 REPL 中直接输入:
```
/commit-push-pr
```
或者带上额外指令:
```
/commit-push-pr 重点说明新增了缓存层来优化查询性能
```
Claude 会自动查看 `git status``git diff``git branch --show-current`,分析所有相关提交,生成 commit message推送到远程并通过 `gh pr create` 创建 PR。如果 CLAUDE.md 里配置了 Slack 通知,还会尝试搜索 Slack 工具并发送 PR 链接。
Git 安全协议被硬编码在 prompt 里:不更新 git config、不跑破坏性命令`push --force``hard reset`)、不跳 hooks、不提交含密钥的文件。
## `/subscribe-pr`:订阅 PR 事件
`/subscribe-pr` 命令让你关注某个 PR 的动态——新评论、CI 状态变化、review 等。它把订阅信息存在本地的 `~/.claude/pr-subscriptions.json` 文件里。
使用方式:
```
# 通过完整 URL 订阅
/subscribe-pr https://github.com/owner/repo/pull/123
# 通过短引用
/subscribe-pr owner/repo#123
# 如果在 git 仓库内,直接用 PR 编号
/subscribe-pr 123
# 查看当前订阅列表
/subscribe-pr --list
# 取消订阅
/subscribe-pr --remove 123
```
订阅数据结构很简单——每条记录包含仓库、PR 编号和订阅时间。这个功能在 Bridge 模式下特别有用Bridge 层的 `useReplBridge``webhookSanitizer` 会根据订阅过滤入站事件,只推送你关心的 PR 通知。
## Pipe 多会话与 `/pipe-status`
Claude Code 支持主从 pipe 架构——一个主会话可以连接多个子会话,通过 pipe IPC 机制传递消息和任务。`/pipe-status` 命令查看当前连接状态。
有三种角色:
- **Main 模式**:未连接任何子会话的默认状态
- **Slave被控模式**:被主会话控制,所有数据上报给 master
- **Master主控模式**:已连接子会话,可以向子会话派发任务
在 master 模式下,`/pipe-status` 会显示每个子会话的状态、连接时间、历史记录数,并列出可用操作:
```
/pipe-status
# Master mode — 2 sub session(s) connected:
#
# worker-1
# Status: idle (connected)
# Connected: 14:32:05
# History: 12 entries
#
# worker-2
# Status: busy (connected)
# Connected: 14:33:12
# History: 8 entries
#
# Commands:
# /send <name> <msg> — Send a task to a sub session
# /history <name> — View sub session transcript
# /detach [name] — Disconnect from a sub session (or all)
```
## BYOC Runner`environment-runner` 与 `self-hosted-runner`
BYOCBring Your Own ComputeRunner 是两种 headless 长驻运行模式,设计目标是在你自己的基础设施上运行 Claude Code 任务。它们都在 `src/entrypoints/cli.tsx` 中注册为独立的 fast-path避免加载完整 CLI。
**`claude environment-runner`**
```bash
claude environment-runner <args...>
```
这是一个 BYOC自带计算环境的 headless runner。入口在 `src/environment-runner/main.ts`,受 `BYOC_ENVIRONMENT_RUNNER` feature flag 控制。
**`claude self-hosted-runner`**
```bash
claude self-hosted-runner <args...>
```
这是一个自托管 runner对接 SelfHostedRunnerWorkerService APIregister + pollpoll 同时充当 heartbeat。入口在 `src/self-hosted-runner/main.ts`,受 `SELF_HOSTED_RUNNER` feature flag 控制。
注意:这两个 runner 的当前实现是 stub占位`main.ts` 里只有 `Promise.resolve()`。它们是 feature-gated 的,需要在构建时启用对应 feature 才能使用。实际的 BYOC 能力目前更多通过 Bridge 模式(`BRIDGE_MODE`)和 ACP 协议(`ACP`)实现。
如果你想在自己的服务器上长驻运行 Claude 任务,当前可用的替代方案是:
- Bridge 模式:`claude remote-control` 启动后,外部客户端通过 WebSocket 连接
- ACP 协议:`claude --acp` 把 Claude 暴露为 ACP agent
- 自托管 RCS`bun run rcs` 启动 Remote Control Server包含 Web UI
## 定时任务cron + pipe 实现巡检
自动化不只是"跑一次",很多时候你需要定期巡检。有两种方式:
**方式一cron 调用 pipe 模式**
最简单的方式是用系统 crontab 定时调用 `claude -p`
```bash
# 每 30 分钟检查一次主分支是否有新的 CI 失败
*/30 * * * * cd /path/to/repo && claude --bare -p "检查 CI 是否有失败,如果有则列出失败原因" >> /var/log/claude-ci-check.log 2>&1
# 每天早上 9 点生成一份代码变更摘要
0 9 * * * cd /path/to/repo && claude --bare -p "总结过去 24 小时 main 分支的所有变更" | mail -s "日报" team@example.com
```
**方式二:`/schedule` 远程 cron 触发器**
`/schedule` 命令创建远程 cron 触发器,由服务端按计划触发(需要认证)。这种方式不依赖本机在线:
```
# 创建一个每小时触发一次的巡检任务
/schedule create "检查依赖安全漏洞" --cron "0 * * * *" --prompt "运行 npm audit 并报告高危漏洞"
```
更详细的内容见第七章Daemon、Background Sessions、Schedule
## 退出码与脚本判断
在脚本里调用 Claude 时判断成功失败很重要。Pipe 模式下Claude Code 的退出码取决于执行结果:
- `0`:正常完成
-`0`:出错或被拒绝
结合 shell 的 `&&` / `||` 可以实现条件执行:
```bash
# 只有 Claude 确认代码正确才执行部署
claude -p "审查这个 PR 的代码质量,如果有问题就说 FAIL" && ./deploy.sh
# Claude 分析失败时发送告警
claude -p "分析错误日志 /var/log/app.log" || echo "分析失败,需要人工介入" | mail -s "告警" ops@example.com
```
`src/entrypoints/cli.tsx` 中,各个 fast-path 在出错时通过 `process.exitCode = 1``process.exit(1)` 设置退出码。主流程的退出码由 `src/main.tsx` 中的 action handler 决定。
一个实用的 CI 脚本模板:
```bash
#!/bin/bash
set -euo pipefail
# 环境准备
export ANTHROPIC_API_KEY="${API_KEY}"
export CLAUDE_CODE_REMOTE=true # 容器环境内存优化
# 运行 Claude 分析
if claude --bare -p "检查 src/ 下是否有明显的 bug 或安全问题" --allowed-tools "Read Grep Glob"; then
echo "检查通过"
exit 0
else
echo "发现问题,检查输出"
exit 1
fi
```
## `CLAUDE_CODE_ABLATION_BASELINE`:消融实验基线
`CLAUDE_CODE_ABLATION_BASELINE` 是一个用于 harness-science L0 消融实验的环境变量。当同时满足 `feature('ABLATION_BASELINE')` 和设置了该环境变量时,`cli.tsx` 顶层会批量设置一组简化开关:
```
CLAUDE_CODE_SIMPLE=1 # 简化模式
CLAUDE_CODE_DISABLE_THINKING=1 # 禁用 thinking
DISABLE_INTERLEAVED_THINKING=1 # 禁用交错 thinking
DISABLE_COMPACT=1 # 禁用 compact
DISABLE_AUTO_COMPACT=1 # 禁用自动 compact
CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 # 禁用自动记忆
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 # 禁用后台任务
```
这个逻辑被特意放在 `cli.tsx` 的顶层(不在 `init.ts` 里),因为 `BashTool``AgentTool``PowerShellTool` 在 import 时就把 `DISABLE_BACKGROUND_TASKS` 等环境变量捕获进模块级常量——如果放在 `init()` 里就太晚了。
普通用户不需要关心这个环境变量。它是给做模型能力消融实验的研究者用的。
## 下一步
- 想在 PR 评论中自动触发 Claude回到本章"GitHub Actions 集成"部分,参考 `setupGitHubActions` 的自动配置流程
- 想了解 `@claude` 在 GitHub 中的完整配置,看 [claude-code-action 仓库](https://github.com/anthropics/claude-code-action) 的使用文档
- 想让 Claude 定时自动执行任务(不依赖本机 crontab看 [第七章Daemon、Background Sessions、Schedule](./07-daemon-bg-schedule.md)
- 想把 Claude 暴露给外部客户端调用,看 [第八章Bridge、Remote Control、ACP](./08-bridge-rcs-acp.md)
- 想限制 Claude 在 CI 中的权限,看 [第九章:权限规则配置指南](./09-savings-hooks-config.md) 中的 `allow` / `deny` 规则部分