<!-- title: Claude Code驱动CI/CD自动化流水线 -->

# Claude Code 驱动 CI/CD 全自动化流水线实战

## 概述

本教程面向已经熟悉 Claude Code 交互式用法的开发者与 DevOps 工程师，目标是把 Claude Code 从"工程师本地的对话伙伴"升级为"CI/CD 流水线里的常驻 Agent"。我们将围绕三大支柱——`-p` 无头模式、GitHub Actions 官方 Action、Hooks 生命周期事件——搭建一条覆盖 **PR 自动审查、定时日报、提交规范门禁、批量 Issue 处理** 的完整自动化流水线。学完后你能让 Claude 在每次提交、每个 PR、每天定时自动工作，且全程可审计、可计费、可复现。

## 前置条件

- 已安装 Claude Code CLI（`claude -v` 可输出版本，建议 v2.1.128 以上以获得本文提到的全部能力）
- 一个 GitHub 仓库的 **管理员** 权限（用于安装 GitHub App 与添加 Secrets）
- 一个 `ANTHROPIC_API_KEY`（或 Bedrock / Vertex 凭证）
- 基础的 YAML、`jq`、Shell 知识
- 阅读过本系列前三轮（安装篇、Skill 开发篇、MCP 服务器篇）会更顺畅，但非必需

---

## 第一步：理解无头模式的三个关键开关

交互模式面向人，无头模式面向脚本。无头模式由 `-p`（`--print`）开启，但真正决定它在 CI 中是否"可复现、可控成本"的是另外几个开关。

### 操作说明

最朴素的无头调用：

```bash
claude -p "What does the auth module do?"
```

这条命令在 CI 里能跑，但有两个隐患：一是它默认会加载本机 `~/.claude` 与项目 `.claude/` 下的全部 hooks、skills、plugins、MCP 服务器与 `CLAUDE.md`，导致**同一仓库在不同机器上行为不一致**；二是它不会告诉你这次调用花了多少钱。

官方推荐的解法是 **`--bare` 模式**。加上它，Claude 会跳过上述全部自动发现逻辑，只承认你显式传入的 flag：

```bash
claude --bare -p "Summarize this file" --allowedTools "Read"
```

`--bare` 模式下 Claude 仍保留 Bash、文件读、文件写三种基础工具，其余上下文通过 flag 注入：

| 需要加载的内容 | 对应 flag |
| --- | --- |
| 系统提示词补充 | `--append-system-prompt`、`--append-system-prompt-file` |
| 配置 | `--settings <file-or-json>` |
| MCP 服务器 | `--mcp-config <file-or-json>` |
| 自定义子 Agent | `--agents <json>` |
| 插件 | `--plugin-dir <path>`、`--plugin-url <url>` |

官方明确指出：**`--bare` 是脚本与 SDK 调用的推荐模式，未来会成为 `-p` 的默认行为**。所以从第一天起就用 `--bare` 写 CI，等于提前对齐未来版本。

第三个开关是 **`--output-format`**，它把"看不懂的文本"变成"程序能解析的结构"：

- `text`（默认）：纯文本
- `json`：结构化 JSON，包含 `result`、`session_id` 与 `total_cost_usd` 及分模型成本拆解
- `stream-json`：换行分隔的 JSON，用于实时流式处理

### 预期结果

```bash
claude -p "Summarize this project" --output-format json
```

返回 payload 中关键字段如下：

```json
{
  "type": "result",
  "subtype": "success",
  "result": "This project is a FastAPI-based ...",
  "session_id": "abc123...",
  "total_cost_usd": 0.0421,
  "usage": { "input_tokens": 12034, "output_tokens": 856 }
}
```

`total_cost_usd` 让脚本调用方无需打开用量面板就能逐次核算成本——这是 CI 里做"成本门禁"的基础。

### 常见问题

**Q：报错 stdin 超过 10MB？**
自 v2.1.128 起，管道传入的 stdin 上限为 10MB，超出会非零退出并给出清晰错误。解决办法：把内容写入文件，在 prompt 里引用文件路径，而不是用管道喂进去。

