课程大纲 › 领域 3:Claude Code 配置与工作流

3.6 将 Claude Code 集成进 CI/CD 流水线

タスクステートメント3.6:ClaudeCodeをCI/CDパイプラインに統合する

官方大纲原文(日文):知识 4 条 · 技能 5 条

需要掌握的知识

  • 自動化されたパイプラインでClaude Codeを非対話モードで実行するための-p(または--print)フラグ
  • CIのコンテキストで構造化出力を強制するための--output-format jsonおよび--json-schemaのCLIフラグ
  • CIから呼び出されるClaude Codeにプロジェクトのコンテキスト(テスト標準、フィクスチャの規約、レビュー基準)を提供する仕組みとしてのCLAUDE.md
  • セッションコンテキストの分離:コードを生成したのと同じClaudeセッションは、独立したレビューインスタンスと比べて、自身の変更をレビューする効果が低い理由

需要能做到的事

  • CIで-pフラグを付けてClaude Codeを実行し、対話的な入力待ちによるハングを防ぐ
  • --output-format jsonを--json-schemaとともに使用し、PRのインラインコメントとして自動投稿するための、機械で解析可能な構造化された指摘事項を生成する
  • 新しいコミットの後にレビューを再実行する際に、以前のレビューの指摘事項をコンテキストに含め、重複コメントを避けるために新規または未対応の問題のみを報告するようClaudeに指示する
  • 既存のテストファイルをコンテキストに提供し、テスト生成において、テストスイートですでにカバーされている重複シナリオが提案されないようにする
  • テスト標準、価値のあるテストの基準、利用可能なフィクスチャをCLAUDE.mdに文書化し、テスト生成の品質を高め、価値の低いテスト出力を減らす

课程讲解 · AI 草稿,未经人工审核 以官方文档为准

这一条考什么

考你能否把 Claude Code 稳定地嵌入 CI/CD:用 -p(--print)非交互运行避免挂起;用 --output-format json 加 --json-schema 得到可机器解析的结构化结果,用于自动发布 PR 行内评论;用 CLAUDE.md 给 CI 中的 Claude 提供测试标准、fixture 约定和审查标准;在新提交后重跑审查时带上旧结论只报新问题;生成测试时提供已有测试避免重复;并理解为什么让生成代码的同一会话来审查自己的改动效果较差。

核心概念

-p:非交互模式

交互式的 claude 会等待用户输入,在 CI 里就会一直挂起直到超时。claude -p "提示词"(或 --print)执行一次任务后输出结果并退出,适合流水线。常配合的参数:

  • --allowedTools:预先允许需要的工具,避免权限确认卡住流程。
  • --max-turns:限制 Agent 的回合数。
  • --max-budget-usd:限制单次调用的花费上限。
  • --append-system-prompt:在 Claude Code 默认系统提示之后追加审查指令,保留默认的工具使用能力;用 --system-prompt 则会整体替换默认提示,可能让 Claude 不再主动探索相关文件。
git diff origin/main...HEAD | claude -p "审查这个 diff,必要时读取相关文件确认调用方影响" \
  --append-system-prompt "你是严格的代码审查者,只报告 bug 与安全问题" \
  --allowedTools "Read,Grep,Glob" \
  --max-turns 15 --max-budget-usd 2.00

--output-format json 与 --json-schema

--output-format json 让 CLI 输出一个 JSON 对象(包含结果文本、会话 ID、费用等元数据),而非纯文本。再加上 --json-schema 传入 JSON Schema,Claude Code 会让最终结果符合该结构,结构化数据出现在输出的专门字段中(结构化输出字段),可直接被脚本解析:

SCHEMA='{
  "type": "object",
  "properties": {
    "findings": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "path": {"type": "string"},
          "line": {"type": "integer"},
          "severity": {"type": "string", "enum": ["critical", "major", "minor"]},
          "issue": {"type": "string"},
          "suggestion": {"type": "string"}
        },
        "required": ["path", "line", "severity", "issue"]
      }
    }
  },
  "required": ["findings"]
}'

claude -p "审查 origin/main...HEAD 的改动" \
  --allowedTools "Read,Grep,Glob,Bash(git diff:*)" \
  --output-format json --json-schema "$SCHEMA" > review.json

之后的脚本遍历 findings,用 GitHub API 在对应 path 和 line 发表行内评论。纯文本输出则需要正则解析,脆弱且易错。

CLAUDE.md 是 CI 中的项目上下文

CI 里运行的 Claude Code 同样会读取仓库的 CLAUDE.md。把以下内容写进去,CI 中的审查和测试生成就有了统一的标准:

## 测试标准
- 有价值的测试:验证业务规则、边界值、错误路径;不要写只断言“不抛异常”的测试
- 可用 fixture:tests/fixtures/users.py 中的 make_user()、make_admin();数据库测试使用 db_session fixture
- 新测试不得与 tests/ 中已有场景重复

## 审查标准
- 报告:逻辑错误、安全漏洞、数据丢失风险
- 不报告:lint 已覆盖的格式问题、团队有意使用的模式(见下)
- 有意使用的模式:Swift 中经评审的强制解包、generated/ 下的生成代码

