Đến nội dung chính
Tools & MCP

Claude Code trong CI/CD: review pull request tự động với -p

Chạy Claude Code headless trong CI bằng claude -p, lấy finding dạng JSON để comment lên PR, giảm false positive và chọn API đồng bộ hay Message Batches.

Đội ngũ CertGrove · 7 phút đọc

Một bot review làm treo pipeline, đăng lại cùng một comment năm lần, hoặc bắt bẻ từng lỗi style nhỏ thì chỉ sau một tuần là bị tắt. Scenario 5 của đề CCAR-F xoay quanh đúng những lỗi đó. Bài này chỉ cách chạy Claude Code ở chế độ headless trong CI, lấy kết quả dạng JSON để đăng thành inline comment trên PR, và chọn đúng API cho từng loại job.

Chạy Claude Code trong CI/CD bằng `claude -p`

Lệnh claude "Review this PR" mở một phiên tương tác. Trên CI runner không có ai trả lời, nên job đứng chờ mãi. Cách sửa là cờ -p (hoặc --print): Claude Code xử lý prompt, in kết quả ra stdout rồi thoát với exit code mà script kiểm tra được.

gh pr diff "$PR_NUMBER" | claude -p "Review this diff for bugs and security issues" \
  --allowedTools "Read,Grep,Glob"

Đáp án nhiễu trong đề hay bịa ra thứ không tồn tại: biến môi trường CLAUDE_HEADLESS, cờ --batch, hoặc redirect stdin từ /dev/null. Cách được tài liệu hóa là -p.

Thêm hai cờ hay dùng: --allowedTools cấp sẵn quyền cho các tool cần thiết vì không có ai bấm "allow", và --max-turns giới hạn độ dài một lần chạy.

Kết quả máy đọc được với `--output-format json` và `--json-schema`

Text tự do đủ cho người đọc log. Nhưng muốn đăng inline comment, script cần file, số dòng và nội dung của từng finding. Task statement 3.6 nêu hai cờ:

  • --output-format json bọc response trong JSON, text nằm ở trường result, kèm session ID, usage và chi phí.
  • --json-schema truyền vào một JSON Schema. Output phải khớp schema và nằm ở trường structured_output.
claude -p "Review the changes on this branch against CLAUDE.md review criteria" \
  --allowedTools "Read,Grep,Glob,Bash(git diff *)" \
  --output-format json \
  --json-schema "$(cat .github/review-schema.json)" \
  | jq '.structured_output.findings' > findings.json

Schema chỉ cần mỗi finding có file, line, severity (ví dụ bug, security, performance) và message. Bước sau duyệt findings.json và gọi GitHub API để đăng từng comment.

Phiên bản GitHub Actions

Anthropic có action chính thức anthropics/claude-code-action@v1. Ở automation mode bạn truyền prompt, còn claude_args nhận mọi cờ CLI:

name: Claude PR review
on:
  pull_request:
    types: [opened, synchronize]
jobs:
  review:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write
      id-token: write
    steps:
      - uses: actions/checkout@v6
      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          prompt: "Review PR #${{ github.event.pull_request.number }} using the criteria in CLAUDE.md"
          claude_args: "--max-turns 10"

Đề thi hỏi về cờ CLI chứ không hỏi input của action, nên học -p, --output-format json, --json-schema trước. Hiện Anthropic còn có tính năng Code Review được quản lý sẵn, chạy trên mọi PR mà không cần file workflow. Tính năng này ra sau exam guide và không phải thứ Scenario 5 hỏi tới.

Cung cấp context cho reviewer trong CI và giữ nó độc lập

CLAUDE.md là context của CI. Lần chạy claude -p load CLAUDE.md của repo giống như phiên tương tác. Đặt tiêu chí review, chuẩn viết test và các fixture có sẵn ở đó, pipeline nào cũng dùng được. Lưu ý theo tài liệu hiện tại: cờ --bare (khuyến nghị cho script cần kết quả ổn định) bỏ qua CLAUDE.md. Nếu dùng nó, hãy truyền tiêu chí bằng --append-system-prompt-file. Xem thêm thứ bậc CLAUDE.md.

Review lại chỉ báo cái mới. Khi developer push bản sửa, lần review mới không nhớ gì về lần trước và sẽ lặp lại toàn bộ. Hãy đưa các finding cũ vào prompt và yêu cầu Claude chỉ báo vấn đề mới hoặc chưa được xử lý. Với sinh test cũng vậy: đưa các file test hiện có vào context để Claude không đề xuất lại kịch bản đã có.

