14 · Pipeline locali
Una pipeline è una catena di passaggi automatici in cui l’uscita di uno è l’ingresso del successivo: raccogli → elabora → pubblica. In questo modulo Claude diventa uno degli anelli della catena — non tutta la catena — e imparerai i tre pattern che coprono quasi tutto: la composizione con gli strumenti Unix, il fan-out (letteralmente “apertura a ventaglio”: lo stesso lavoro distribuito su tante invocazioni indipendenti, una per file) e l’integrazione in CI — il servizio che esegue controlli automatici a ogni modifica del codice, per noi GitHub Actions.
Obiettivi
Sezione intitolata “Obiettivi”- Comporre Claude Code con gli altri strumenti da riga di comando invece di sostituirli.
- Elaborare centinaia di file distribuendo il lavoro su invocazioni parallele.
- Integrare Claude Code in GitHub Actions, con l’autenticazione giusta.
- Far fallire una pipeline quando serve, e solo quando serve.
- Riconoscere quando Claude non è lo strumento giusto per un passaggio.
Concetti chiave
Sezione intitolata “Concetti chiave”Claude Code è un pezzo della pipeline, non la pipeline. Legge da stdin, scrive su stdout, restituisce
un exit code: si compone con git, jq, xargs, find. La regola pratica è che ogni passaggio che un
comando deterministico può fare, deve farlo un comando deterministico. Claude serve dove serve
giudizio.
# ✗ Sbagliato: chiedi a Claude di fare quello che grep fa meglioclaude -p "find all files containing TODO"
# ✓ Giusto: grep trova, Claude giudicagrep -rn "TODO" src/ | claude -p "group these TODOs by theme and flag the ones that look like real bugs"Il fan-out batte il singolo prompt gigante. Per migrazioni o analisi su molti file, distribuire il
lavoro su tante invocazioni claude -p è più affidabile di un unico prompt che chiede di fare tutto: ogni
invocazione ha contesto pulito, gli errori sono isolati, e puoi ritentare solo i file falliti.
In CI, autentica con un token, non con il browser. claude setup-token genera un token OAuth di lunga
durata, valido un anno, che autentica con il tuo abbonamento. Lo metti nei secret del repository come
CLAUDE_CODE_OAUTH_TOKEN.
Comporre con gli strumenti Unix
Sezione intitolata “Comporre con gli strumenti Unix”Pipe in ingresso
Sezione intitolata “Pipe in ingresso”# Spiegare un errore di buildnpm run build 2>&1 | tail -50 | claude -p 'spiega in un paragrafo la causa radice di questo errore'
# Rivedere una diff senza dare permessi Bash a Claudegit diff main | claude -p 'elenca i problemi di correttezza, uno per riga, formato file:riga — problema'
# Analizzare dei logjournalctl -u myservice --since "1 hour ago" | claude -p 'raggruppa questi errori per causa e stima la gravità'
# Riassumere un CSVhead -200 dati.csv | claude -p 'descrivi le colonne, i tipi e le anomalie che noti'Pipe in uscita
Sezione intitolata “Pipe in uscita”# Il risultato in un fileclaude -p 'riassumi il progetto' > SUMMARY.md
# Estrarre e riusareclaude -p "elenca gli endpoint" --output-format json | jq -r '.result' | sort
# Concatenare con altri comandiclaude -p "elenca i file da migrare" \ --output-format json --json-schema '{"type":"object","properties":{"files":{"type":"array","items":{"type":"string"}}},"required":["files"]}' \ | jq -r '.structured_output.files[]' > files.txtElaborazioni batch
Sezione intitolata “Elaborazioni batch”Il pattern documentato per le migrazioni su larga scala ha tre fasi.
-
Genera la lista di lavoro. Fai scrivere a Claude l’elenco dei file da trattare, così il ciclo del passo successivo può leggerlo. L’esempio che seguiremo in tutto il capitolo: migrare i file che usano ancora la vecchia API di configurazione del progetto alla nuova.
list all files that still use the legacy config API and save the list to files.txt(= “elenca i file che usano ancora la vecchia API di configurazione e salva la lista in files.txt”)
-
Cicla sulla lista. Un giro di ciclo = un’invocazione di Claude = un file, ognuna con il suo contesto pulito:
Terminal window # per ogni riga di files.txt...for file in $(cat files.txt); do# ...un'invocazione dedicata, che risponde solo OK o FAILclaude -p "Migrate $file from the legacy config API to the new one. Return OK or FAIL." \--allowedTools "Edit,Bash(git commit *)"done -
Prova su pochi file, poi scala. Raffina il prompt in base a cosa va storto sui primi due o tre, poi lancia sull’insieme completo.
--allowedToolslimita cosa Claude può fare, e conta molto quando gira senza sorveglianza.
Una versione più robusta
Sezione intitolata “Una versione più robusta”Il ciclo minimo funziona per una dimostrazione. Per un lavoro vero servono parallelismo, log e la possibilità di ritentare:
#!/usr/bin/env bash# Nota: manca apposta la "-e" (esci al primo errore): un file che# fallisce NON deve fermare la migrazione degli altri — i fallimenti# li gestiamo noi, marcandoli e proseguendo.set -uo pipefail
# argomenti con default: la lista dei file e quante migrazioni in paralleloLISTA="${1:-files.txt}"PARALLELI="${2:-4}"# tre cartelle di lavoro in un colpo (la brace expansion {a,b,c} le crea tutte)mkdir -p .migrazione/{ok,fail,log}
# la funzione che migra UN filemigra_uno() { local file="$1" local slug # trasforma il percorso in un nome di file valido: src/app.py -> src_app.py slug=$(printf '%s' "$file" | tr '/' '_')
# IDEMPOTENZA (= rieseguire non fa danni): se questo file risulta gia # migrato da un run precedente, saltalo. E cio che rende lo script # ri-lanciabile dopo un'interruzione senza rifare tutto. [ -f ".migrazione/ok/$slug" ] && { echo "skip $file"; return 0; }
# l'invocazione vera: prompt preciso, permessi minimi, tetto ai turni, # e TUTTO l'output in un log dedicato a questo file (2>&1 = anche gli errori) if claude -p "Migrate $file from the legacy config API to the new one. \Follow the pattern in src/config/new-api.ts. Do not change behaviour. \Run \`npm run typecheck\` when done. Reply with exactly OK or FAIL." \ --allowedTools "Read,Edit,Bash(npm run typecheck)" \ --max-turns 15 \ > ".migrazione/log/$slug.log" 2>&1 then # Claude ha risposto: ha detto proprio "OK"? if grep -q '^OK' ".migrazione/log/$slug.log"; then touch ".migrazione/ok/$slug"; echo "ok $file"; return 0 fi fi
# qualsiasi altro esito: marca il fallimento (il log dira perche) touch ".migrazione/fail/$slug"; echo "FAIL $file"; return 1}# rende la funzione visibile ai processi figli che xargs lanceraexport -f migra_uno
# il motore del parallelismo: xargs legge la lista (-a) e lancia fino a# PARALLELI processi insieme (-P), chiamando migra_uno su ogni file.# La coda "bash -c '...' _ {}" e un idioma fisso: serve solo a passare# il nome del file alla funzione — copialo cosi com'e.xargs -a "$LISTA" -P "$PARALLELI" -I{} bash -c 'migra_uno "$@"' _ {}
# riepilogo: conta i marcatori nelle due cartelleechoecho "riusciti: $(ls .migrazione/ok | wc -l) falliti: $(ls .migrazione/fail | wc -l)"echo "per ritentare i falliti:"# ricostruisce i percorsi dai nomi dei marcatori e li salva come nuova listaecho " ls .migrazione/fail | tr '_' '/' > retry.txt && ./migra.sh retry.txt"Le quattro proprietà che lo rendono usabile: idempotenza (i file già fatti si saltano),
parallelismo controllato con xargs -P, log per file per capire i fallimenti, e una lista di
retry invece di rifare tutto.
Claude Code in CI
Sezione intitolata “Claude Code in CI”Preparare l’autenticazione
Sezione intitolata “Preparare l’autenticazione”-
Genera il token, una volta sola, dalla tua macchina:
Terminal window claude setup-tokenSi apre lo stesso flusso di autorizzazione del browser di
/login, e il token viene stampato a terminale dopo l’approvazione. Non viene salvato da nessuna parte: copialo subito. -
Mettilo nei secret del repository come
CLAUDE_CODE_OAUTH_TOKEN:Terminal window gh secret set CLAUDE_CODE_OAUTH_TOKEN -
Ricorda i suoi limiti. Il token può solo fare richieste al modello: non può stabilire sessioni Remote Control né recuperare i connettori di claude.ai. I server MCP configurati localmente funzionano.
Uno script in CI
Sezione intitolata “Uno script in CI”Se parti da zeroCos'è GitHub Actions e come si legge un workflow
GitHub Actions è il servizio di CI integrato in GitHub: metti un file
YAML nella cartella .github/workflows/ del repository, e GitHub esegue quei
passi su una sua macchina (il runner) ogni volta che accade l’evento indicato. Le parole chiave dei
file che vedrai: on: = quando scattare (un push, l’apertura di una PR, un orario); jobs: = i
lavori da eseguire; steps: = i passi di ciascun lavoro; uses: = “riusa un’azione già pronta”;
run: = “esegui questo comando”; secrets = le credenziali custodite da GitHub, mai scritte nel
file.
Il modo più semplice: uno script che gira come qualsiasi altro passo.
name: Claude review
on: pull_request: types: [opened, synchronize]
jobs: review: runs-on: ubuntu-latest permissions: contents: read steps: - uses: actions/checkout@v6 with: fetch-depth: 0
- name: Installa Claude Code run: curl -fsSL https://claude.ai/install.sh | bash
- name: Review della diff env: CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} run: | git diff origin/${{ github.base_ref }}...HEAD \ | claude --bare -p "Review this diff. Report only defects that affect correctness or security and that have a concrete failure scenario." \ --output-format json \ --max-turns 10 \ | jq -r '.result'Il --bare è la scelta che conta: senza, il job eseguirebbe gli hook e i server MCP definiti nel
repository, che su una PR da un fork significa eseguire codice di un estraneo.
La GitHub Action ufficiale
Sezione intitolata “La GitHub Action ufficiale”Per l’integrazione completa — rispondere a @claude, aprire PR, commentare inline — esiste
anthropics/claude-code-action.
Il setup rapido è un comando da dentro Claude Code:
/install-github-appInstalla la Claude GitHub App, configura il secret di autenticazione e prepara la PR con i file di workflow. Serve accesso admin al repository e il GitHub CLI autenticato.
Il workflow minimo, in modalità interattiva:
name: Claude Codeon: issue_comment: types: [created] pull_request_review_comment: types: [created]jobs: claude: if: contains(github.event.comment.body, '@claude') runs-on: ubuntu-latest permissions: contents: write pull-requests: write issues: write id-token: write actions: read steps: - uses: actions/checkout@v6 with: fetch-depth: 1 - uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}Quasi tutte le righe di questo file sono la struttura fissa che ogni workflow ripete uguale (il “boilerplate” nel senso di codice-cerimonia — non confonderlo con le cartelle-template del modulo 18, che rubano lo stesso nome). Le righe che invece meritano attenzione:
| Riga | Perché c’è |
|---|---|
id-token: write |
Richiesto dall’autenticazione di default via GitHub App |
actions: read |
Permette a Claude di leggere i risultati della CI sulle PR |
actions/checkout |
Dà a Claude una copia locale del repository |
if: contains(...) |
Evita di avviare runner su commenti che non menzionano @claude |
Due modalità
Sezione intitolata “Due modalità”| Modalità | Quando | Comportamento |
|---|---|---|
| Interattiva | Il workflow non passa l’input prompt |
Claude aspetta la frase trigger, @claude di default, in un commento o nel corpo di una issue appena aperta. Progresso e risultati appaiono come commento |
| Automazione | Il workflow passa prompt |
Claude parte senza aspettare una menzione. I risultati finiscono nel log del run, a meno che il prompt non gli dica di pubblicare |
Chi può far partire un run
Sezione intitolata “Chi può far partire un run”Due controlli sull’attore che ha innescato il run, e il run fallisce se uno dei due rifiuta:
- Accesso in scrittura — su eventi di issue e pull request, l’utente deve avere accesso in scrittura al
repository. Per permettere utenti specifici senza scrittura serve
allowed_non_write_users, che richiede anche un token GitHub personalizzato (github_token). Attenzione al doppio taglio di quel parametro: come vedremo nel troubleshooting, passare ilGITHUB_TOKENdi default impedisce ai commit di Claude di far partire la CI — quindi usalo solo se ti serve davvero questa eccezione, e in quel caso con un token di una GitHub App dedicata. Gli eventi senza autore, come un triggerschedule, saltano il controllo. - Attore umano — su ogni evento, un attore bot viene rifiutato a meno che non sia in
allowed_bots. Serve a evitare che i bot facciano partire Claude in loop. Vale anche per i run schedulati, che GitHub attribuisce a un utente del repository, di solito l’ultimo che ha toccato ilcron.
Un run schedulato
Sezione intitolata “Un run schedulato”name: Daily Reporton: schedule: - cron: "0 9 * * *" # sintassi cron: minuto ora giorno mese giorno-settimana # "0 9 * * *" = alle 9:00 UTC, ogni giornojobs: report: runs-on: ubuntu-latest permissions: contents: read issues: read id-token: write steps: - uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} prompt: "Generate a summary of yesterday's commits and open issues" claude_args: | --model claude-opus-4-8 --allowedTools "mcp__github__list_commits,mcp__github__list_issues"Con un prompt di testo semplice, Claude non ha accesso a shell né alle API GitHub finché non gli
concedi i tool che gli servono, tramite --allowedTools in claude_args o una regola permissions.allow
nell’input settings. Qui legge commit e issue via API con i tool MCP di GitHub, quindi il checkout non
serve.
Il parametro claude_args
Sezione intitolata “Il parametro claude_args”Accetta qualsiasi argomento della CLI:
claude_args: "--max-turns 5 --model claude-sonnet-5 --mcp-config /path/to/config.json"I più usati: --max-turns, --model, --mcp-config, --allowedTools, --debug.
Esempio guidato
Sezione intitolata “Esempio guidato”-
Una pipeline locale in un comando. Trova, giudica, formatta:
Terminal window git log --since="1 week ago" --oneline \| claude -p "raggruppa questi commit per area funzionale. Per ogni area, una riga: area — cosa è cambiato. Niente preamboli." \| tee CHANGELOG-settimana.md -
Un gate riusabile. Riprendi lo script del modulo 12 e usalo come pre-push hook:
.git/hooks/pre-push #!/usr/bin/env bash./gate.sh origin/main || {echo "Push bloccato dal gate. Per forzare: git push --no-verify" >&2exit 1}Terminal window chmod +x .git/hooks/pre-push -
Un batch su molti file. Prima la lista:
Terminal window grep -rln "require(" src/ > files.txtwc -l files.txtPoi due file di prova:
Terminal window head -2 files.txt > prova.txt./migra.sh prova.txt 1cat .migrazione/log/*.logSolo quando i due funzionano, tutto il resto:
Terminal window ./migra.sh files.txt 4 -
Porta la stessa cosa in CI. Crea il token e il secret:
Terminal window claude setup-tokengh secret set CLAUDE_CODE_OAUTH_TOKENPoi il workflow
review.ymlvisto sopra. -
Verifica il workflow senza aspettare una PR.
Terminal window gh workflow run review.yml || gh run list --workflow=review.yml --limit 3Per un workflow che scatta su
pull_request, apri una PR di prova con una modifica banale. -
Aggiungi la Action ufficiale.
/install-github-appPoi menziona
@claudein un commento di una issue per verificare.
Quando Claude non è lo strumento giusto
Sezione intitolata “Quando Claude non è lo strumento giusto”Vale la pena dirlo esplicitamente, perché è l’errore più costoso in una pipeline:
| Non usare Claude per | Usa invece | Cosa sono |
|---|---|---|
| Trovare pattern testuali | grep, rg |
I cerca-testo del terminale, istantanei |
| Formattare codice | prettier, black, gofmt |
I formattatori automatici (JS, Python, Go) |
| Applicare regole di lint deterministiche | eslint, ruff |
I linter: trovano gli errori senza eseguire |
| Trasformazioni sintattiche meccaniche | codemod, jscodeshift, ast-grep |
Strumenti che riscrivono codice seguendo una regola esatta |
| Validare uno schema | ajv, jsonschema |
Validatori di JSON Schema |
| Contare, ordinare, deduplicare | wc, sort, uniq |
I coltellini svizzeri Unix del testo |
Claude serve dove serve giudizio: capire perché una build fallisce, decidere se un TODO è un bug, scrivere il codice che il codemod non sa scrivere, rivedere una diff. Metterlo dove basta un comando significa pagare latenza e token per un risultato meno affidabile.
Esercizio
Sezione intitolata “Esercizio”Costruisci una pipeline che produca un report settimanale del repository, e falla girare da sola.
- Raccogli i dati con comandi deterministici: commit, issue, risultati della CI.
- Fai a Claude solo la parte di giudizio: cosa è successo davvero, cosa è a rischio.
- Produci un output strutturato, non prosa.
- Falla girare ogni lunedì in GitHub Actions.
Soluzione
Passi 1–3. Lo script locale, che raccoglie con git e gh e delega solo la sintesi:
#!/usr/bin/env bashset -euo pipefail
DA="${1:-1 week ago}"
# Tutto cio che e deterministico lo fanno git e gh. Le graffe { ... }# raggruppano i comandi: l'output di TUTTI finisce insieme nel file# indicato dopo la parentesi (un solo ">" per l'intero blocco).{ echo "## Commit" # la storia della settimana, un commit per riga (%h=hash, %s=messaggio, %an=autore) git log --since="$DA" --pretty='- %h %s (%an)' echo echo "## Issue aperte questa settimana" # gh restituisce JSON; il suo flag --jq lo formatta al volo in righe # markdown (e jq "annidato" dentro gh: stessa sintassi del modulo 13) gh issue list --state open --search "created:>$(date -d "$DA" +%F)" \ --json number,title,labels \ --jq '.[] | "- #\(.number) \(.title) [\(.labels | map(.name) | join(", "))]"' echo echo "## Ultimi run di CI" gh run list --limit 20 --json conclusion,name,createdAt \ --jq '.[] | "- \(.createdAt[0:10]) \(.name): \(.conclusion)"'} > .dati-settimana.md
# A Claude solo il giudizio.claude --bare -p "Da questi dati grezzi produci un report settimanale.Non ripetere l'elenco dei commit: sintetizza per tema.Per i rischi, riporta solo cose che i dati mostrano davvero, citando la prova." \ --output-format json \ --json-schema '{ "type": "object", "properties": { "titolo": { "type": "string" }, "sintesi": { "type": "string" }, "temi": { "type": "array", "items": { "type": "object", "properties": { "tema": { "type": "string" }, "cosa": { "type": "string" }, "commit": { "type": "array", "items": { "type": "string" } } }, "required": ["tema", "cosa", "commit"] } }, "rischi": { "type": "array", "items": { "type": "object", "properties": { "rischio": { "type": "string" }, "prova": { "type": "string" }, "gravita": { "type": "string", "enum": ["alta", "media", "bassa"] } }, "required": ["rischio", "prova", "gravita"] } } }, "required": ["titolo", "sintesi", "temi", "rischi"] }' \ < .dati-settimana.md \ | jq '.structured_output' > report.json
# Il markdown lo genera jq, non Claude: è formattazione, non giudizio.jq -r ' "# \(.titolo)\n\n\(.sintesi)\n\n## Temi\n" + ([.temi[] | "### \(.tema)\n\(.cosa)\n\nCommit: \(.commit | join(", "))\n"] | join("\n")) + "\n## Rischi\n" + ([.rischi[] | "- **[\(.gravita)]** \(.rischio)\n - prova: \(.prova)"] | join("\n"))' report.json > REPORT.md
rm -f .dati-settimana.mdecho "✔ REPORT.md generato"Tre decisioni che vale la pena notare:
| Decisione | Perché |
|---|---|
I dati li raccolgono git e gh |
Sono esatti e gratis. Chiedere a Claude di eseguire git log costerebbe permessi, turni e token per un risultato meno affidabile |
--bare |
Nessun CLAUDE.md né hook del repo: il report deve venire dai dati, non da istruzioni di progetto |
Il markdown lo genera jq |
Formattare non richiede giudizio. Claude produce la struttura, la presentazione la fa un template |
Passo 4. Il workflow:
name: Report settimanale
on: schedule: - cron: "0 7 * * 1" # ogni lunedì alle 07:00 UTC workflow_dispatch: # e a mano, per provarlo
jobs: report: runs-on: ubuntu-latest permissions: contents: write issues: read actions: read steps: - uses: actions/checkout@v6 with: fetch-depth: 0
- name: Installa Claude Code run: curl -fsSL https://claude.ai/install.sh | bash
- name: Genera il report env: CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: ./report-settimanale.sh "1 week ago"
- name: Pubblica come issue env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: gh issue create --title "Report settimanale $(date +%F)" --body-file REPORT.mdDue dettagli che fanno la differenza tra un workflow che funziona e uno che sembra funzionare:
workflow_dispatchti permette di provarlo subito congh workflow run report-settimanale.yml, invece di aspettare lunedì per scoprire un errore di sintassi.fetch-depth: 0: senza,actions/checkoutfa un clone shallow (“superficiale”: scarica solo l’ultimo commit, senza la storia) egit log --since="1 week ago"restituisce quasi nulla. È il modo più comune di ottenere un report vuoto senza capire perché.
E ricorda il vincolo di GitHub: i workflow schedulati girano solo dal branch di default, e nei repository pubblici lo schedule si disattiva dopo 60 giorni di inattività.
Errori comuni e troubleshooting
Sezione intitolata “Errori comuni e troubleshooting”| Sintomo | Causa | Soluzione |
|---|---|---|
| In CI il risultato non è riproducibile | -p carica hook, MCP e CLAUDE.md del repository |
--bare |
| Un job in CI esegue codice di una PR da un fork | Senza --bare, gli hook del repo girano |
--bare è obbligatorio sul codice non tuo |
| Il job si blocca aspettando un permesso | In CI nessuno può approvare | --allowedTools o --permission-mode dontAsk |
git log --since non restituisce nulla in CI |
actions/checkout fa un clone shallow (senza storia) |
fetch-depth: 0 |
| Il ciclo batch riparte da capo dopo un errore | Nessuna idempotenza | Marca i file già fatti e salta |
| Un batch consuma token all’infinito | Nessun limite di turni | --max-turns per ogni invocazione |
| Il workflow schedulato non parte | GitHub li esegue solo dal branch di default | Assicurati che il file sia su main |
| Lo schedule si è disattivato da solo | Nei repo pubblici, dopo 60 giorni di inattività | Riattivalo dalla UI di GitHub |
@claude non risponde |
App non installata, secret mancante, o l’utente non ha accesso in scrittura | Verifica i tre in quest’ordine |
| Un run schedulato viene rifiutato | GitHub attribuisce i run schedulati a un utente, e i bot vengono rifiutati | Aggiungi quell’attore ad allowed_bots |
| La CI non parte sui commit di Claude | GitHub non innesca workflow sui commit fatti con il GITHUB_TOKEN di default |
Non passare github_token: ${{ secrets.GITHUB_TOKEN }} all’action |
| Il token OAuth non funziona per i colleghi | È legato all’abbonamento di chi l’ha generato | Per un’organizzazione, usa una API key dalla Console |
| Errori di autenticazione nel workflow | Il token non è valido | Provalo prima in locale con claude |
Cheat-sheet
Sezione intitolata “Cheat-sheet”Composizione
comando | claude -p "prompt" # dati in ingresso, niente permessi necessariclaude -p "prompt" | comando # risultato verso altroclaude -p "prompt" --output-format json | jq -r '.result'Batch
# Fan-out sequenzialefor f in $(cat files.txt); do claude -p "..." --allowedTools "Edit"; done
# Fan-out paralleloxargs -a files.txt -P 4 -I{} bash -c 'claude -p "... {}" --allowedTools "Edit"'CI
| Passo | Comando |
|---|---|
| Generare il token | claude setup-token |
| Metterlo nei secret | gh secret set CLAUDE_CODE_OAUTH_TOKEN |
| Installare in CI | curl -fsSL https://claude.ai/install.sh | bash |
| Setup della Action ufficiale | /install-github-app da dentro Claude Code |
| Provare un workflow a mano | gh workflow run <file>.yml |
Il workflow minimo
- uses: actions/checkout@v6- uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}Permessi necessari: contents: write, pull-requests: write, issues: write, id-token: write,
actions: read.
Regole d’oro
1. Ciò che un comando deterministico può fare, lo fa un comando deterministico2. --bare in CI, sempre3. --max-turns su ogni invocazione non sorvegliata4. La pipe in ingresso evita di dare permessi Bash5. Batch idempotente, con log per file e lista di retryPagine ufficiali consultate, verificate il 16 agosto 2026:
- Run Claude Code programmatically — pipe, bare mode, script di build, permessi
- Best practices — fan-out sui file e modalità non interattiva
- Claude Code GitHub Actions — setup, workflow, modalità,
claude_args, chi può innescare i run - GitLab CI/CD — l’equivalente per GitLab
- Authentication —
claude setup-tokene i limiti del token - CLI reference — flag usati negli script
- Code review — review automatica senza mantenere un workflow
Corso indipendente, non affiliato ad Anthropic o Google. Claude e Claude Code sono marchi di Anthropic; Antigravity e Gemini sono marchi di Google.