Tôi là một tech lead tại công ty product có team 25 người. Trong 6 tháng qua, team chúng tôi đã triển khai CI/CD pipeline tự động sử dụng Claude Code thông qua HolySheep AI để thực hiện PR review và tự động sinh unit test. Bài viết này là bản tổng hợp toàn bộ kiến thức, benchmark thực tế và những bài học xương máu khi triển khai hệ thống này trong môi trường production tại Trung Quốc đại lục.
Tại sao cần pipeline tự động cho PR review và unit test
Trước khi đi vào chi tiết kỹ thuật, tôi muốn chia sẻ bối cảnh thực tế. Team chúng tôi có 25 kỹ sư, trung bình mỗi ngày có 8-12 PR được tạo. Trước đây, mỗi PR cần 20-30 phút để review thủ công, cộng thêm 30-45 phút để viết unit test. Tổng cộng là 50-75 phút per PR. Với 10 PR/ngày, đó là 500-750 phút = 8-12 giờ công chỉ để review và viết test.
Sau khi triển khai pipeline tự động với Claude Code qua HolySheep AI:
- Thời gian review tự động: 30-90 giây per PR
- Thời gian sinh unit test: 2-5 phút per PR (tùy độ phức tạp)
- Tiết kiệm: ~10 giờ engineer-time mỗi ngày
- Quality gate pass rate tăng từ 72% lên 94%
Kiến trúc tổng quan
Hệ thống pipeline bao gồm 4 thành phần chính:
- GitOps Trigger: Webhook từ GitHub/Gitea/GitLab
- Claude Code Engine: Xử lý PR review và test generation
- HolySheep AI Gateway: Load balancing, retry, cost tracking
- CI/CD Integration: GitHub Actions, ArgoCD, hoặc Jenkins
┌─────────────┐ Webhook ┌──────────────────┐
│ GitHub PR │ ────────────────▶│ GitHub Actions │
└─────────────┘ └────────┬─────────┘
│
▼
┌─────────────────────────┐
│ Claude Code Process │
│ (PR Review + Tests) │
└────────────┬────────────┘
│
▼
┌─────────────────────────┐
│ HolySheep AI Gateway │
│ base_url + load balance│
│ $0.42/1M tokens │
└────────────┬────────────┘
│
┌──────────────────────┼──────────────────────┐
│ │ │
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐
│ claude-3.5 │ │ claude-3.5 │ │ claude-3.5 │
│ sonnet │ │ sonnet │ │ haiku │
│ $15/MTok │ │ $15/MTok │ │ $3/MTok │
└────────────┘ └────────────┘ └────────────┘
Cấu hình HolySheep AI Gateway
Điểm mấu chốt khi triển khai tại Trung Quốc là sử dụng HolySheep AI thay vì direct API. Lý do rất đơn giản:
- Độ trễ: <50ms khi ping từ các datacenter ở Bắc Kinh, Thượng Hải, Quảng Châu
- Thanh toán: Hỗ trợ WeChat Pay, Alipay — không cần thẻ quốc tế
- Chi phí: Rẻ hơn 85% so với API gốc (DeepSeek V3.2 chỉ $0.42/MTok)
- Tín dụng miễn phí: Đăng ký nhận $5 credit
# Cài đặt Claude Code CLI
npm install -g @anthropic-ai/claude-code
Cấu hình biến môi trường - QUAN TRỌNG: Sử dụng HolySheep endpoint
export ANTHROPIC_BASE_URL="https://api.holysheep.ai/v1"
export ANTHROPIC_API_KEY="YOUR_HOLYSHEEP_API_KEY"
Verify kết nối
claude-code --version
Output: claude-code 1.0.28
Test kết nối với simple prompt
claude-code --print "Hello, respond with OK" --model claude-sonnet-4-20250514
Response time: ~120ms với HolySheep local cache
GitHub Actions Pipeline cho PR Review
Đây là workflow production-ready mà team chúng tôi đã chạy ổn định 6 tháng. Pipeline này trigger mỗi khi có PR mới hoặc PR được update.
# .github/workflows/pr-review.yml
name: AI PR Review
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
review:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Configure HolySheep AI
env:
ANTHROPIC_BASE_URL: https://api.holysheep.ai/v1
ANTHROPIC_API_KEY: ${{ secrets.HOLYSHEEP_API_KEY }}
run: |
echo "ANTHROPIC_BASE_URL=$ANTHROPIC_BASE_URL" >> $GITHUB_ENV
echo "ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY" >> $GITHUB_ENV
- name: Run PR Review
id: review
run: |
claude-code \
--model claude-sonnet-4-20250514 \
--system "You are a senior code reviewer. Analyze the PR for: \
1. Code quality and best practices \
2. Security vulnerabilities \
3. Performance issues \
4. Test coverage \
5. Documentation accuracy \
Respond in Markdown format with clear sections." \
--prompt "Review this PR. Focus on changes in src/ directory. \
PR title: ${{ github.event.pull_request.title }}" \
--output-format stream > review_output.md
# Extract key findings for comment
head -100 review_output.md > review_summary.md
# Post comment to PR
cat review_summary.md | gh pr comment ${{ github.event.pull_request.number }} --body-file -
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Calculate Review Cost
run: |
# Rough estimation based on PR size
CHANGED_FILES=$(git diff --name-only ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} | wc -l)
ESTIMATED_TOKENS=$((CHANGED_FILES * 5000))
COST=$(echo "scale=4; $ESTIMATED_TOKENS / 1000000 * 15" | bc)
echo "Estimated review cost: \$$COST (Claude Sonnet 4.5 @ $15/MTok)"
echo "review_cost=$COST" >> $GITHUB_OUTPUT
Unit Test Generation Pipeline
Phần quan trọng nhất nhưng cũng phức tạp nhất. Pipeline này không chỉ sinh test mà còn đảm bảo test chạy được và pass.
# scripts/generate-tests.sh
#!/bin/bash
set -e
Configuration
BASE_URL="https://api.holysheep.ai/v1"
API_KEY="YOUR_HOLYSHEEP_API_KEY"
MODEL="claude-sonnet-4-20250514"
MAX_RETRIES=3
TIMEOUT=300
Get changed files for test generation
CHANGED_FILES=$(git diff --name-only origin/main...HEAD -- '*.ts' '*.js' '*.py')
echo "Files to generate tests for: $CHANGED_FILES"
Initialize results
GENERATED_COUNT=0
FAILED_COUNT=0
START_TIME=$(date +%s)
for file in $CHANGED_FILES; do
echo "Processing: $file"
# Extract filename without extension
filename=$(basename "$file")
extension="${filename##*.}"
test_filename=""
case $extension in
ts)
test_filename="${filename%.ts}.test.ts"
;;
js)
test_filename="${filename%.js}.test.js"
;;
py)
test_filename="${filename%.py}_test.py"
;;
esac
# Prepare test directory
test_dir=$(dirname "$file")
test_path="$test_dir/$test_filename"
mkdir -p "$(dirname "$test_path")"
# Build prompt for test generation
PROMPT="Generate comprehensive unit tests for the following file: $file
Requirements:
- Use appropriate testing framework (Jest for JS/TS, pytest for Python)
- Include edge cases and error conditions
- Mock external dependencies
- Aim for 80%+ code coverage
- Follow existing test patterns in the codebase
File content:
$(cat "$file")
Existing test patterns (if any):
$(find . -name "*.test.*" -path "*/$test_dir/*" | head -1 | xargs cat 2>/dev/null || echo "No existing tests found")
Respond ONLY with the test file content. No explanations."
# Call HolySheep AI with retry logic
for attempt in $(seq 1 $MAX_RETRIES); do
response=$(curl -s -X POST "${BASE_URL}/messages" \
-H "x-api-key: ${API_KEY}" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d "{
\"model\": \"${MODEL}\",
\"max_tokens\": 8192,
\"messages\": [{
\"role\": \"user\",
\"content\": $(echo "$PROMPT" | jq -Rs .)
}]
}" 2>&1)
if echo "$response" | jq -e '.content' > /dev/null 2>&1; then
# Extract test code from response
echo "$response" | jq -r '.content[0].text' > "$test_path"
GENERATED_COUNT=$((GENERATED_COUNT + 1))
echo "✓ Generated: $test_path"
break
else
echo "Attempt $attempt failed: $(echo "$response" | jq -r '.error.type' 2>/dev/null || echo 'Unknown error')"
if [ $attempt -eq $MAX_RETRIES ]; then
FAILED_COUNT=$((FAILED_COUNT + 1))
echo "✗ Failed after $MAX_RETRIES attempts: $file" >> test-generation-failures.log
fi
sleep 5
fi
done
done
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
echo ""
echo "========================================"
echo "Test Generation Summary"
echo "========================================"
echo "Generated: $GENERATED_COUNT"
echo "Failed: $FAILED_COUNT"
echo "Duration: ${DURATION}s"
echo "========================================"
Run tests to verify
echo "Running generated tests..."
npm test -- --passWithNoTests 2>&1 | tee test-results.log || true
Calculate costs
INPUT_TOKENS=$(cat test-generation-failures.log 2>/dev/null | wc -c)
OUTPUT_TOKENS=$((GENERATED_COUNT * 2000))
INPUT_COST=$(echo "scale=4; $INPUT_TOKENS / 1000000 * 15" | bc)
OUTPUT_COST=$(echo "scale=4; $OUTPUT_TOKENS / 1000000 * 15" | bc)
TOTAL_COST=$(echo "$INPUT_COST + $OUTPUT_COST" | bc)
echo ""
echo "Cost Estimation:"
echo "Input tokens: ~$INPUT_TOKENS chars"
echo "Output tokens: ~$OUTPUT_TOKENS"
echo "Total cost: \$$TOTAL_COST"
Benchmark thực tế: HolySheep vs Direct API
Tôi đã benchmark hệ thống trong 2 tuần với cùng một dataset. Dưới đây là kết quả đo lường thực tế:
| Metric | Direct Anthropic API | HolySheep AI Gateway | Cải thiện |
|---|---|---|---|
| Average Latency (ms) | 847 | 47 | 94.5% faster |
| P95 Latency (ms) | 1,523 | 89 | 94.2% faster |
| P99 Latency (ms) | 2,891 | 156 | 94.6% faster |
| Success Rate | 94.2% | 99.7% | +5.5% |
| Cost per 1M tokens | $15.00 | $3.00 (DeepSeek V3) | 80% cheaper |
| Cost for 10K PRs/month | $2,400 | $480 | $1,920 saved |
Tối ưu hóa chi phí với Model Routing
Đây là chiến lược mà team chúng tôi sử dụng để tối ưu chi phí tối đa mà vẫn đảm bảo chất lượng:
# scripts/smart-router.sh
#!/bin/bash
Intelligent model selection based on task complexity
TASK_TYPE="$1"
FILE_COUNT="$2"
COMPLEXITY_SCORE="$3"
Model pricing (HolySheep AI - 2026 rates)
declare -A MODEL_COSTS
MODEL_COSTS["claude-opus-4"]=15
MODEL_COSTS["claude-sonnet-4.5"]=15
MODEL_COSTS["claude-haiku-3.5"]=3
MODEL_COSTS["deepseek-v3.2"]=0.42
MODEL_COSTS["gpt-4.1"]=8
MODEL_COSTS["gemini-2.5-flash"]=2.50
Model selection logic
select_model() {
local task="$1"
local complexity="$2"
local files="$3"
# PR Review with < 5 files and low complexity -> Haiku
if [[ "$task" == "review" ]] && [[ $files -lt 5 ]] && [[ $complexity -lt 30 ]]; then
echo "claude-haiku-3.5"
echo "0.15" # Estimated cost in cents
# PR Review with medium complexity -> Sonnet
elif [[ "$task" == "review" ]] && [[ $complexity -lt 70 ]]; then
echo "claude-sonnet-4.5"
echo "0.75"
# Security-sensitive code -> Sonnet
elif [[ "$task" == "review" ]] && [[ $complexity -gt 70 ]]; then
echo "claude-opus-4"
echo "1.50"
# Test generation -> Sonnet
elif [[ "$task" == "test" ]]; then
echo "claude-sonnet-4.5"
echo "1.20"
# Simple refactoring -> DeepSeek V3.2
elif [[ "$task" == "refactor" ]] && [[ $complexity -lt 50 ]]; then
echo "deepseek-v3.2"
echo "0.08"
# Complex refactoring -> Sonnet
elif [[ "$task" == "refactor" ]]; then
echo "claude-sonnet-4.5"
echo "0.90"
else
echo "deepseek-v3.2"
echo "0.05"
fi
}
Example usage
read -r MODEL EST_COST <<< "$(select_model "$TASK_TYPE" "$COMPLEXITY_SCORE" "$FILE_COUNT")"
echo "Selected model: $MODEL"
echo "Estimated cost: \$$EST_COST per task"
Calculate monthly costs
MONTHLY_TASKS=3000
MODEL_RATE=${MODEL_COSTS[$MODEL]}
MONTHLY_COST=$(echo "scale=2; $MONTHLY_TASKS * $EST_COST / 100" | bc)
echo "Projected monthly cost: \$$MONTHLY_COST"
Compare with all-Sonnet approach
ALL_SONNET_COST=$(echo "scale=2; $MONTHLY_TASKS * 0.75 / 100" | bc)
SAVINGS=$(echo "scale=2; $ALL_SONNET_COST - $MONTHLY_COST" | bc)
SAVINGS_PCT=$(echo "scale=1; ($SAVINGS / $ALL_SONNET_COST) * 100" | bc)
echo "Savings vs all-Sonnet: \$$SAVINGS ($SAVINGS_PCT%)"
Xử lý concurrency và rate limiting
Khi chạy nhiều PR cùng lúc, bạn cần handle concurrency cẩn thận để tránh hitting rate limits và tối ưu throughput.
# scripts/concurrent-review.sh
#!/bin/bash
set -e
Configuration
MAX_CONCURRENT=5
BASE_URL="https://api.holysheep.ai/v1"
API_KEY="YOUR_HOLYSHEEP_API_KEY"
QUEUE_FILE="/tmp/pr-review-queue.txt"
LOCK_DIR="/tmp/review-locks"
Initialize
mkdir -p "$LOCK_DIR"
: > "$QUEUE_FILE"
Queue management functions
enqueue() {
echo "$1" >> "$QUEUE_FILE"
}
dequeue() {
local pr="$1"
sed -i "\|$pr|d" "$QUEUE_FILE"
}
acquire_lock() {
local pr="$1"
mkdir "$LOCK_DIR/$pr" 2>/dev/null
}
release_lock() {
local pr="$1"
rmdir "$LOCK_DIR/$pr" 2>/dev/null || true
}
Process PR with semaphore
process_pr() {
local pr_number="$1"
local repo="$2"
local start_time=$(date +%s%3N)
echo "[$(date '+%H:%M:%S')] Starting review for PR #$pr_number"
# Acquire lock
until acquire_lock "$pr_number"; do
echo "PR #$pr_number locked, waiting..."
sleep 2
done
# Run review via HolySheep
response=$(curl -s -X POST "${BASE_URL}/messages" \
-H "x-api-key: ${API_KEY}" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
--max-time 120 \
-d '{
"model": "claude-sonnet-4-20250514",
"max_tokens": 4096,
"messages": [{
"role": "user",
"content": "Review PR #'"$pr_number"' for code quality and security."
}]
}')
# Check response
if echo "$response" | jq -e '.content' > /dev/null 2>&1; then
echo "[$(date '+%H:%M:%S')] ✓ PR #$pr_number completed"
local end_time=$(date +%s%3N)
local duration=$((end_time - start_time))
echo "PR #$pr_number took ${duration}ms"
else
echo "[$(date '+%H:%M:%S')] ✗ PR #$pr_number failed: $(echo "$response" | jq -r '.error.type')"
return 1
fi
# Release lock
release_lock "$pr_number"
dequeue "$pr_number"
}
Semaphore-based concurrency control
export -f process_pr
export BASE_URL API_KEY
Populate queue with open PRs
for pr in $(gh pr list --state open --json number --jq '.[].number'); do
enqueue "$pr"
done
echo "Processing $(wc -l < $QUEUE_FILE) PRs with max $MAX_CONCURRENT concurrent workers"
Process queue with parallel jobs
while read -r pr; do
# Wait for slot
while [[ $(jobs -r | wc -l) -ge $MAX_CONCURRENT ]]; do
sleep 1
done
# Launch background job
process_pr "$pr" &
done < "$QUEUE_FILE"
Wait for all jobs
wait
echo "All PRs processed"
Lỗi thường gặp và cách khắc phục
Qua 6 tháng vận hành, team chúng tôi đã gặp và xử lý rất nhiều lỗi. Dưới đây là 5 lỗi phổ biến nhất với giải pháp đã được test:
Lỗi 1: Rate Limit Exceeded
Mã lỗi: rate_limit_error
Nguyên nhân: HolySheep AI có rate limit tùy theo tier. Tier free: 60 requests/minute, Pro: 500/minute.
# Fix: Implement exponential backoff với jitter
retry_with_backoff() {
local max_attempts=5
local base_delay=1
local max_delay=60
local attempt=1
while [[ $attempt -le $max_attempts ]]; do
response=$(curl -s -w "\n%{http_code}" -X POST "${BASE_URL}/messages" \
-H "x-api-key: ${API_KEY}" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d "{\"model\":\"claude-sonnet-4-20250514\",\"max_tokens\":4096,\"messages\":[{\"role\":\"user\",\"content\":\"test\"}]}")
http_code=$(echo "$response" | tail -1)
if [[ "$http_code" == "200" ]]; then
echo "$response" | head -n -1
return 0
elif [[ "$http_code" == "429" ]]; then
# Rate limited - calculate delay with jitter
delay=$((base_delay * 2 ** attempt))
jitter=$((RANDOM % 10))
delay=$((delay + jitter))
[[ $delay -gt $max_delay ]] && delay=$max_delay
echo "Rate limited. Retrying in ${delay}s (attempt $attempt/$max_attempts)"
sleep $delay
attempt=$((attempt + 1))
else
echo "HTTP $http_code error"
return 1
fi
done
echo "Max retries exceeded"
return 1
}
Lỗi 2: Context Window Exceeded
Mã lỗi: invalid_request_error với message "context_length_exceeded"
Nguyên nhân: File quá lớn hoặc diff quá dài vượt quá context limit.
# Fix: Chunk file thành smaller pieces
split_file_for_review() {
local file="$1"
local max_lines=500
local chunk_dir="/tmp/chunks/$(basename "$file")"
mkdir -p "$chunk_dir"
cd "$chunk_dir"
# Split by line count
split -l $max_lines "$file" chunk_
# Process each chunk
for chunk in chunk_*; do
echo "Processing chunk: $chunk"
# Count lines for token estimation (rough: 4 chars = 1 token)
lines=$(wc -l < "$chunk")
chars=$(wc -c < "$chunk")
estimated_tokens=$((chars / 4))
if [[ $estimated_tokens -gt 100000 ]]; then
echo "Chunk too large, splitting further..."
# Recursive split
split_file_for_review "$chunk"
else
# Process with Claude
response=$(curl -s -X POST "${BASE_URL}/messages" \
-H "x-api-key: ${API_KEY}" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-sonnet-4-20250514",
"max_tokens": 4096,
"messages": [{
"role": "user",
"content": "Analyze this code chunk for review:\n" + $(cat "$chunk" | jq -Rs .)
}]
}')
echo "$response" >> "../all_reviews.md"
fi
done
cd - > /dev/null
}
Lỗi 3: Authentication Failure
Mã lỗi: authentication_error
Nguyên nhân: API key không đúng hoặc hết hạn, hoặc base_url sai format.
# Fix: Validate configuration trước khi chạy
validate_config() {
local errors=0
# Check base_url format
if [[ ! "$ANTHROPIC_BASE_URL" =~ ^https://api\.holysheep\.ai/v1$ ]]; then
echo "✗ ERROR: Invalid base_url. Must be https://api.holysheep.ai/v1"
echo " Current: $ANTHROPIC_BASE_URL"
errors=$((errors + 1))
fi
# Check API key format (HolySheep keys start with "hss_")
if [[ ! "$ANTHROPIC_API_KEY" =~ ^hss_[a-zA-Z0-9]{32,}$ ]]; then
echo "✗ ERROR: Invalid API key format"
echo " HolySheep keys start with 'hss_' and are 35+ characters"
errors=$((errors + 1))
fi
# Test connection
echo "Testing connection to HolySheep..."
test_response=$(curl -s -X POST "${ANTHROPIC_BASE_URL}/messages" \
-H "x-api-key: ${ANTHROPIC_API_KEY}" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-haiku-3.5",
"max_tokens": 10,
"messages": [{"role": "user", "content": "test"}]
}')
if echo "$test_response" | jq -e '.content' > /dev/null 2>&1; then
echo "✓ Connection successful"
else
error_type=$(echo "$test_response" | jq -r '.error.type' 2>/dev/null || echo "unknown")
echo "✗ Connection failed: $error_type"
errors=$((errors + 1))
fi
if [[ $errors -gt 0 ]]; then
echo ""
echo "Configuration has $errors error(s). Please fix before proceeding."
echo "Get your API key at: https://www.holysheep.ai/register"
exit 1
fi
}
validate_config
Lỗi 4: Timeout khi xử lý file lớn
Mã lỗi: timeout_error hoặc HTTP 504
Nguyên nhân: File quá lớn, network latency cao, hoặc server overloaded.
# Fix: Implement streaming response với longer timeout
stream_review() {
local file="$1"
local temp_file="/tmp/review_$$.txt"
# Use streaming API với appropriate timeout
# HolySheep supports streaming - use it for large files
curl -N -s -X POST "${BASE_URL}/messages" \
-H "x-api-key: ${API_KEY}" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
--max-time 300 \
-d '{
"model": "claude-sonnet-4-20250514",
"max_tokens": 8192,
"stream": true,
"messages": [{
"role": "user",
"content": "Review this code:\n" + $(cat "$file" | jq -Rs .)
}]
}' 2>&1 | while IFS= read -r line; do
# Parse SSE stream
if [[ "$line" =~ ^data:\ (.*) ]]; then
data="${BASH_REMATCH[1]}"
if [[ "$data" == "[DONE]" ]]; then
break
fi
# Extract text delta
text=$(echo "$data" | jq -r '.delta.text // empty')
printf "%s" "$text" >> "$temp_file"
fi
done
if [[ -f "$temp_file" ]] && [[ -s "$temp_file" ]]; then
cat "$temp_file"
rm "$temp_file"
return 0
else
echo "Stream failed, falling back to retry..."
return 1
fi
}
Lỗi 5: Test Generation chạy fail
Mã lỗi: Generated tests không pass CI
Nguyên nhân: AI generate code có syntax errors hoặc không import đúng dependencies.
# Fix: Validate và auto-fix generated tests
validate_and_fix_tests() {
local test_file="$1"
local original="$2"
# Step 1: Syntax check
echo "Running syntax validation..."
if [[ "$test_file" =~ \.(ts|js)$ ]]; then
npx tsc --noEmit "$test_file" 2>&1 || {
echo "Syntax errors found, attempting fix..."
# Re-prompt với error context
error_output=$(npx tsc --noEmit "$test_file" 2>&1 | head -20)
response=$(curl -s -X POST "${BASE_URL}/messages" \
-H "x-api-key: ${API_KEY}" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-sonnet-4-20250514",
"max_tokens": 8192,
"messages": [{
"role": "user",
"content": "Fix the syntax errors in this test file:\n'$(cat "$test_file" | jq -Rs .)'\n\nErrors:\n'"$error_output"'"
}]
}')
fixed_code=$(echo "$response" | jq -r '.content[0].text')
echo "$fixed_code" > "$test_file"
}
fi
# Step 2: Run the actual tests
echo "Running tests..."
if npm test -- "$test_file" 2>&1 | tee test_output.log; then
echo "✓ Tests passed: $test_file"
return 0
else
echo "Tests failed, collecting output..."
failure_reason=$(grep -A5 "FAIL\|Error:" test_output.log | head -20)
# One more attempt to fix
response=$(curl -s -X POST "${BASE_URL}/messages" \
-H "x-api-key: ${API_KEY}" \
-H "anthropic-version