这样能从源头减少低价值输出,比生成后再用第二次调用打分过滤、或用关键词后处理压制更根本。若 CI 为了启动速度使用精简模式(如 --bare 跳过自动发现 CLAUDE.md 等),则需要用 --append-system-prompt-file ./CLAUDE.md 之类的方式显式加载标准。

重跑审查:只报新增或未解决的问题

PR 收到新提交后再次审查,如果不提供之前的结论,Claude 会重复发表已有评论,刷屏且令人烦躁。做法:把上一轮的 findings(以及哪些已被解决)放进提示,明确要求“只报告新的或仍未解决的问题”。

claude -p "以下是上一轮审查结论:$(cat previous_findings.json)
请审查最新改动,只报告新出现的问题或上述仍未修复的问题,已修复的不要再报,相同问题不要重复。" \
  --output-format json --json-schema "$SCHEMA"

生成测试时提供已有测试

让 Claude 生成测试时,把现有测试文件放进上下文(或允许它 Read 相关测试目录),它才能知道哪些场景已覆盖,避免提出重复测试。

会话上下文隔离:独立审查更有效

生成代码的那个会话里,保留着它当时的推理和假设,审查时容易沿用同样的思路,“看不见”自己的盲点。一个全新的、独立的审查实例只看到代码和标准,没有先入为主的推理,更可能发现问题。因此 CI 中应让审查作为单独的 claude -p 调用运行,而不是在生成代码的会话里追加“请检查一下你刚写的代码”。

正确做法与反模式

  • 正确:CI 中一律使用 claude -p,并预设 --allowedTools。反模式:直接运行交互式 claude,作业挂起直到超时。
  • 正确:--output-format json + --json-schema 产出结构化 findings,再自动发行内评论。反模式:解析自由文本、用正则提取文件名和行号。
  • 正确:在 CLAUDE.md 中写测试标准、有价值测试的标准、可用 fixture 和审查标准。反模式:生成后再用第二个模型打分过滤,或按目录历史接受率限制生成范围。
  • 正确:重跑审查时附上旧 findings,只报新问题或未解决问题。反模式:每次从零审查,重复评论。
  • 正确:生成测试时提供已有测试文件。反模式:只给源码,让它从零想测试场景。
  • 正确:用独立实例审查生成的代码。反模式:让同一会话自我审查。

常见陷阱

  • 用作业级超时代替 Claude Code 自身限制:题目要求“由 Claude Code 本身限制回合数和花费”时,答案是 --max-turns 与 --max-budget-usd,而不是 CI 的 timeout 或换更便宜的模型。
  • `--system-prompt` 与 `--append-system-prompt` 混淆:替换默认提示可能导致 Claude 不再主动读取相关文件;想保留默认能力并加审查指令,用追加。
  • 后处理过滤代替前置上下文:关键词过滤、二次打分、行内抑制注释都是“事后补救”,题干问“从源头防止”时选 CLAUDE.md 文档化。
  • 只看 diff 不看上下文:限制 Claude 只看改动行会让它更容易误判,而不是减少误报。
  • 同一会话自审:“让生成代码的会话最后再审一遍”是看似省事的干扰项。
  • 批处理的适用性:若题目引入 Message Batches API,关键看“最长 24 小时返回”是否可接受;阻塞合并的 PR 审查一般不适合。

实操练习

目标:在 GitHub Actions 中用 Claude Code 产生结构化审查结果,并在第二次运行时只报告新问题。

  1. 在仓库 CLAUDE.md 中加入上文的“审查标准”和“测试标准”。
  2. 在 .github/workflows/review.yml 添加下面的作业(需在仓库 secrets 中配置 ANTHROPIC_API_KEY)。
  3. 提交一个故意带 SQL 拼接的 PR,查看生成的 review.json。
  4. 推送一个修复了 SQL 问题、但新增一个空指针问题的提交,确认第二次只报告空指针问题。
# .github/workflows/review.yml 中 run 步骤的核心脚本
set -euo pipefail
npm install -g @anthropic-ai/claude-code
PREV=$( [ -f .review/previous.json ] && cat .review/previous.json || echo '{"findings":[]}' )
claude -p "审查 origin/main...HEAD 的改动。上一轮结论:$PREV 。只报告新问题或未修复的问题。" \
  --append-system-prompt "按 CLAUDE.md 中的审查标准判断" \
  --allowedTools "Read,Grep,Glob,Bash(git diff:*)" \
  --max-turns 15 --max-budget-usd 2.00 \
  --output-format json --json-schema "$(cat .github/review-schema.json)" > review.json
jq '.' review.json

检查结果:作业不挂起并正常退出;review.json 中能解析出符合 schema 的 findings 数组;第二次运行的 findings 不再包含已修复的 SQL 问题。

自测清单

  • 为什么 CI 中必须使用 -p?还应配合哪些参数避免卡住或失控?
  • --output-format json 和 --json-schema 各起什么作用?如何用于 PR 行内评论?
  • 应在 CLAUDE.md 中写哪些内容来提升 CI 测试生成和审查质量?
  • 新提交后重跑审查,如何避免重复评论?
  • 为什么独立的审查实例比生成代码的同一会话更适合做审查?

对应题目(11)

题目归类由 AI 判断,仅供参考。

练习这 11 道题