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

16 KiB
Raw Blame History

第十一章:自动化与 CI 集成 —— 把 Claude 嵌入流水线

不想每次都手动对话?让 Claude 在脚本、CI 和容器里自动干活。

Pipe 模式:一句话调用,拿结果就走

Pipe 模式(也叫 headless / print 模式)是 Claude Code 最直接的自动化入口。不需要 TTY不需要交互传入提示词拿回结果进程退出。它在 src/main.tsx 里注册为 -p, --print 选项,描述原文是 "Print response and exit (useful for pipes)"。

最基本的用法:

# 把结果直接输出到终端
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 格式的结果,方便脚本解析:

claude -p "列出 3 个最常见的 TypeScript 性能问题" --output-format json

第三,支持流式 JSON 输出(--output-format stream-json),适合需要实时处理中间结果的场景。

第四,可以限制工具白名单。在 CI 环境中,你可能不想让 Claude 随意执行任意命令。通过 --allowed-tools 参数可以精确控制:

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.tsxheadless 模式会在启动时创建一个轻量级的 headlessStoreZustand store跳过 Ink UI 渲染、MCP 交互式认证等需要 TTY 的步骤。

在无 TTY 的环境CI runner、Docker 容器、cron 任务Claude Code 会自动检测并进入 headless 行为。但有一个常见坑:嵌套 bun 启动时 TTY 检测可能出错。比如你的脚本用 bun 调用另一个 bun 进程时,子进程可能误判自己有 TTY。

解决方案是设置环境变量 CLAUDE_CODE_FORCE_INTERACTIVE

# 在 CI 脚本中,如果 Claude 意外进入了交互模式(卡住等待输入),
# 反过来设置这个变量让 stdin/stdout/stderr 的 isTTY 被强制标记为 true
CLAUDE_CODE_FORCE_INTERACTIVE=1 claude -p "你的提示词"

这个环境变量的处理逻辑在 src/entrypoints/cli.tsx 的顶层,在 main() 函数之前就生效。它会把 process.stdinprocess.stdoutprocess.stderrisTTY 属性强行覆写为 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 场景:

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 顶层有一段专门处理容器环境的逻辑:

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=81928GB 上限)。这对 Node.js 运行时的构建产物生效——V8 引擎会尊重这个限制。容器通常有 16GB 内存配额8GB 上限留足余量。

在 Docker Compose 或 CI 配置中这样用:

# 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", "运行测试并报告结果"]
# 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 执行任务:

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 CLIbrew install ghmacOS或参考 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 命令:

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 statusgit diffgit branch --show-current,分析所有相关提交,生成 commit message推送到远程并通过 gh pr create 创建 PR。如果 CLAUDE.md 里配置了 Slack 通知,还会尝试搜索 Slack 工具并发送 PR 链接。

Git 安全协议被硬编码在 prompt 里:不更新 git config、不跑破坏性命令push --forcehard 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 层的 useReplBridgewebhookSanitizer 会根据订阅过滤入站事件,只推送你关心的 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 Runnerenvironment-runnerself-hosted-runner

BYOCBring Your Own ComputeRunner 是两种 headless 长驻运行模式,设计目标是在你自己的基础设施上运行 Claude Code 任务。它们都在 src/entrypoints/cli.tsx 中注册为独立的 fast-path避免加载完整 CLI。

claude environment-runner

claude environment-runner <args...>

这是一个 BYOC自带计算环境的 headless runner。入口在 src/environment-runner/main.ts,受 BYOC_ENVIRONMENT_RUNNER feature flag 控制。

claude self-hosted-runner

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
  • 自托管 RCSbun run rcs 启动 Remote Control Server包含 Web UI

定时任务cron + pipe 实现巡检

自动化不只是"跑一次",很多时候你需要定期巡检。有两种方式:

方式一cron 调用 pipe 模式

最简单的方式是用系统 crontab 定时调用 claude -p

# 每 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 的 && / || 可以实现条件执行:

# 只有 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 = 1process.exit(1) 设置退出码。主流程的退出码由 src/main.tsx 中的 action handler 决定。

一个实用的 CI 脚本模板:

#!/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 里),因为 BashToolAgentToolPowerShellTool 在 import 时就把 DISABLE_BACKGROUND_TASKS 等环境变量捕获进模块级常量——如果放在 init() 里就太晚了。

普通用户不需要关心这个环境变量。它是给做模型能力消融实验的研究者用的。

下一步