Dùng reviewer độc lập. Phiên đã viết code vẫn giữ lập luận của chính nó nên dễ đồng tình với quyết định cũ. Task statement 4.6 nói rõ: một instance thứ hai không có context của bên sinh code bắt lỗi tốt hơn câu lệnh "hãy tự review lại" hay extended thinking trong cùng phiên.

Chia PR lớn thành nhiều lượt. Một lượt cho 14 file sẽ cho độ sâu không đều và nhận xét mâu thuẫn nhau. Chạy một lượt riêng cho từng file để bắt lỗi cục bộ, rồi một lượt integration xem luồng dữ liệu giữa các file. Context window lớn hơn không chữa được việc chú ý bị dàn mỏng.

Giảm false positive bằng tiêu chí rõ ràng

Bot sai một nửa số lần thì developer sẽ bỏ qua, và một nhóm lỗi nhiều nhiễu kéo theo mất niềm tin vào cả nhóm chính xác. Câu "hãy thận trọng" hay "chỉ báo khi chắc chắn" không giúp mấy. Quy tắc theo loại cụ thể thì có:

  • Báo: lỗi logic, lỗi bảo mật, comment mô tả sai hành vi thật của code.
  • Bỏ qua: style nhỏ, sở thích đặt tên, pattern giống code xung quanh.

Mỗi mức severity nên có ví dụ code cụ thể để phân loại nhất quán. Nếu một nhóm cứ sinh nhiễu, tạm tắt nó trong lúc sửa prompt.

API đồng bộ hay Message Batches API

Có job chặn merge, có job đợi đến sáng được. Chọn API theo yêu cầu độ trễ:

WorkloadAPILý do
Check trước merge, developer đang chờMessages API đồng bộ (hoặc claude -p)Cần kết quả ngay
Sinh test hằng đêm, audit hằng tuần, báo cáo tech debtMessage Batches APIRẻ hơn 50%, chịu được độ trễ

Batches API xử lý trong tối đa 24 giờ, không cam kết độ trễ. Mỗi request có custom_id để ghép kết quả với input và chỉ gửi lại những request lỗi. Nó cũng không hỗ trợ gọi tool nhiều lượt trong một request, nên việc agentic cần kết quả tool giữa chừng phải dùng API đồng bộ.

Thử sức

Bot review trong CI chạy mỗi lần push lên PR. Sau khi developer push bản sửa, bot đăng lại cả tám comment cũ, kể cả ba lỗi đã sửa. Bạn nên đổi gì?

A. Thêm --max-turns 1 để review dừng trước khi lặp lại. B. Đưa finding của lần chạy trước vào prompt và yêu cầu Claude chỉ báo vấn đề mới hoặc chưa được xử lý. C. Chạy review trong cùng phiên đã sinh code để nó nhớ các comment cũ. D. Chuyển lần review lại sang Message Batches API để kết quả được khử trùng lặp theo custom_id.

Đáp án: B. Lần chạy mới không biết gì về comment cũ, nên bạn phải đưa finding trước đó vào và nói rõ cần báo gì.

  • A giới hạn số lượt, không giải quyết trùng lặp. Review một lượt vẫn có thể lặp đủ tám comment.
  • C tái dùng context của bên sinh code, làm review kém đi, và CI vốn không mang bộ nhớ giữa các lần push.
  • D nhầm giữa ghép cặp và khử trùng lặp. custom_id chỉ ghép response với request, không biết gì về review cũ.

Điểm chính cần nhớ

  • -p (--print) là cách chính thức để chạy Claude Code không tương tác. Thiếu nó, CI bị treo.
  • --output-format json cùng --json-schema cho finding parse được trong structured_output, sẵn sàng làm inline comment.
  • CLAUDE.md mang tiêu chí review vào CI. Finding cũ mang trạng thái giữa các lần review lại.
  • Review bằng instance độc lập, chia PR lớn thành lượt theo file cộng một lượt integration.
  • Đồng bộ cho check chặn merge, Message Batches (50% chi phí, tối đa 24h, custom_id) cho job ban đêm.

Câu hỏi thường gặp

Đội ngũ CertGroveViết ghi chú ôn thi song ngữ cho developer Việt Nam chuẩn bị Claude Certified Architect — Foundations.