**Q：CI 跑完不退出，一直挂起？**
如果你在无头任务里启动了后台 Bash（比如 `npm run dev`），v2.1.163 之前它会永久挂住进程；新版本会在 Claude 返回最终结果、stdin 关闭后约 5 秒终止该后台任务。务必升级，或在 prompt 里明确禁止启动长驻进程。

---

## 第二步：让 Claude 产出机器可读的确定性结果

CI 自动化的命门是"输出必须可被下一步解析"。`--output-format json` 解决了格式问题，但要保证**字段结构稳定**，必须用 `--json-schema`。

### 操作说明

下面这条命令从 `auth.py` 抽取函数名，并强制返回符合指定 schema 的对象：

```bash
claude -p "Extract the main function names from auth.py" \
  --output-format json \
  --json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}'
```

响应里，结构化数据落在 `structured_output` 字段（其余仍是元数据）。配合 `jq` 取值：

```bash
claude -p "Extract function names from auth.py" \
  --output-format json \
  --json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}' \
  | jq '.structured_output.functions'
```

要拿纯文本结论则用 `.result`：

```bash
claude -p "Summarize this project" --output-format json | jq -r '.result'
```

### 预期结果

```json
{
  "result": "...",
  "structured_output": { "functions": ["login", "refresh_token", "logout"] },
  "total_cost_usd": 0.018
}
```

### 常见问题

**Q：schema 校验失败导致重试，成本飙升？**
`--json-schema` 在工具层强制校验，模型不匹配会重试。给 schema 设宽松一些（如允许 `additionalProperties`、用 `oneOf` 表达可选字段），并配合 `--max-turns` 限制轮次，可避免无限重试烧钱。

**Q：流式场景怎么取增量文本？**
用 `--output-format stream-json --verbose --include-partial-messages`，逐行是事件 JSON，再用 `jq` 过滤 `text_delta` 类型事件即可实现打字机效果或实时日志。

---

## 第三步：把无头模式嵌进构建脚本

无头模式最轻量的落地点是 `package.json` 脚本——它把 Claude 当成一个"项目级 linter"。

### 操作说明

下面这个脚本把相对 `main` 的 diff 管道喂给 Claude，让它只报拼写错误。管道喂 diff 的好处是 Claude 不需要 Bash 权限去读文件，且转义后的双引号让脚本在 Windows 上也能跑：

```json
{
  "scripts": {
    "lint:claude": "git diff main | claude -p \"you are a typo linter. for each typo in this diff, report filename:line on one line and the issue on the next. return nothing else.\""
  }
}
```

同理可做"构建失败根因解释器"：

```bash
cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt
```

### 预期结果

`npm run lint:claude` 输出形如：

```
src/auth/session.ts:142
recieve -> receive
src/utils/parser.go:8
paramter -> parameter
```

干净、可 grep、可被后续脚本消费。

### 常见问题

**Q：CI 上每次结果不一样？**
八成是没加 `--bare`，加载了某位同事 `~/.claude` 里的 hook。统一加 `--bare` 并把系统提示词用 `--append-system-prompt-file` 指向仓库内受版本控制的文件，即可复现。

---

## 第四步：安装官方 GitHub Action，让 PR 里 `@claude` 即可派活

第三步是"本地脚本"，第四步是"团队级平台能力"。Anthropic 官方维护了 `anthropics/claude-code-action`，让任何人在 issue 或 PR 评论里 `@claude` 就能派活。

### 操作说明

最快的安装方式是在终端里：

```bash
claude
# 进入交互式会话后执行
/install-github-app
```

该命令会引导你安装 GitHub App 并配置所需 Secrets。手动安装则需：

1. 安装 Claude GitHub App（`https://github.com/apps/claude`），授权 Contents / Issues / Pull requests 的读写权限；
2. 在仓库 Secrets 里加 `ANTHROPIC_API_KEY`；
3. 把官方 `examples/claude.yml` 复制到 `.github/workflows/`。

注意 **v1.0 有破坏性变更**，从 beta 升级必须改 workflow：

| Beta 输入 | v1.0 输入 |
| --- | --- |
| `mode: "tag"` / `"agent"` | 删除，现自动检测 |
| `direct_prompt` | `prompt` |
| `custom_instructions` | `claude_args: --append-system-prompt` |
| `max_turns` | `claude_args: --max-turns` |
| `model` | `claude_args: --model` |
| `allowed_tools` | `claude_args: --allowedTools` |

