Praktische Referenz für die Integration von Claude Code in GitHub Actions Workflows. Setup, Konfiguration, Use Cases, Kosten-Management und Troubleshooting.
Setup & Grundkonfiguration
Installation der Action
Die offizielle Action ist verfügbar im GitHub Marketplace:
# .github/workflows/claude-code-review.yml
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Claude Code Review
uses: anthropics/claude-code-action@v1
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
model: claude-opus
max-turns: 20
Secrets Setup
Die API-Keys müssen in GitHub Secrets gespeichert werden:
# 1. Secrets im Repository hinzufügen
# Settings → Secrets and variables → Actions → New repository secret
# Name: ANTHROPIC_API_KEY
# Value: sk-ant-v1-...
In GitHub UI:
- Repository öffnen
- Settings → Security → Secrets and variables → Actions
- "New repository secret" klicken
- Name:
ANTHROPIC_API_KEY - Value: API Key von https://console.anthropic.com/account/keys
CLAUDE.md im CI-Context
---
name: Code Review Agent
description: >
Spezialisiert auf sicherheit, Performance und Wartbarkeit.
Trigger: code-review, security-check, performance-audit
version: 1.0.0
---
# Code Review für CI/CD
## Kontext
Du arbeitet in GitHub Actions mit begrenztem Context und Timeout von 300 Sekunden.
## Regeln
- Fokus auf: Security, Performance, Best Practices
- Max 5 kritische Probleme pro Review
- Verwende Standard-Report-Format (GH Comments)
- Kein Auto-Approve — nur Feedback
Use Cases
1. Automatischer Code Review auf Pull Requests
name: Auto Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Claude Code Review
uses: anthropics/claude-code-action@v1
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
model: claude-opus
max-turns: 15
custom-instructions: |
Überprüfe diesen PR auf:
1. Security Vulnerabilities
2. Performance Issues
3. Code Style Violations
4. Missing Tests
5. API Breaking Changes
output-format: github-comments
- name: Post Review as Comment
if: always()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const review = fs.readFileSync('claude-review.md', 'utf-8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: review
});
2. Automatische PR-Beschreibungen
name: Generate PR Description
on:
pull_request:
types: [opened]
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Analyse Changes
id: changes
run: |
git diff origin/main..HEAD --stat > /tmp/changes.txt
echo "changes=$(cat /tmp/changes.txt)" >> $GITHUB_OUTPUT
- name: Generate Description
uses: anthropics/claude-code-action@v1
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
model: claude-sonnet
max-turns: 5
custom-instructions: |
Erstelle eine aussagekräftige PR-Beschreibung basierend auf:
- Geänderten Dateien
- Git Diff
- Branch Name: ${{ github.head_ref }}
Format:
## Changes
(Kurze Zusammenfassung)
## Testing
(Wie wurde getestet)
## Breaking Changes
(Falls vorhanden)
output-format: raw
- name: Update PR Description
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const description = fs.readFileSync('claude-output.md', 'utf-8');
github.rest.pulls.update({
pull_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: description
});
3. Issue Triage & Auto-Labeling
name: Issue Triage
on:
issues:
types: [opened, edited]
jobs:
triage:
runs-on: ubuntu-latest
steps:
- name: Analyze Issue
uses: anthropics/claude-code-action@v1
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
model: claude-sonnet
max-turns: 3
custom-instructions: |
Analysiere dieses GitHub Issue und gebe folgende Labels zurück:
- bug / feature / enhancement / documentation
- priority: critical / high / medium / low
- complexity: simple / moderate / complex
Issue Title: ${{ github.event.issue.title }}
Issue Body: ${{ github.event.issue.body }}
Output Format (JSON):
{
"labels": ["label1", "label2"],
"priority": "high",
"suggest_assignee": true
}
output-format: json
- name: Apply Labels
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const labels = JSON.parse(fs.readFileSync('claude-output.json', 'utf-8'));
github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: labels.labels
});
4. Test-Generierung aus Code
name: Generate Missing Tests
on:
pull_request:
paths:
- 'src/**/*.ts'
- 'src/**/*.js'
jobs:
generate-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Find Untested Functions
id: untested
run: |
# Finde Funktionen ohne Tests
git diff origin/main..HEAD --name-only --diff-filter=AM | grep -E '\.(ts|js)$' > /tmp/new-files.txt
echo "files=$(cat /tmp/new-files.txt)" >> $GITHUB_OUTPUT
- name: Generate Tests
uses: anthropics/claude-code-action@v1
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
model: claude-opus
max-turns: 10
custom-instructions: |
Erstelle Vitest-Tests für folgende Funktionen:
${{ steps.untested.outputs.files }}
Anforderungen:
- Mindestens 80% Code Coverage
- Teste Edge Cases
- Benutze Mocking wo nötig
- Formatierung: TypeScript/Vitest
output-format: file
output-path: test-suggestions.ts
- name: Create Test Suggestion Comment
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const tests = fs.readFileSync('test-suggestions.ts', 'utf-8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '## Suggested Tests\n\n```typescript\n' + tests + '\n```'
});
5. Security Scanning & Vulnerability Detection
name: Security Scan
on:
pull_request:
push:
branches: [main, develop]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Scan for Security Issues
uses: anthropics/claude-code-action@v1
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
model: claude-opus
max-turns: 20
custom-instructions: |
Überprüfe diesen Code auf Security Issues:
1. SQL Injection Vulnerabilities
2. XSS/HTML Injection
3. Authentication Bypass
4. Exposed API Keys/Secrets
5. Deserialization Vulnerabilities
6. CSRF Issues
7. Weak Cryptography
8. Path Traversal Bugs
Format: Markdown mit Severity Level (CRITICAL, HIGH, MEDIUM, LOW)
output-format: github-comments
- name: Fail on Critical Issues
if: failure()
run: |
echo "::error::Critical security issues found!"
exit 1
6. Changelog & Release Notes Generator
name: Generate Changelog
on:
push:
tags:
- 'v*'
jobs:
changelog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get Changes
id: changes
run: |
git log $(git describe --tags --abbrev=0)..HEAD --oneline > /tmp/commits.txt
echo "commits=$(cat /tmp/commits.txt)" >> $GITHUB_OUTPUT
- name: Generate Changelog
uses: anthropics/claude-code-action@v1
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
model: claude-sonnet
max-turns: 5
custom-instructions: |
Erstelle Changelog/Release Notes aus diesen Commits:
${{ steps.changes.outputs.commits }}
Format (Markdown):
## Features
- Item 1
- Item 2
## Bug Fixes
- Fix 1
## Breaking Changes
- If any
## Upgrade Guide
- Step 1
- Step 2
output-format: raw
- name: Create Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
body_path: claude-output.md
draft: false
prerelease: false
Konfigurationsoptionen
Action Input Parameter
with:
# Required
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
# Optional - Default: claude-opus
model: claude-opus | claude-sonnet | claude-haiku
# Optional - Default: 20
max-turns: 10
# Optional - Zusätzliche Anweisungen
custom-instructions: |
Mach X, Y, Z
# Optional - Default: raw
output-format: raw | json | github-comments | file
# Optional - Für file output
output-path: ./results.md
# Optional - Timeout in Sekunden (default: 600)
timeout: 300
# Optional - Temperature (0.0 - 1.0)
temperature: 0.7
Model Auswahl nach Task
| Task | Empfehlung | Grund |
|---|---|---|
| Code Review | opus | Komplexe Analyse |
| Test Generation | opus | Umfangreiche Coverage |
| PR Description | sonnet | Schnell + ausreichend |
| Issue Triage | haiku | Einfache Kategorisierung |
| Security Scan | opus | Gründliche Analyse |
| Simple Linting | haiku | Schnell + kostengünstig |
Kosten-Management
Cost Optimization Strategy
name: Cost-Optimized Workflow
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Stage 1: Quick check mit Haiku (cheap)
- name: Quick Lint Check
uses: anthropics/claude-code-action@v1
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
model: claude-haiku
max-turns: 3
timeout: 60
# Stage 2: Full review mit Sonnet nur wenn Flag gesetzt
- name: Full Code Review
if: contains(github.event.pull_request.labels.*.name, 'needs-full-review')
uses: anthropics/claude-code-action@v1
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
model: claude-opus
max-turns: 15
timeout: 300
# Stage 3: Security scan nur auf main/protected branches
- name: Security Scan
if: github.ref == 'refs/heads/main'
uses: anthropics/claude-code-action@v1
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
model: claude-opus
max-turns: 20
Token Budgeting
# Python script für Budget-Tracking
import json
import os
from datetime import datetime
def track_token_usage(run_id, model, tokens_used):
"""Track Claude API token usage per workflow run"""
budget_file = "/tmp/claude-budget.json"
# Model pricing (Stand März 2026)
pricing = {
"claude-opus": {"input": 0.015, "output": 0.075},
"claude-sonnet": {"input": 0.003, "output": 0.015},
"claude-haiku": {"input": 0.00080, "output": 0.004}
}
entry = {
"timestamp": datetime.now().isoformat(),
"run_id": run_id,
"model": model,
"tokens_used": tokens_used,
"cost_usd": (tokens_used * pricing[model]["input"]) / 1000
}
# Append to log
if os.path.exists(budget_file):
with open(budget_file, 'r') as f:
budget = json.load(f)
else:
budget = []
budget.append(entry)
with open(budget_file, 'w') as f:
json.dump(budget, f)
# Weekly summary
weekly_cost = sum(e["cost_usd"] for e in budget
if (datetime.now() - datetime.fromisoformat(e["timestamp"])).days < 7)
print(f"Weekly cost: ${weekly_cost:.2f}")
Fehlerbehandlung
Common Issues & Fixes
1. API Key Not Found
# Problem: secret nicht gesetzt
# Lösung: GitHub Secrets prüfen
- name: Debug Secret
run: |
if [ -z "${{ secrets.ANTHROPIC_API_KEY }}" ]; then
echo "ERROR: ANTHROPIC_API_KEY not set"
exit 1
fi
echo "API Key configured"
2. Timeout
# Problem: Workflow überschreitet Zeit
# Lösung: max-turns reduzieren oder timeout erhöhen
- name: Claude Code Action
uses: anthropics/claude-code-action@v1
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
max-turns: 5 # Reduce from 20
timeout: 120 # Increase from 60
3. Context Size Exceeded
# Problem: PR ist zu groß für ein Call
# Lösung: Auf spezifische Files filtern
- name: Review Only Changed Files
uses: anthropics/claude-code-action@v1
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
custom-instructions: |
Überprüfe nur diese Dateien:
- ${{ steps.files.outputs.changed }}
Best Practices
1. Caching für häufige Analysen
- name: Cache Analysis Results
uses: actions/cache@v3
with:
path: ./analysis-cache
key: claude-analysis-${{ hashFiles('src/**') }}
2. Parallel Reviews bei großen PRs
strategy:
matrix:
chunk: [1, 2, 3]
steps:
- name: Review Chunk ${{ matrix.chunk }}
uses: anthropics/claude-code-action@v1
3. Notifications bei kritischen Issues
- name: Notify on Critical Issues
if: contains(env.REVIEW_RESULT, 'CRITICAL')
uses: actions/github-script@v7
with:
script: |
github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['security-issue', 'needs-attention']
});
