Claude Code + GitHub Actions — Tự động hóa CI/CD với AI
Điểm nổi bật
Nhấn để đến mục tương ứng
- 1 Claude trả về kết quả không nhất quán Triệu chứng: Cùng một diff, review lần 1 khác lần 2.
- 2 Để giảm thiểu: Viết prompt cụ thể, có cấu trúc rõ ràng Yêu cầu output theo format cố định (severity levels, sections) Tập trung vào phát hiện lỗi nghiêm trọng, không quá quan tâm style suggestions 4.
- 3 Bước tiếp theo Bạn đã có đủ workflow YAML để bắt đầu tích hợp Claude Code vào CI/CD pipeline.
- 4 Giải pháp: # Luôn dùng --max-turns 1 claude -p "..." --max-turns 1 --output-format text # Giới hạn kích thước diff gửi cho Claude head -2000 /tmp/pr-diff.txt > /tmp/pr-diff-truncated.txt # Tăng timeout nếu cần timeout-minutes: 15 2.
- 5 Rate limit từ Anthropic API Triệu chứng: Error 429 Too Many Requests.
Trong quy trình phát triển phần mềm hiện đại, CI/CD (Continuous Integration / Continuous Deployment) là xương sống giúp team ship code nhanh và ổn định. Nhưng phần lớn pipeline CI/CD hiện tại chỉ chạy linting, build và test đã viết sẵn — chúng không thực sự "hiểu" code. Claude Code thay đổi điều này: một AI agent có khả năng đọc diff, phân tích logic, phát hiện lỗi bảo mật, sinh test case và thậm chí đưa ra quyết định deploy — tất cả chạy tự động trong GitHub Actions.
Bài viết này hướng dẫn bạn xây dựng một CI/CD pipeline hoàn chỉnh tích hợp Claude Code, từ auto PR review đến deploy decision — kèm file workflow YAML sẵn sàng sử dụng.
Tại sao cần Claude Code trong CI/CD Pipeline?
Pipeline CI/CD truyền thống chỉ kiểm tra những gì bạn đã quy định trước: ESLint bắt lỗi cú pháp, unit test kiểm tra logic đã viết, build step đảm bảo code compile được. Nhưng chúng bỏ sót rất nhiều thứ quan trọng:
- Logic bugs: Code chạy đúng cú pháp nhưng sai logic nghiệp vụ — static analysis không bắt được
- Security vulnerabilities: SQL injection, XSS, hardcoded secrets — cần context để phát hiện
- Code quality: Naming kém, function quá dài, thiếu error handling — reviewer phải đọc thủ công
- Missing tests: Code mới thêm nhưng không có test đi kèm — dễ bị bỏ qua
- Deploy risk: Thay đổi lớn ảnh hưởng nhiều module — cần đánh giá impact trước khi deploy
Claude Code giải quyết tất cả vấn đề này vì nó đọc và hiểu code như một senior developer. Khi tích hợp vào GitHub Actions, mỗi PR sẽ được review tự động, mỗi commit mới sẽ được phân tích, và quyết định deploy được hỗ trợ bằng AI.
Kiến trúc tổng quan
Pipeline CI/CD với Claude Code gồm 3 tầng chính:
- PR Review Stage: Claude đọc diff, comment trực tiếp vào PR về quality, security, performance
- Test Generation Stage: Claude sinh test case cho code mới, chạy và báo cáo kết quả
- Deploy Decision Stage: Claude phân tích staging health, đánh giá risk level, quyết định có nên deploy production không
Mỗi tầng là một GitHub Actions workflow riêng biệt, có thể bật/tắt độc lập.
Thiết lập ban đầu
Yêu cầu
- Repository trên GitHub (public hoặc private)
- Anthropic API key với quyền truy cập Claude Code
- GitHub Actions đã bật cho repository
Cấu hình Secrets
Vào Settings > Secrets and variables > Actions của repository, thêm các secret sau:
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxx
Quan trọng: không bao giờ hardcode API key trong file workflow. Luôn sử dụng GitHub Secrets.
Stage 1: Auto PR Review với Claude Code
Đây là stage có ROI cao nhất — mỗi PR được review tự động trong vài phút, phát hiện vấn đề trước khi human reviewer đọc code.
Workflow file: .github/workflows/claude-pr-review.yml
name: Claude PR Review
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
jobs:
claude-review:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Get PR diff
id: diff
run: |
git diff origin/${{ github.base_ref }}...HEAD > /tmp/pr-diff.txt
echo "diff_size=$(wc -l < /tmp/pr-diff.txt)" >> $GITHUB_OUTPUT
- name: Claude Review
if: steps.diff.outputs.diff_size > 0
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude -p "You are a senior code reviewer. Analyze this PR diff and provide feedback in Vietnamese.
Focus on:
1. Bug risks and logic errors
2. Security vulnerabilities (SQL injection, XSS, hardcoded secrets)
3. Performance issues
4. Code quality (naming, structure, error handling)
5. Missing edge cases
Format output as markdown with severity levels: 🔴 Critical, 🟡 Warning, 🟢 Suggestion.
Be concise. Only flag real issues, not style preferences.
$(cat /tmp/pr-diff.txt)" --max-turns 1 --output-format text > /tmp/review-result.txt
- name: Post review comment
if: steps.diff.outputs.diff_size > 0
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const review = fs.readFileSync('/tmp/review-result.txt', 'utf8');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: '## 🤖 Claude Code Review\n\n' + review +
'\n\n---\n*Auto-reviewed by Claude Code*'
});
Cách hoạt động
- Khi PR được mở hoặc cập nhật, workflow tự động trigger
- Lấy diff giữa branch hiện tại và base branch
- Gửi diff cho Claude Code CLI với prompt review chuyên biệt
- Claude phân tích và trả về feedback có cấu trúc
- Kết quả được post dưới dạng comment trên PR
Stage 2: Tự động sinh test cho code mới
Code mới thêm mà không có test là nợ kỹ thuật. Claude Code có thể phân tích code mới trong PR và sinh test case phù hợp.
Workflow file: .github/workflows/claude-test-gen.yml
name: Claude Test Generator
on:
pull_request:
types: [opened, synchronize]
paths:
- 'src/**/*.ts'
- 'src/**/*.js'
- '!src/**/*.test.*'
- '!src/**/*.spec.*'
permissions:
contents: write
pull-requests: write
jobs:
generate-tests:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Find new/modified source files
id: changed
run: |
git diff --name-only --diff-filter=AM origin/${{ github.base_ref }}...HEAD -- 'src/**/*.ts' 'src/**/*.js' ':!src/**/*.test.*' ':!src/**/*.spec.*' > /tmp/changed-files.txt
echo "count=$(wc -l < /tmp/changed-files.txt)" >> $GITHUB_OUTPUT
- name: Generate tests with Claude
if: steps.changed.outputs.count > 0
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
while IFS= read -r file; do
test_file="${file%.ts}.test.ts"
if [ ! -f "$test_file" ]; then
echo "Generating tests for: $file"
claude -p "Read this source file and generate comprehensive unit tests.
Use the existing test framework in the project (check package.json).
Cover: happy path, edge cases, error handling.
Follow existing test patterns in the codebase.
Output ONLY the test file content, no explanation.
Source file: $(cat "$file")
Related imports and types context:
$(head -50 "$file")" --max-turns 1 --output-format text > "$test_file"
fi
done < /tmp/changed-files.txt
- name: Run generated tests
if: steps.changed.outputs.count > 0
run: |
npm test -- --passWithNoTests 2>&1 | tee /tmp/test-results.txt
echo "test_exit_code=${PIPESTATUS[0]}" >> $GITHUB_ENV
- name: Commit generated tests
if: steps.changed.outputs.count > 0 && env.test_exit_code == '0'
run: |
git config user.name "claude-code[bot]"
git config user.email "claude-code[bot]@users.noreply.github.com"
git add '*.test.ts' '*.test.js'
git diff --cached --quiet || git commit -m "test: auto-generate tests via Claude Code"
git push
Lưu ý quan trọng
-
Path filter: Workflow chỉ trigger khi có thay đổi trong
src/, bỏ qua file test - Kiểm tra trùng: Chỉ sinh test cho file chưa có test tương ứng
- Validation: Test sinh ra được chạy ngay — nếu fail thì không commit
- Auto-commit: Test pass sẽ tự commit vào PR branch, reviewer chỉ cần approve
Stage 3: Deploy Decision — Claude đánh giá trước khi lên production
Đây là stage quan trọng nhất và cũng cần cẩn thận nhất. Claude Code phân tích nhiều tín hiệu để đưa ra khuyến nghị deploy.
Workflow file: .github/workflows/claude-deploy-decision.yml
name: Claude Deploy Decision
on:
workflow_dispatch:
inputs:
environment:
description: 'Target environment'
required: true
default: 'production'
type: choice
options:
- staging
- production
permissions:
contents: read
deployments: write
issues: write
jobs:
deploy-analysis:
runs-on: ubuntu-latest
timeout-minutes: 10
environment: ${{ github.event.inputs.environment }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 50
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Gather deployment context
id: context
run: |
# Recent commits since last release tag
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD~20")
git log --oneline "$LAST_TAG"..HEAD > /tmp/commits.txt
# Changed files summary
git diff --stat "$LAST_TAG"..HEAD > /tmp/changes-stat.txt
# Check for migration files
find . -path "*/migrations/*" -newer "$LAST_TAG" -type f 2>/dev/null > /tmp/migrations.txt || true
- name: Staging health check
if: github.event.inputs.environment == 'production'
id: health
run: |
# Replace with your staging URL
STAGING_URL="${{ vars.STAGING_URL }}"
if [ -n "$STAGING_URL" ]; then
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$STAGING_URL/health" || echo "000")
echo "status_code=$HTTP_CODE" >> $GITHUB_OUTPUT
else
echo "status_code=skip" >> $GITHUB_OUTPUT
fi
- name: Claude Deploy Analysis
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude -p "You are a DevOps engineer evaluating a deployment to ${{ github.event.inputs.environment }}.
Analyze the following data and provide a deploy recommendation in Vietnamese.
## Commits since last release:
$(cat /tmp/commits.txt)
## Changed files:
$(cat /tmp/changes-stat.txt)
## Database migrations:
$(cat /tmp/migrations.txt)
## Staging health status: ${{ steps.health.outputs.status_code || 'N/A' }}
Provide:
1. RISK LEVEL: LOW / MEDIUM / HIGH / CRITICAL
2. Key changes summary (3-5 bullet points)
3. Potential risks and mitigation
4. Database migration warnings (if any)
5. RECOMMENDATION: PROCEED / HOLD / ABORT
6. If HOLD or ABORT, explain what needs to be done first
Be conservative — when in doubt, recommend HOLD." --max-turns 1 --output-format text > /tmp/deploy-decision.txt
- name: Post decision
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const decision = fs.readFileSync('/tmp/deploy-decision.txt', 'utf8');
const env = '${{ github.event.inputs.environment }}';
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `[Deploy ${env}] AI Analysis - ${new Date().toISOString().slice(0,10)}`,
body: '## 🚀 Deploy Decision Report\n\n' +
`**Environment:** ${env}\n` +
`**Triggered by:** @${context.actor}\n\n` +
decision +
'\n\n---\n*Analyzed by Claude Code*',
labels: ['deployment', env]
});
Cách sử dụng
Workflow này sử dụng workflow_dispatch — bạn trigger thủ công từ tab Actions trên GitHub khi chuẩn bị deploy. Claude sẽ:
- Thu thập tất cả commits kể từ release tag gần nhất
- Phân tích file thay đổi và đánh giá phạm vi ảnh hưởng
- Kiểm tra có migration mới không (rủi ro database)
- Ping staging health endpoint (nếu deploy production)
- Tổng hợp tất cả dữ liệu và đưa ra khuyến nghị PROCEED / HOLD / ABORT
Kiểm soát chi phí: Budget và Token Limits
Chạy Claude Code trong CI/CD có thể tốn kém nếu không kiểm soát. Dưới đây là các chiến lược quản lý chi phí hiệu quả.
Giới hạn token mỗi workflow run
# Trong mỗi step gọi Claude, thêm flag --max-turns
claude -p "..." --max-turns 1 --output-format text
# max-turns 1 đảm bảo Claude chỉ trả lời 1 lượt
# Không cho phép multi-turn conversation trong CI
Giới hạn kích thước diff
# Thêm step kiểm tra trước khi gọi Claude
- name: Check diff size
id: check_size
run: |
DIFF_LINES=$(wc -l < /tmp/pr-diff.txt)
if [ "$DIFF_LINES" -gt 2000 ]; then
echo "skip=true" >> $GITHUB_OUTPUT
echo "⚠️ Diff too large ($DIFF_LINES lines). Skipping AI review."
else
echo "skip=false" >> $GITHUB_OUTPUT
fi
# Sau đó dùng condition
- name: Claude Review
if: steps.check_size.outputs.skip != 'true'
...
Chỉ review file quan trọng
# Filter chỉ lấy file source code, bỏ generated files
git diff origin/main...HEAD -- '*.ts' '*.js' '*.py' '*.go' ':!*.min.js' ':!*.bundle.*' ':!package-lock.json' ':!yarn.lock' > /tmp/pr-diff.txt
Budget monitoring với labels
# Thêm label estimate cost vào PR
- name: Estimate cost
run: |
TOKENS=$(wc -w < /tmp/pr-diff.txt)
# Rough estimate: 1 word ≈ 1.3 tokens, input + output
EST_COST=$(echo "scale=4; $TOKENS * 1.3 * 2 * 0.000003" | bc)
echo "Estimated API cost: ~$$EST_COST"
Bảng ước tính chi phí
Với Claude Sonnet (giá tại thời điểm viết bài):
- PR Review nhỏ (100-500 dòng diff): ~$0.01-0.03 / review
- PR Review trung bình (500-1500 dòng): ~$0.03-0.08 / review
- Test generation (1 file): ~$0.02-0.05 / file
- Deploy decision: ~$0.01-0.03 / lần
- Team 5 devs, ~20 PR/tuần: ước tính ~$5-15/tháng
So với chi phí 1 bug lọt lên production hoặc thời gian review thủ công, đây là khoản đầu tư rất hợp lý.
Workflow nâng cao: Security Scan
Ngoài 3 stage chính, bạn có thể thêm workflow chuyên kiểm tra bảo mật:
name: Claude Security Scan
on:
pull_request:
paths:
- 'src/**'
- 'api/**'
- 'server/**'
jobs:
security-scan:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Security Analysis
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
git diff origin/${{ github.base_ref }}...HEAD -- '*.ts' '*.js' '*.py' > /tmp/code-diff.txt
claude -p "You are a security engineer. Analyze this code diff for vulnerabilities.
Check for:
- SQL/NoSQL injection
- XSS (Cross-Site Scripting)
- SSRF (Server-Side Request Forgery)
- Hardcoded secrets, API keys, passwords
- Insecure deserialization
- Path traversal
- Missing authentication/authorization checks
- Insecure cryptographic usage
- CSRF vulnerabilities
For each finding:
- Severity: CRITICAL / HIGH / MEDIUM / LOW
- File and line reference
- Description of the vulnerability
- Suggested fix with code example
If no security issues found, say so clearly.
Output in Vietnamese." --max-turns 1 --output-format text > /tmp/security-report.txt
- name: Post security report
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const report = fs.readFileSync('/tmp/security-report.txt', 'utf8');
const hasCritical = report.includes('CRITICAL');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: '## 🔒 Security Scan Report\n\n' + report +
'\n\n---\n*Scanned by Claude Code*'
});
if (hasCritical) {
core.setFailed('Critical security issues found!');
}
Khi phát hiện lỗ hổng mức CRITICAL, workflow sẽ fail và chặn merge PR — buộc developer phải sửa trước khi merge.
Troubleshooting: Các vấn đề thường gặp
1. Workflow timeout
Triệu chứng: Job chạy quá 10 phút rồi bị kill.
Nguyên nhân: Diff quá lớn hoặc Claude bị kẹt multi-turn.
Giải pháp:
# Luôn dùng --max-turns 1
claude -p "..." --max-turns 1 --output-format text
# Giới hạn kích thước diff gửi cho Claude
head -2000 /tmp/pr-diff.txt > /tmp/pr-diff-truncated.txt
# Tăng timeout nếu cần
timeout-minutes: 15
2. API key bị lộ trong logs
Triệu chứng: Key hiển thị trong workflow logs.
Giải pháp: Luôn dùng GitHub Secrets, không truyền qua command line argument:
# SAI - key có thể lộ trong process list
claude -p "..." --api-key sk-ant-xxx
# ĐÚNG - dùng environment variable
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
3. Claude trả về kết quả không nhất quán
Triệu chứng: Cùng một diff, review lần 1 khác lần 2.
Giải pháp: Đây là bản chất của LLM. Để giảm thiểu:
- Viết prompt cụ thể, có cấu trúc rõ ràng
- Yêu cầu output theo format cố định (severity levels, sections)
- Tập trung vào phát hiện lỗi nghiêm trọng, không quá quan tâm style suggestions
4. Rate limit từ Anthropic API
Triệu chứng: Error 429 Too Many Requests.
Giải pháp:
# Thêm concurrency limit trong workflow
concurrency:
group: claude-review-${{ github.ref }}
cancel-in-progress: true
# Đảm bảo chỉ 1 Claude review chạy tại một thời điểm cho mỗi branch
5. Permission denied khi post comment
Triệu chứng: Workflow thành công nhưng không post được comment lên PR.
Giải pháp: Kiểm tra phần permissions trong workflow file:
permissions:
contents: read
pull-requests: write # Cần quyền này để comment
issues: write # Cần nếu tạo issue
6. Diff chứa binary files hoặc quá nhiều noise
Giải pháp: Filter trước khi gửi cho Claude:
# Bỏ binary, lock files, generated code
git diff origin/main...HEAD --diff-filter=ACMR -- '*.ts' '*.js' '*.tsx' '*.jsx' '*.py' '*.go' ':!**/generated/**' ':!**/*.min.*' ':!*lock*' > /tmp/clean-diff.txt
Best practices khi vận hành
- Bắt đầu nhỏ: Chỉ bật PR review trước, sau 2-4 tuần mới thêm test gen và deploy decision
- Tune prompt liên tục: Review kết quả Claude hàng tuần, điều chỉnh prompt cho phù hợp với codebase
- Không thay thế human review: Claude Code là "first pass" — giúp reviewer tập trung vào kiến trúc và logic nghiệp vụ thay vì code style
- Monitor chi phí: Set up billing alert trên Anthropic Console, track usage theo team/repo
-
Tạo CLAUDE.md: Đặt file
CLAUDE.mdở root repo để hướng dẫn Claude Code về convention, architecture và tech stack của project — giúp review chính xác hơn - Version control workflow: Commit các workflow YAML vào repo, review thay đổi prompt như review code
- Fail-safe: Không bao giờ để Claude tự động deploy production mà không có human approval gate
Tổng hợp: Pipeline hoàn chỉnh
Sau khi thiết lập xong, quy trình CI/CD với Claude Code hoạt động như sau:
- Developer tạo PR → Claude tự động review code, post comment với phát hiện
- Developer push thêm commits → Claude re-review, sinh test cho code mới
- PR merged vào main → Build, test, deploy staging tự động
- Chuẩn bị deploy production → Trigger Claude Deploy Decision, nhận báo cáo risk assessment
- Team lead review báo cáo → Quyết định PROCEED hoặc HOLD dựa trên khuyến nghị AI + judgment
Toàn bộ quy trình này giúp team phát hiện bug sớm hơn, viết test đầy đủ hơn, và deploy tự tin hơn — trong khi giảm tải cognitive cho reviewer và tiết kiệm thời gian đáng kể.
Bước tiếp theo
Bạn đã có đủ workflow YAML để bắt đầu tích hợp Claude Code vào CI/CD pipeline. Hãy bắt đầu với PR Review workflow — đây là bước đơn giản nhất và mang lại giá trị nhanh nhất. Sau khi team quen thuộc, dần bổ sung thêm test generation và deploy decision.
Để tìm hiểu thêm các ứng dụng khác của Claude Code trong phát triển phần mềm, truy cập Thư viện Ứng dụng Claude.
Bai viet co huu ich khong?
Bản quyền thuộc về tác giả. Vui lòng dẫn nguồn khi chia sẻ.