最基础的响应式工作流（评论里 `@claude` 触发）：

```yaml
name: Claude Code
on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]
jobs:
  claude:
    runs-on: ubuntu-latest
    steps:
      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
```

### 预期结果

在任意 PR 评论里输入 `@claude fix the TypeError in the user dashboard component`，Action 会自动分析上下文、修改代码并推送提交。

### 常见问题

**Q：用 Bedrock / Vertex 怎么办？**
`/install-github-app` 仅支持直连 Claude API。Bedrock/Vertex 用户需参考官方文档的 provider 凭证配置章节，用各自的凭证体系替代 `ANTHROPIC_API_KEY`。

**Q：怎么限制 Claude 的工具权限？**
通过 `claude_args: "--allowedTools Read,Edit,Bash --disallowedTools ..."` 精确收口，避免 Agent 在 CI runner 上执行危险操作。

---

## 第五步：在 Action 里调用 Skill 与定时任务

官方 Action 的 `prompt` 既能接受纯文本，也能接受 **Skill 调用**。这让"团队提示词库"直接进入 CI。

### 操作说明

下面这个工作流安装 `code-review` 插件，并在每个新建/更新的 PR 上运行其 Skill：

```yaml
name: Code Review
on:
  pull_request:
    types: [opened, synchronize]
jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          plugin_marketplaces: "https://github.com/anthropics/claude-code.git"
          plugins: "code-review@claude-code-plugins"
          prompt: "/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}"
```

定时任务用 GitHub 原生 `schedule`：

```yaml
name: Daily Report
on:
  schedule:
    - cron: "0 9 * * *"
jobs:
  report:
    runs-on: ubuntu-latest
    steps:
      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          prompt: "Generate a summary of yesterday's commits and open issues"
          claude_args: "--model opus"
```

### 预期结果

每天 09:00 UTC 自动生成"昨日提交 + 未关闭 Issue"摘要，可作为站会简报或周报素材。

### 常见问题

**Q：Skill 在仓库里而非插件里怎么调？**
在 Action 之前加一步 `actions/checkout`，然后 `prompt: /skill-name`。注意 Skill 必须放在 `.claude/skills/` 下且 frontmatter 合法。

---

## 第六步：用 Hooks 给整条流水线加"自动门禁与副作用"

Hooks 是 Claude Code 工作流特定节点上自动执行的 Shell 命令。它们是流水线里"无需人介入的自动化动作"和"硬性规则执行"的核心机制。

### 操作说明

Hooks 在 `~/.claude/settings.json` 或项目 `.claude/settings.json` 里配置。核心事件类型：

| 事件 | 触发时机 | 典型用途 |
| --- | --- | --- |
| `PreToolUse` | 工具执行**前** | 拦截危险命令、写前 lint、审计日志 |
| `PostToolUse` | 工具执行**后** | 写后格式化（prettier/black/gofmt）、跑测试、自动提交、发通知 |
| `UserPromptSubmit` | 用户提交 prompt | 注入上下文、关键词拦截 |
| `Notification` | 需要通知时 | 推 Slack/飞书 |
| `Stop` / `SubagentStop` | 主/子 Agent 结束 | 汇总、清理、发报告 |
| `SessionStart` / `SessionEnd` | 会话起止 | 初始化环境、归档 |

