Se stai costruendo pipeline CI/CD con GitLab, probabilmente ti sei chiesto come far eseguire i job in un ordine specifico. Magari vuoi che i test vengano eseguiti prima del build, o che il deploy in produzione avvenga solo dopo aver superato tutti i controlli di qualità.
In questa guida completa sulle dipendenze tra job GitLab CI/CD scoprirai tutto quello che c’è da sapere: cos’è la keyword needs, come funziona, quando usarla e come costruire pipeline complesse ma efficienti. Che tu stia gestendo un piccolo progetto o un’infrastruttura enterprise, questa guida ti aiuterà a ottimizzare i tempi di esecuzione delle tue pipeline.
Cos’è una Dipendenza tra Job in GitLab CI/CD
Immagina di dover preparare una cena: non puoi servire il piatto prima di averlo cucinato, e non puoi cuocerlo prima di aver comprato gli ingredienti. Esiste un ordine logico che deve essere rispettato.
Lo stesso vale per le pipeline CI/CD. Una dipendenza tra job è semplicemente una regola che dice: “questo job può partire solo quando quest’altro job è completato con successo”.
Il Problema delle Pipeline Sequenziali Tradizionali
Per impostazione predefinita, GitLab CI/CD organizza i job in stage (fasi) che vengono eseguiti in sequenza:
stages:
- test
- build
- deploy
test_job:
stage: test
script:
- npm test
build_job:
stage: build
script:
- npm run build
deploy_job:
stage: deploy
script:
- npm run deploy
Come funziona questo approccio:
- Tutti i job dello stage
testvengono eseguiti in parallelo - Solo quando tutti i job di
testfiniscono, parte lo stagebuild - Solo quando tutti i job di
buildfiniscono, parte lo stagedeploy
Il problema: Se hai 10 job di test che durano 1 minuto ciascuno, ma uno solo dura 10 minuti, gli altri 9 job devono aspettare inutilmente prima che inizi lo stage successivo!
La Soluzione: La Keyword needs
La keyword needs ti permette di creare dipendenze esplicite tra job specifici, ignorando completamente gli stage. Questo significa:
- Job indipendenti partono subito in parallelo
- Job dipendenti partono appena i loro prerequisiti finiscono
- Nessuna attesa inutile
- Pipeline più veloci
Esempio pratico:
build_frontend:
script:
- npm run build
deploy_frontend:
needs: [build_frontend]
script:
- deploy frontend
In questo caso, deploy_frontend parte immediatamente dopo che build_frontend finisce, senza aspettare altri job dello stesso stage!
Come Funziona la Keyword needs in GitLab CI/CD
Vediamo nel dettaglio come usare needs per creare dipendenze tra job.
Sintassi Base della Keyword needs
La sintassi più semplice è questa:
nome_job:
needs: [job_prerequisito]
script:
- echo "Questo job parte dopo job_prerequisito"
Caratteristiche fondamentali:
needsaccetta una lista di nomi di job- Il job parte solo quando tutti i job nella lista sono completati con successo
- Se un job prerequisito fallisce, il job dipendente viene automaticamente cancellato
- Puoi specificare più job nella lista
Esempio Pratico: Pipeline di Test e Build
Creiamo una pipeline realistica per un’applicazione web:
stages:
- test
- build
- deploy
# Test unitari veloci (2 minuti)
unit_tests:
stage: test
script:
- npm run test:unit
# Test di integrazione lenti (10 minuti)
integration_tests:
stage: test
script:
- npm run test:integration
# Test end-to-end molto lenti (15 minuti)
e2e_tests:
stage: test
script:
- npm run test:e2e
# Build del frontend - dipende solo dai test unitari
build_frontend:
stage: build
needs: [unit_tests]
script:
- npm run build:frontend
- echo "Frontend pronto dopo soli 2 minuti!"
# Build del backend - dipende dai test unitari e di integrazione
build_backend:
stage: build
needs: [unit_tests, integration_tests]
script:
- npm run build:backend
- echo "Backend pronto dopo 10 minuti"
# Deploy - dipende da entrambi i build
deploy_production:
stage: deploy
needs: [build_frontend, build_backend]
script:
- deploy production
Vantaggi di questa configurazione:
- Il frontend può essere buildato dopo soli 2 minuti (non aspetta i test E2E)
- Il backend parte dopo 10 minuti (non aspetta i test E2E)
- Il deploy parte appena entrambi i build finiscono
- I test E2E continuano in parallelo per validazione completa
Senza needs: La pipeline durerebbe almeno 15 minuti (aspettando tutti i test)
Con needs: La pipeline può completare in ~12 minuti, risparmiando tempo prezioso!
Dipendenze Multiple: Quando un Job Dipende da Più Job
Puoi specificare più job come prerequisiti. Il job dipendente parte solo quando tutti i prerequisiti sono completati.
# Questi job sono indipendenti e partono in parallelo
lint_code:
script:
- npm run lint
security_scan:
script:
- npm audit
unit_tests:
script:
- npm test
# Questo job parte solo quando tutti e tre i precedenti finiscono
build_app:
needs: [lint_code, security_scan, unit_tests]
script:
- npm run build
- echo "Build avviato solo dopo validazione completa"
Rappresentazione visiva del flusso:
[lint_code] ─┐
│
[security] ─┼──> [build_app] ──> [deploy]
│
[unit_tests] ─┘
Tutti e tre i job di validazione vengono eseguiti in parallelo, e build_app parte non appena tutti e tre sono completati con successo.
needs vs stage: Differenze Fondamentali
Capire la differenza tra needs e stage è cruciale per costruire pipeline efficienti.
Come Funzionano gli Stage Tradizionali
Gli stage creano una dipendenza implicita: ogni stage attende il completamento di tutti i job dello stage precedente.
stages:
- test
- build
test_fast: # Dura 1 minuto
stage: test
script: fast test
test_slow: # Dura 20 minuti
stage: test
script: slow test
build:
stage: build
script: build app
Timeline di esecuzione:
Minuto 0: [test_fast] [test_slow] ──┐
│ (Aspetta 20 minuti)
Minuto 1: [test_fast completato] │
Minuto 20: [test_slow completato] │
↓
Minuto 20: [build] inizia
Il job build deve aspettare 20 minuti anche se test_fast finisce dopo 1 minuto!
Come Funziona needs per Ottimizzare il Flusso
Con needs, puoi creare dipendenze esplicite ignorando gli stage:
stages:
- test
- build
test_fast:
stage: test
script: fast test
test_slow:
stage: test
script: slow test
build:
stage: build
needs: [test_fast] # Dipende SOLO da test_fast
script: build app
Timeline di esecuzione migliorata:
Minuto 0: [test_fast] [test_slow] ──┐
│ │
Minuto 1: └──> [build] │ (Continua in parallelo)
│
Minuto 20: [test_slow completato] ─┘
Il job build parte dopo solo 1 minuto, risparmiando 19 minuti di attesa!
Tabella Comparativa: stage vs needs
| Caratteristica | stage | needs |
|---|---|---|
| Dipendenza | Implicita da tutti i job dello stage precedente | Esplicita solo dai job specificati |
| Esecuzione parallela | Limitata agli stage | Massima tra job indipendenti |
| Flessibilità | Bassa (struttura rigida) | Alta (dipendenze granulari) |
| Tempo di esecuzione | Più lungo (attese inutili) | Ottimizzato (zero attese inutili) |
| Complessità configurazione | Bassa (semplice) | Media (più controllo) |
| Quando usarlo | Pipeline semplici e lineari | Pipeline complesse con ottimizzazione |
needs con artifacts: Condividere File tra Job
Una delle funzionalità più potenti di needs è la possibilità di condividere file (artifacts) tra job dipendenti.
Come Funzionano gli Artifacts con needs
Sintassi completa:
job_che_usa_artifacts:
needs:
- job: job_che_genera_artifacts
artifacts: true # Scarica gli artifacts
script:
- ls artifacts/
Cosa succede:
- Il job
job_che_genera_artifactsesegue e crea artifacts - GitLab salva gli artifacts nello storage
- Il job
job_che_usa_artifactsparte quando il prerequisito finisce - GitLab scarica automaticamente gli artifacts prima di eseguire lo script
- I file sono disponibili nella working directory del job
Esempio Pratico: Build, Test, Deploy con Artifacts
# Compila l'applicazione e salva il risultato
compile:
script:
- gcc -o myapp main.c
artifacts:
paths:
- myapp
expire_in: 1 day
# Test che usa l'eseguibile compilato
test_executable:
needs:
- job: compile
artifacts: true
script:
- ./myapp --test
- echo "Test passed!"
# Package che crea un archivio dell'eseguibile
package:
needs:
- job: compile
artifacts: true
- test_executable # Non serve artifacts da questo
script:
- tar -czf release.tar.gz myapp README.md
artifacts:
paths:
- release.tar.gz
# Deploy che usa il package
deploy:
needs:
- job: package
artifacts: true
script:
- scp release.tar.gz server:/releases/
- ssh server "cd /releases && tar -xzf release.tar.gz"
Ottimizzare l’Uso degli Artifacts: artifacts: false
A volte non hai bisogno degli artifacts dal job prerequisito, ma vuoi comunque aspettare che finisca. Usa artifacts: false per risparmiare tempo e bandwidth:
test_unit:
script:
- npm test
artifacts:
paths:
- coverage/ # Genera report di copertura
deploy:
needs:
- job: test_unit
artifacts: false # Non scarica i report di copertura
script:
- deploy to production
Quando usare artifacts: false:
- Il job dipendente non ha bisogno dei file generati
- Gli artifacts sono grandi e rallenterebbero il download
- Vuoi solo aspettare il completamento del job prerequisito
Artifacts di Lunga Durata vs Temporanei
GitLab ti permette di controllare quanto tempo conservare gli artifacts:
build:
script:
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 week # Conserva per 1 settimana
build_release:
script:
- npm run build:production
artifacts:
paths:
- release/
expire_in: never # Conserva per sempre
Best practice per expire_in:
- Build temporanei:
1 houro1 day - Release candidate:
1 weeko1 month - Release ufficiali:
never(o molti mesi)
Questo aiuta a risparmiare storage e mantenere il sistema pulito!
Gestione degli Errori e Fallback con needs
Cosa succede quando un job prerequisito fallisce? Vediamo come gestire questi scenari.
Comportamento Predefinito: Cancellazione Automatica
Quando un job specificato in needs fallisce, tutti i job dipendenti vengono automaticamente cancellati:
test:
script:
- npm test # FALLISCE!
build:
needs: [test]
script:
- npm run build # NON VIENE ESEGUITO
deploy:
needs: [build]
script:
- deploy # NON VIENE ESEGUITO
Risultato: Se test fallisce, sia build che deploy vengono cancellati automaticamente. Questo previene deploy di codice non testato!
Keyword allow_failure: Continuare Anche con Errori
A volte vuoi che la pipeline continui anche se un job non critico fallisce:
test_unit:
script:
- npm run test:unit
test_experimental:
script:
- npm run test:experimental
allow_failure: true # Non blocca la pipeline se fallisce
build:
needs:
- test_unit # Deve passare
- test_experimental # Può fallire
script:
- npm run build
Cosa succede:
- Se
test_unitfallisce →buildviene cancellato - Se
test_experimentalfallisce →buildcontinua normalmente - Se entrambi passano →
buildcontinua normalmente
Keyword when: Eseguire Job in Scenari Specifici
La keyword when controlla quando eseguire un job in base al risultato dei prerequisiti:
test:
script:
- npm test
# Eseguito solo se test ha successo (default)
deploy_success:
needs: [test]
when: on_success
script:
- deploy to production
# Eseguito solo se test fallisce
cleanup_failed:
needs: [test]
when: on_failure
script:
- send alert
- cleanup resources
# Eseguito sempre, indipendentemente dal risultato
notify_team:
needs: [test]
when: always
script:
- send notification to Slack
Valori possibili per when:
on_success(default) - Esegui solo se i prerequisiti hanno successoon_failure- Esegui solo se almeno un prerequisito falliscealways- Esegui sempre, indipendentemente dal risultatomanual- Richiede approvazione manualedelayed- Esegui dopo un ritardo specificato
Pattern: Retry Automatico su Fallimento
Combina retry con needs per gestire fallimenti temporanei:
deploy_to_server:
needs: [build]
script:
- deploy to production
retry:
max: 3
when:
- runner_system_failure
- stuck_or_timeout_failure
Questo job verrà ritentato fino a 3 volte se fallisce per problemi infrastrutturali!
Pattern: Rollback Automatico
Crea un job di rollback che parte solo se il deploy fallisce:
deploy:
needs: [build]
script:
- deploy to production
rollback:
needs: [deploy]
when: on_failure
script:
- rollback to previous version
- send alert
Se deploy fallisce, rollback parte automaticamente per ripristinare la versione precedente!
Se deploy fallisce, rollback parte automaticamente per ripristinare la versione precedente!
Link Utili e Risorse
Documentazione Ufficiale GitLab
GitLab CI/CD - Keyword needs:
- Documentazione needs - Riferimento completo alla keyword needs
- Job dependencies - Guida alle dipendenze tra job
- Pipeline DAG - Directed Acyclic Graph in GitLab CI/CD
Artifacts e Trasferimento Dati:
- Job artifacts - Come gestire gli artifacts
- Keyword artifacts - Riferimento completo alla keyword artifacts
Pipeline Configuration:
- GitLab CI/CD YAML reference - Riferimento completo del file .gitlab-ci.yml
- Pipeline efficiency - Ottimizzare le pipeline GitLab
Guide Correlate
Tutorial GitLab CI/CD su CloudOpsItalia:
Tool Utili per GitLab CI/CD
Validazione e Testing:
- GitLab CI Lint - Validatore online per file .gitlab-ci.yml
- Pipeline Editor - Editor integrato con validazione