Claude ile GitHub Action’ınız mükemmel çalışıyor — ta ki inceleme ortasında bir hız limiti devreye girene, adım başarısız olana ve tüm pipeline geliştiriciler 20 dakika beklerken bloke olana kadar. Claude’u CI’da çalıştırmak, etkileşimli modda görmediğiniz başarısızlıkları planlamak demektir.
Claude Code, otomatik kod incelemesi, test üretimi, dokümantasyon ve daha fazlası için CI/CD pipeline’larında etkileşimsiz olarak çalışır. Resmi GitHub Action anahtar teslim entegrasyon sağlarken, CLI’ın --print modu açık maliyet tavanları ve yeniden deneme mantığı ile özel pipeline iş akışlarını mümkün kılar.
Bu kapsamlı bir referans bölümüdür. Sadece CI’ı çalıştırmak istiyorsanız, aşağıdaki GitHub Action bölümüyle başlayın — 5 dakikadan kısa sürede CI’da kod incelemesi yapabilirsiniz. Yeniden deneme kalıplarına ve dayanıklılık pipeline’larına ihtiyaç duyduğunuzda geri gelin.
Buradaki kalıplar, yerel geliştirmede ortaya çıkmayan üç başarısızlık modunu ele almaktan doğmuştur: hız limitleri, model aşırı yüklenmesi ve pipeline ortasında bütçe tükenmesi.
GitHub Action
anthropics/claude-code-action@v1 action’ı, CLI’ı mantıklı CI varsayılanlarıyla sarar. PR veya issue olayı üzerinde çalışıp çalışmadığını otomatik algılar, diff bağlamını enjekte eder ve Claude’un yanıtını yorum olarak gönderir.
Action, checkout, bağlam enjeksiyonu ve yorum göndermeyi otomatik olarak halleder. Siz bir istem, API anahtarınızı ve isteğe bağlı bir bütçe tavanı sağlarsınız. Daha fazla kontrol için, CLI’ı doğrudan yükleyip kendiniz çalıştırabilirsiniz.
CI Bayrakları
Her CI çağrısı, etkileşimsiz bir ortamda güvenli çalışmak için belirli bir bayrak setine ihtiyaç duyar. İşte dökümü.
Temel CI Bayrakları
| Bayrak | Amacı | CI’da Neden Önemli |
|---|---|---|
-p / —print | Başsız mod | Gerekli — CI’da etkileşimli arayüz yok |
—output-format json | Makine tarafından ayrıştırılabilir çıktı | Maliyet, oturum kimliği ve sonucu jq ile çıkarmanızı sağlar |
—max-budget-usd N | Çağrı başına maliyet tavanı | Aşırı harcamayı önler — aynı istem için maliyetler 10 kat değişebilir |
—no-session-persistence | Oturumu diske kaydetme | Geçici CI çalıştırıcılarını temiz tutar — artık oturum dosyası kalmaz |
—permission-mode bypassPermissions | Etkileşimli istem yok | Bu olmadan, CLI TTY girdisi bekleyerek takılır ve sonunda zaman aşımına uğrar |
—strict-mcp-config | Herhangi bir MCP sunucu bağlanamazsa başarısız ol | CI için önemli: Olmadan, MCP yapılandırma hataları sessizce görmezden gelinir — pipeline’ınız bağlı olmadığı halde her şeyin bağlı olduğunu düşünür |
—fallback-model MODEL | Aşırı yüklenmede alternatif model kullan | Yalnızca HTTP 429 (hız sınırlama) durumunda tetiklenir, diğer hatalar için değil. Genel hata kurtarma olarak güvenmeyin |
—from-pr URL | PR’a bağlı oturumu devam ettir | Ortamda GITHUB_TOKEN gerektirir |
Minimum uygulanabilir CI çağrısı bu bayraklardan dördünü birleştirir:
claude -p "Review this code for bugs" \ --output-format json \ --max-budget-usd 0.50 \ --no-session-persistence \ --permission-mode bypassPermissionsBir CI komutuna bütçe koruması ekleyin ve ne olduğunu görün:
claude -p “Review this PR for security issues” —max-budget-usd 0.50 —output-format json | jq ‘{subtype, cost: .total_cost_usd}’
İnceleme bütçe dahilinde tamamlandı mı? subtype “error_max_budget_usd” olarak dönse betiğiniz ne yapardı? Üretimde olmadan önce şimdi bu durumu planlayın.
Özel Pipeline’lar
GitHub Actions’ın ötesinde, Claude’u herhangi bir CI sistemine — GitLab CI, Jenkins, CircleCI veya düz bir bash betiği — gömebilirsiniz. Kalıp her yerde aynıdır: JSON çıktısını yakala, jq ile ayrıştır ve sonuca göre hareket et.
Maliyet Tavanlı PR İncelemesi:
claude -p "Review the changes in this PR" \ --from-pr "$PR_URL" \ --output-format json \ --max-budget-usd 0.50 \ --no-session-persistence \ --permission-mode bypassPermissionsToplu Dosya İşleme:
for file in src/**/*.ts; do claude -p "Add JSDoc comments to $file" \ --output-format json \ --max-budget-usd 0.10 \ --no-session-persistence \ --permission-mode bypassPermissionsdoneHer çağrı tamamen izoledir — dosyalar arasında oturum durumu sızmaz.
CI’da Planla-İncele-Uygula:
Üç adımlı bir iş akışı: bir plan oluştur, insan incelemesi için gönder, onay üzerine uygula.
# Adım 1: Plan oluşturPLAN_RESULT=$(claude -p "Fix all lint errors in src/" \ --permission-mode plan \ --output-format json \ --max-budget-usd 0.50)
# Adım 2: Planı PR yorumu olarak gönderPLAN=$(echo "$PLAN_RESULT" | jq -r \ '.permission_denials[] | select(.tool_name == "ExitPlanMode") | .tool_input.plan')gh pr comment "$PR_NUMBER" --body "$PLAN"
# Adım 3: Onay üzerine uygulaSESSION=$(echo "$PLAN_RESULT" | jq -r '.session_id')claude -p "yes, proceed" \ --resume "$SESSION" \ --permission-mode bypassPermissionsPlan modunda, Claude’un önerilen değişiklikleri tool_name: "ExitPlanMode" ile permission_denials olarak görünür. Plan metni tool_input.plan alanında bulunur.
CI Yanıt Yükü
--no-session-persistence, --max-budget-usd 0.50 ve --output-format json ile bir CI çalıştırmasından gerçek bir yanıt burada.
CI betiklerinizde ayrıştırılacak temel alanlar:
is_error/subtype— bütçe aşımını algılamak için"error_max_budget_usd"kontrol edintotal_cost_usd— toplam CI çalıştırma maliyeti için pipeline adımları arasında toplayınresult— gerçek çıktı metnisession_id—--no-session-persistenceile bile mevcut (yalnızca süreç ömrü boyunca geçerli)stop_reason—"end_turn"normal tamamlama anlamına gelir; diğer değerler kesintiyi gösterir
Bash’te Sonucu Ayrıştırma
#!/usr/bin/env bashset -euo pipefail
RESULT=$(claude -p "Review this diff for bugs" \ --output-format json \ --max-budget-usd 0.50 \ --no-session-persistence \ --permission-mode bypassPermissions)
# Bütçe aşımı kontrolüSUBTYPE=$(echo "$RESULT" | jq -r '.subtype // ""')if [ "$SUBTYPE" = "error_max_budget_usd" ]; then echo "::error::Claude exceeded budget cap" exit 1fi
# Sonuç ve maliyeti çıkarREVIEW=$(echo "$RESULT" | jq -r '.result')COST=$(echo "$RESULT" | jq -r '.total_cost_usd')
echo "Review cost: $COST"echo "$REVIEW"::error:: ön eki, iş akışı özetinde hataları görüntülemek için GitHub Actions söz dizimidir. CI sisteminizin dengiyle değiştirin.
--from-pr PR İnceleme İş Akışı
--from-pr bayrağı, PR bağlamını bir oturuma enjekte ederek otomatik kod incelemeyi mümkün kılar:
# Numarasıyla bir PR'ı incele (doğru git deposunda olmalısınız)claude -p "Review this PR for security issues" \ --from-pr 42 \ --output-format json \ --max-budget-usd 0.25 \ --permission-mode bypassPermissions
# Tam URL ile inceleclaude -p "Summarize what this PR changes" \ --from-pr "https://github.com/org/repo/pull/42" \ --output-format jsonTemel davranışlar:
- Hem PR numarası hem de URL formatları sözdizimsel olarak kabul edilir
- Veri ön yükleyicisi değildir —
--from-prmodele bir PR incelemesi istendiğini bildirir. Model daha sonra araştırmak için araçları (gh pr view,gh pr diff,git log) kullanır. Bu, araç izinleri ve birden fazla tur için yeterli bütçe gerektirir anlamına gelir - Bütçe değerlendirmesi — PR incelemeleri çok turlu işlemlerdir. $0.10 bütçe büyük PR’lar için yeterli olmayabilir. Kapsamlı incelemeler için $0.25+ kullanın
- Zarif bozulma — geçersiz PR numaraları ve git olmayan dizinler çökme değil, yardımcı mesajlar üretir
- GitHub kimlik doğrulaması — özel depolar için
ghCLI,GITHUB_TOKENile kimlik doğrulaması yapılmış olmalıdır
CI/CD PR inceleme pipeline’ları için, —from-pr’yi —output-format json ile birleştirin ve result alanını ayrıştırın: claude -p “Review for security” —from-pr $PR_NUMBER —output-format json | jq -r ‘.result’
CI Claude komutunuza —max-budget-usd 1.00 —output-format json ekleyin. Yanıttaki subtype’ı ayrıştırın — eğer “error_max_budget_usd” ise, pipeline’ı başarısız kılmak yerine bir uyarı kaydedin. CI’da bütçe koruması, iş akışınızı bozmadan sürpriz faturaları önler.
CI/CD Dayanıklılık Kalıpları
Claude ile CI pipeline’ınız zamanın %95’inde çalışıyor. Diğer %5’te, API bir 529 döndürüyor, adımınız başarısız oluyor ve tüm PR iş akışı geliştiriciler beklerken 20 dakika bloke oluyor. Üretim pipeline’ları yeniden deneme mantığı, yedek modeller ve zarif bozulma gerektirir — sadece bir Claude komutu değil.
CI pipeline’ları başarısız olur. API’ler 500 döndürür, hız limitleri devreye girer, ağlar düşer. --fallback-model bayrağı bir başarısızlık modunu (429 hız sınırlama) ele alır, ancak üretim pipeline’ları güvenilir kalmak için açık yeniden deneme mantığı, hata sınıflandırması ve zarif bozulma gerektirir.
Yeniden Deneme Kalıpları
--fallback-model bayrağı yalnızca 429 aşırı yüklenme hatalarını ele alır. Diğer geçici başarısızlıklar — ağ hataları, zaman aşımları, API 500’ler — için açık yeniden deneme mantığı gerekir.
Bash Yeniden Deneme Fonksiyonu
retry_claude() { local max_retries=3 prompt="$1"; shift for attempt in $(seq 1 "$max_retries"); do if RESULT=$(claude -p "$prompt" "$@" 2>/dev/null); then if echo "$RESULT" | jq -e '.is_error != true' >/dev/null 2>&1; then echo "$RESULT" return 0 fi fi echo "Attempt $attempt/$max_retries failed, retrying in $((attempt * 5))s..." >&2 sleep "$((attempt * 5))" done echo "All $max_retries attempts failed" >&2 return 1}Fonksiyon her denemede iki şeyi doğrular: CLI sürecinin başarıyla çıktığını ve JSON yanıtında is_error: true olmadığını. Geri çekilme doğrusal olarak artar — 5 saniye, 10 saniye, 15 saniye.
Node.js Yeniden Deneme Fonksiyonu
Node.js pipeline’ları için aynı kalıp doğrudan çevrilir:
async function retryClaudeSync(args, maxRetries = 3) { for (let attempt = 1; attempt <= maxRetries; attempt++) { try { const output = execFileSync('claude', args, { encoding: 'utf-8', timeout: 120_000, env: { ...process.env, CLAUDECODE: '' } }); const data = JSON.parse(output); if (!data.is_error) return data; } catch (err) { /* yeniden dene */ } if (attempt < maxRetries) { await new Promise(r => setTimeout(r, attempt * 5000)); } } throw new Error(`All ${maxRetries} attempts failed`);}Hata Sınıflandırmalı Gelişmiş Yeniden Deneme
Tüm hatalar yeniden denemeyi hak etmez. Kimlik doğrulama hataları (401/403) yeniden denemede asla başarılı olmaz. Bütçe hataları, işin tamamlandığı ama limitleri aştığı anlamına gelir. Yalnızca geçici hatalar yeniden denemeden fayda görür:
retry_claude_smart() { local max_retries=3 prompt="$1"; shift for attempt in $(seq 1 "$max_retries"); do RESULT=$(claude -p "$prompt" "$@" 2>&1) && { SUBTYPE=$(echo "$RESULT" | jq -r '.subtype // ""') case "$SUBTYPE" in error_max_budget_usd) echo "Budget exceeded — not retrying" >&2 echo "$RESULT"; return 1 ;; success) echo "$RESULT"; return 0 ;; *) # Bilinmeyen subtype -- is_error kontrol et if echo "$RESULT" | jq -e '.is_error != true' >/dev/null 2>&1; then echo "$RESULT"; return 0 fi ;; esac } # Kimlik doğrulama hatası kontrolü (JSON olmayan çıkış) if echo "$RESULT" | grep -qi "unauthorized\|forbidden\|invalid.*key"; then echo "Auth failure — not retrying" >&2 return 1 fi echo "Attempt $attempt/$max_retries failed, retrying in $((attempt * 5))s..." >&2 sleep "$((attempt * 5))" done echo "All $max_retries attempts failed" >&2 return 1}Bu sürüm, yeniden denenebilir hatalar (ağ hataları, 500’ler, zaman aşımları) ile kalıcı hatalar (kimlik doğrulama hataları, bütçe aşımı) arasında ayrım yaparak mahkum yeniden denemelerde zaman ve para kaybını önler.
Kasıtlı olarak bir hız limiti senaryosu tetikleyerek —fallback-model bayrağını test edin:
claude -p “Hello” —output-format json —fallback-model claude-sonnet-4-6 | jq ‘{model: .modelUsage | keys[0], cost: .total_cost_usd}’
Hangi model kullanıldı? Birincil model hız sınırlandığında (429), Claude otomatik olarak daha ucuz modele geçer. Pipeline’ınız her iki maliyet katmanını da ele alıyor mu?
Yedek Modeller
--fallback-model bayrağı, birincil model hız sınırlandığında bir yedek sağlar:
claude -p "Review this PR" \ --fallback-model claude-haiku-4-5-20251001 \ --max-budget-usd 0.50Burada kritik bir sınırlama var. Yedek yalnızca HTTP 429 (hız sınırlama) durumunda tetiklenir. Diğer hatalar için tetiklenmez:
Yedek Tetikleme Matrisi
| Hata Türü | Yedeği Tetikler mi? | Çözümünüz |
|---|---|---|
| Hız sınırlama (429) | Evet | —fallback-model bunu otomatik ele alır |
| API hatası (500) | Hayır | Geri çekilmeli yeniden deneme mantığı kullanın |
| Zaman aşımı | Hayır | Geri çekilmeli yeniden deneme mantığı kullanın |
| Kimlik doğrulama hatası (401/403) | Hayır | Kimlik bilgilerini düzeltin — yeniden denemeler yardımcı olmaz |
Bu, --fallback-model’in genel bir dayanıklılık mekanizması olmadığı anlamına gelir. Tam kapsama için yukarıdaki yeniden deneme fonksiyonuyla birleştirin.
CLI, başlangıçta yedek model isimlerini doğrulamaz. —fallback-model claude-haku-4-5 gibi bir yazım hatası sessizce kabul edilir — hata yalnızca bir 429 yedeği tetiklediğinde ve model ismine ulaşılamadığında ortaya çıkar. İsteğe gerçekte hangi modelin hizmet verdiğini doğrulamak için yanıttaki modelUsage anahtarlarını kontrol edin: Object.keys(data.modelUsage).
Tam Dayanıklılık Pipeline’ı
Yeniden deneme mantığı, yedek modeller, hata sınıflandırması ve bütçe kontrollerini birleştirmek, üretime hazır bir pipeline fonksiyonu verir:
#!/usr/bin/env bashset -euo pipefail
# Üretime hazır CI sarmalayıcıci_claude() { local prompt="$1" local budget="${2:-0.50}" local max_retries="${3:-3}"
for attempt in $(seq 1 "$max_retries"); do RESULT=$(claude -p "$prompt" \ --output-format json \ --max-budget-usd "$budget" \ --fallback-model claude-haiku-4-5-20251001 \ --no-session-persistence \ --permission-mode bypassPermissions 2>/dev/null) && {
SUBTYPE=$(echo "$RESULT" | jq -r '.subtype // ""')
if [ "$SUBTYPE" = "error_max_budget_usd" ]; then echo "::warning::Budget exceeded on attempt $attempt" >&2 echo "$RESULT" return 1 fi
if echo "$RESULT" | jq -e '.is_error != true' >/dev/null 2>&1; then # Toplama için maliyeti kaydet COST=$(echo "$RESULT" | jq -r '.total_cost_usd // 0') echo "::notice::Claude call cost: \$$COST (attempt $attempt)" >&2 echo "$RESULT" return 0 fi }
if [ "$attempt" -lt "$max_retries" ]; then DELAY=$((attempt * 5)) echo "::warning::Attempt $attempt/$max_retries failed, retrying in ${DELAY}s..." >&2 sleep "$DELAY" fi done
echo "::error::All $max_retries attempts failed" >&2 return 1}
# KullanımREVIEW=$(ci_claude "Review this PR for security issues" 1.00 3)echo "$REVIEW" | jq -r '.result'Bu sarmalayıcı tüm dayanıklılık kalıplarını birleştirir: geri çekilmeli yeniden deneme, hız sınırlama için yedek model, bütçe tavanı uygulaması, hata sınıflandırması ve GitHub Actions not çıktısı (::warning::, ::error::, ::notice::).
CI’da Hata Yönetimi
Bütçe Aşımı Algılama
SUBTYPE=$(echo "$RESULT" | jq -r '.subtype // ""')if [ "$SUBTYPE" = "error_max_budget_usd" ]; then echo "::error::Claude exceeded budget cap" exit 1fi::error:: ön eki, iş akışı özetinde hataları görüntülemek için GitHub Actions söz dizimidir. CI sisteminizin dengiyle değiştirin.
—max-budget-usd turlar arasında kontrol edilir, üretim ortasında değil. İlk tur bütçeyi herhangi bir miktarda aşabilir. Opus için sistem istemi cache oluşturma tek başına ~$0.016’ya mal olur, bu yüzden bütçeyi bunun altına ayarlamak yararlı çıktı olmadan bir error_max_budget_usd yanıtını garanti eder.
Eksik API Anahtarı
ANTHROPIC_API_KEY eksik veya geçersizse, CLI sıfır olmayan bir kodla çıkar ancak JSON çıktısı üretmeyebilir. Pipeline’ınız JSON ayrıştırmayı denemeden önce çıkış kodunu kontrol etmelidir, aksi takdirde jq adımı sessizce başarısız olur ve CI işi aslında hiçbir şey yapmadığı halde başarı bildirebilir.
Başsız Modda Hook’lar
SessionStart ve SessionStop hook’ları —print modunda tetiklenmez. Yalnızca PreToolUse, PostToolUse ve Stop hook’ları —print modunda tetiklenir. Denetim kaydınız SessionStart’a bağlıysa, CI’da sessizce atlanacaktır.
Dayanıklılık Sonraki Adımlar
Dayanıklılık kalıpları yerindeyken, CI pipeline’larınız insan müdahalesi olmadan geçici hataları ele alabilir. Bu pipeline’ları ölçekte çalıştırmanın maliyetini yönetmek için Bütçe Kontrolleri ve Ölçekte Maliyet bölümlerine bakın.
CI Claude komutlarınıza —fallback-model claude-sonnet-4-6 ekleyin. Bu, 429 hız limitlerini otomatik olarak ele alır — Claude başarısız olmak yerine Sonnet’e geçer. Diğer hata türleri için çağrıyı bir yeniden deneme döngüsüne sarın: for i in 1 2 3; do RESULT=$(claude -p ”…” —output-format json —fallback-model claude-sonnet-4-6) && break; sleep 5; done.