Skip to content

CI/CD Entegrasyonu

GitHub Actions, özel pipeline'lar, yeniden deneme mantığı ve CI bayrakları

15 dk okuma

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.

GitHub Action -- PR İnceleme İş Akışı
$ # .github/workflows/claude-review.yml
$ cat .github/workflows/claude-review.yml
name: Claude PR Review on: pull_request: types: [opened, synchronize] jobs: review: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: anthropics/claude-code-action@v1 with: prompt: | Review this PR for: 1. Security vulnerabilities 2. Performance issues 3. Code style violations anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} max_budget_usd: 1.00

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.

Actions'da Özel CLI Pipeline
$ # Custom CLI pipeline in GitHub Actions
$ npm install -g @anthropic-ai/claude-code
added 1 package in 4s
$ RESULT=$(claude -p "Review changes for bugs" \ --output-format json \ --max-budget-usd 0.50 \ --no-session-persistence \ --permission-mode bypassPermissions)
$ echo "Cost: $(echo "$RESULT" | jq -r '.total_cost_usd')"
Cost: 0.016079

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ı

BayrakAmacıCI’da Neden Önemli
-p / —printBaşsız modGerekli — CI’da etkileşimli arayüz yok
—output-format jsonMakine 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-persistenceOturumu diske kaydetmeGeçici CI çalıştırıcılarını temiz tutar — artık oturum dosyası kalmaz
—permission-mode bypassPermissionsEtkileşimli istem yokBu olmadan, CLI TTY girdisi bekleyerek takılır ve sonunda zaman aşımına uğrar
—strict-mcp-configHerhangi bir MCP sunucu bağlanamazsa başarısız olCI 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 MODELAşırı yüklenmede alternatif model kullanYalnı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 URLPR’a bağlı oturumu devam ettirOrtamda GITHUB_TOKEN gerektirir

Minimum uygulanabilir CI çağrısı bu bayraklardan dördünü birleştirir:

Terminal window
claude -p "Review this code for bugs" \
--output-format json \
--max-budget-usd 0.50 \
--no-session-persistence \
--permission-mode bypassPermissions
Try This

Bir 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:

Terminal window
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 bypassPermissions

Toplu Dosya İşleme:

Terminal window
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 bypassPermissions
done

Her ç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.

Terminal window
# Adım 1: Plan oluştur
PLAN_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önder
PLAN=$(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 uygula
SESSION=$(echo "$PLAN_RESULT" | jq -r '.session_id')
claude -p "yes, proceed" \
--resume "$SESSION" \
--permission-mode bypassPermissions

Plan 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 Çalıştırması -- Bütçe Tavanı + Kalıcılık Yokartifacts/14/ci_flags_test.json
1{
2 "type": "result",
3 "subtype": "success",A
4 "is_error": false,
5 "duration_ms": 1513,
6 "duration_api_ms": 1497,
7 "num_turns": 1,
8 "result": "4",B
9 "stop_reason": "end_turn",E
10 "session_id": "94d02fdc-9f01-4b5c-8bc9-8f08e684d8a3",C
11 "total_cost_usd": 0.016079,D
12 "usage": {
13 "input_tokens": 3,
14 "cache_creation_input_tokens": 1410,
15 "cache_read_input_tokens": 14253,
16 "output_tokens": 5,
17 "server_tool_use": {
18 "web_search_requests": 0,
19 "web_fetch_requests": 0
20 },
21 "service_tier": "standard"
22 },
23 "modelUsage": {
24 "claude-opus-4-6": {
25 "inputTokens": 3,
26 "outputTokens": 5,
27 "cacheReadInputTokens": 14253,
28 "cacheCreationInputTokens": 1410,
29 "costUSD": 0.016079,
30 "contextWindow": 200000,
31 "maxOutputTokens": 32000
32 }
33 },
34 "permission_denials": [],
35 "fast_mode_state": "off"
36}
ACI'da bunu ilk kontrol edin -- false, çağrının başarılı olduğu anlamına gelir
BGerçek çıktı metni -- jq -r '.result' ile çıkarın
C--no-session-persistence ile bile mevcut, ancak çıkış sonrası devam ettirilemez
DToplam CI çalıştırma maliyeti için pipeline adımları arasında toplayın
Eend_turn, Claude'un doğal olarak bitirdiği anlamına gelir -- kesilmişse max_tokens'ı izleyin

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 edin
  • total_cost_usd — toplam CI çalıştırma maliyeti için pipeline adımları arasında toplayın
  • result — gerçek çıktı metni
  • session_id--no-session-persistence ile 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 bash
set -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 1
fi
# Sonuç ve maliyeti çıkar
REVIEW=$(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:

Terminal window
# 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 incele
claude -p "Summarize what this PR changes" \
--from-pr "https://github.com/org/repo/pull/42" \
--output-format json

Temel davranışlar:

  • Hem PR numarası hem de URL formatları sözdizimsel olarak kabul edilir
  • Veri ön yükleyicisi değildir--from-pr modele 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 gh CLI, GITHUB_TOKEN ile kimlik doğrulaması yapılmış olmalıdır
Tip

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’

Now Do This

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

Terminal window
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:

Terminal window
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.

Retry with Exponential Backoff
time 529 overloaded attempt 1 1s 429 rate limit attempt 2 2s 429 rate limit attempt 3 4s Sonnet fallback model primary model fails --fallback-model
Try This

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:

Terminal window
claude -p "Review this PR" \
--fallback-model claude-haiku-4-5-20251001 \
--max-budget-usd 0.50

Burada 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ırGeri çekilmeli yeniden deneme mantığı kullanın
Zaman aşımıHayırGeri çekilmeli yeniden deneme mantığı kullanın
Kimlik doğrulama hatası (401/403)HayırKimlik 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.

Geçersiz Yedek İsimleri Sessizce Kabul Edilir

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 bash
set -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ım
REVIEW=$(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

Terminal window
SUBTYPE=$(echo "$RESULT" | jq -r '.subtype // ""')
if [ "$SUBTYPE" = "error_max_budget_usd" ]; then
echo "::error::Claude exceeded budget cap"
exit 1
fi

::error:: ön eki, iş akışı özetinde hataları görüntülemek için GitHub Actions söz dizimidir. CI sisteminizin dengiyle değiştirin.

Gotcha

—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ı

Gotcha

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

Tip

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.

Now Do This

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.