最经典的"写后自动格式化 + 跑测试"组合：

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "command": "scripts/guard-write.sh"
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "command": "prettier --write $CLAUDE_FILE_PATHS && npm test --silent"
      }
    ]
  }
}
```

`PreToolUse` 返回非零退出码（或通过 stdout 输出 JSON 的 `decision: "block"`）会**阻止该工具调用**，这是"提交规范门禁"的实现基础。

### 预期结果

Claude 每写一个文件，自动 `prettier` 格式化并跑一次测试；任何对 `secrets/*` 的写入都会被 `guard-write.sh` 拦下并在会话里给出原因。

### 常见问题

**Q：CI 上 hooks 没生效？**
默认 `-p` 会加载项目 hooks，但若你用了 `--bare`，hooks 会被跳过。CI 里建议**显式**用 `--settings` 注入受版本控制的 settings 文件，而不是依赖隐式发现。

**Q：hook 失败导致整条流水线红？**
生产环境务必给 hook 脚本加 `set +e` 或用 `|| true` 容错，把"门禁型 hook"（必须阻断）与"增强型 hook"（失败可忽略）分开。

---

## 第七步：开通托管 Code Review，零配置拿多 Agent 审查

如果你不想自己维护审查流水线，Anthropic 提供**托管 Code Review**（Team/Enterprise 可用，research preview）。它与自建 Action 的区别是：审查跑在 Anthropic 基础设施上，一个 **Agent 编队** 并行检查不同类别的缺陷，再经一步验证过滤误报，最终以 inline 评论形式贴在出问题的代码行上。

### 工作机制

- **触发**：PR 打开、每次推送，或评论 `@claude review` / `@claude review once`；
- **严重等级**：🔴 Important（合并前应修的 bug）、🟡 Nit（值得修但不阻塞）、🟣 Pre-existing（PR 之前就存在的 bug）；
- **产出**：inline 评论 + check run 汇总表，按严重度排序；
- **反馈闭环**：每条评论自带 👍/👎，PR 合并后 Anthropic 收集计数用于调优审查器。

本地不装 GitHub App 也能用：在任意 Claude Code 会话里运行 `/code-review`，直接在终端审查 diff。

### 与自建流水线的关系

托管 Code Review 负责"发现问题"，自建 Action + hooks 负责"修复 + 门禁"。两者互补：托管服务贴出 🔴 Important，再用 `@claude fix` 触发自建 Action 落地修复，最后由 `PostToolUse` hook 跑测试验证。

---

## 实战案例：一条端到端的"PR 守护流水线"

目标：为一个开源 Python 项目搭建——**PR 一旦打开，自动多 Agent 审查 → 自动修复低危问题 → 跑测试 → 生成中文摘要；每天定时输出日报；本地提交受 hooks 门禁约束**。

### 1. 目录结构

```
repo/
├── .github/workflows/
│   ├── claude-review.yml      # 托管 Code Review 触发
│   ├── claude-fix.yml         # @claude 修复
│   └── daily-report.yml       # 定时日报
├── .claude/
│   ├── settings.json          # hooks 配置
│   └── CLAUDE.md              # 项目规范
└── scripts/
    └── guard-write.sh         # 写入门禁
```

### 2. `.claude/CLAUDE.md`（节选）

```markdown
# 项目规范
- 使用 Python 3.11，类型注解必须完整
- 所有公共函数需有 docstring
- 禁止提交 .env / 密钥文件
- 测试框架：pytest，覆盖率门槛 80%
```

### 3. PR 审查 + 自动修复（`claude-review.yml`）

```yaml
name: Claude Review & Fix
on:
  pull_request:
    types: [opened, synchronize]
jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          prompt: |
            审查本 PR 的 diff。对每个 🔴 Important 问题：
            1) 直接修改代码修复；
            2) 运行 pytest 验证；
            3) 把未修复的 🟡 Nit 汇总成中文清单回复。
          claude_args: |
            --bare
            --allowedTools "Read,Edit,Bash"
            --max-turns 25
            --output-format json
```

### 4. 每日中文日报（`daily-report.yml`）

```yaml
name: Daily Report
on:
  schedule:
    - cron: "30 1 * * *"   # 北京时间 09:30
  workflow_dispatch:
jobs:
  report:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          prompt: |
            基于 git log（昨日）与 open issues，
            生成一份中文日报：进展、风险、今日建议。
          claude_args: "--bare --output-format json --model sonnet"
```

### 5. 本地门禁（`.claude/settings.json`）

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "command": "scripts/guard-write.sh"
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "command": "ruff format $CLAUDE_FILE_PATHS && ruff check --fix $CLAUDE_FILE_PATHS && pytest -q"
      }
    ]
  }
}
```

### 6. 整体工作流

```mermaid
flowchart TD
    A[开发者推送 / 开 PR] --> B[GitHub Actions 触发]
    B --> C[托管 Code Review<br/>多 Agent 并行]
    C --> D{发现缺陷?}
    D -- 是 --> E[claude-code-action@v1<br/>bare + json-schema]
    E --> F[PostToolUse Hook<br/>ruff + pytest 验证]
    F --> G[修复提交 + 中文摘要]
    D -- 否 --> H[check run 绿灯]
    I[每日 cron 09:30] --> J[生成交日报]
    K[本地编辑] --> L[PreToolUse Hook 门禁]
    L --> M{命中禁区?}
    M -- 是 --> N[阻断并提示]
    M -- 否 --> O[放行写入]
    O --> F
    style C fill:#ffe0e6
    style E fill:#e0f0ff
    style F fill:#e6ffe0
```

### 关键设计取舍

- **`--bare` + 显式 `--settings`**：保证 CI 在任何机器上行为一致，不踩"同事 hook 污染"的坑；
- **`--max-turns 25`**：硬上限，防止 Agent 失控烧光 Agent SDK 月度额度；
- **`--output-format json`**：`total_cost_usd` 字段供后续做"单 PR 成本看板"；
- **门禁 hook 与增强 hook 分离**：`PreToolUse` 必须阻断，`PostToolUse` 失败用 `|| true` 容错。

---

## 成本与额度要点

- **2026 年 6 月 15 日起**，订阅计划上的 Agent SDK 与 `claude -p` 用量从**独立的月度 Agent SDK 额度**扣除，与交互式用量分开计。这对 CI 自动化是利好——流水线跑爆不会直接影响你日常对话额度，但也意味着要在 CI 层做用量预算；
- 用 `--output-format json` 的 `total_cost_usd` 在每次调用后落库，配合 Grafana 即可做"每日 Agent 消费看板"；
- `--max-turns`、`--model`、`--disallowedTools` 是 CI 侧的三大成本与安全阀门，务必每次显式设置。

---

## 延伸阅读

- 官方 Headless 文档（`code.claude.com/docs/en/headless`）：`--bare`、`--output-format`、`--json-schema` 的权威说明
- 官方 GitHub Actions 文档（`code.claude.com/docs/en/github-actions`）：`anthropics/claude-code-action@v1` 全部输入项与迁移指南
- 官方 Code Review 文档（`code.claude.com/docs/en/code-review`）：托管多 Agent 审查的严重度模型与定价
- Agent SDK 文档：Python / TypeScript 包的 `query()`、tool-approval 回调与原生消息对象
- Hooks 参考与 `settings.json` schema：`PreToolUse` / `PostToolUse` 等事件与 `decision: block` 阻断语义

---

## 训练营适用性评估

- **适合类型**：企业级 DevOps / 平台工程训练营、AI 研发效能（DevEx）训练营、中高级 Claude Code 工程师认证营
- **不适合**：纯零基础营（需先掌握交互模式与基本 Git/CI 概念）
- **建议时长**：理论 1.5 小时 + 动手实验 3 小时。实验产出物即本文实战案例的完整流水线，可作为结业作品
- **前置衔接**：建议放在系列第 4 天，承接前三轮（安装、Skill、MCP），为第 5 天"高级技巧与性能优化"做铺垫
- **考核点**：(1) 能否写出可复现的 `--bare` 无头脚本；(2) 能否用 `--json-schema` 拿到稳定结构化输出；(3) 能否配置一套 Pre/PostToolUse 门禁；(4) 能否在 GitHub Actions 里跑通 `@v1` 并完成一次自动修复

## 参考来源

1. [Run Claude Code programmatically (官方 Headless 文档)](https://code.claude.com/docs/en/headless) — `-p`、`--bare`、`--output-format`、`--json-schema` 与 Agent SDK 月度额度的权威定义
2. [Claude Code GitHub Actions (官方)](https://code.claude.com/docs/en/github-actions) — `anthropics/claude-code-action@v1` 安装、v1.0 迁移、Skill 与定时任务用法
3. [Code Review (官方)](https://code.claude.com/docs/en/code-review) — 托管多 Agent 审查的触发、严重度等级与 inline 评论机制
4. [Claude Code Headless Mode for Batch Tasks and CI/CD (Restato 博客)](https://restato.github.io/blog/claude-code-headless-mode/) — 批量任务与 CI/CD 集成的工程实践补充
5. [The Ultimate Headless Claude Code Guide (GitHub: mjmirza/headless-claude)](https://github.com/mjmirza/headless-claude) — 生产级 headless 自动化的可复用模板与脚本

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
