GitHub Actions : Pourquoi « needs » et « if » ne font pas la même chose ?

GitHub Actions : Pourquoi « needs » et « if » ne font pas la même chose ?

> gh workflow --debug dependencies_

needs vs if : Maîtriser le flux GitHub Actions

Par Nicolas DELAHAYE | Coach DevSecOps

STATUS: PIPELINE_LOGIC_ANALYSIS


Imaginez un chantier où le peintre commence à peindre les murs alors que les maçons n'ont pas encore fini de monter la brique. C'est exactement ce qui arrive dans vos pipelines GitHub Actions quand la logique de dépendance est floue.

Le problème est classique : on veut qu'un job ne s'exécute pas tant qu'un autre n'est pas terminé. Intuitivement, on cherche une condition. On hésite entre forcer un ordre (needs) ou vérifier une validation (if).

Pourtant, ces deux attributs ne jouent pas dans la même cour. L'un construit le squelette de votre CI/CD, l'autre en est le garde-fou. Si vous les confondez, vous créez des pipelines "magiques" ou instables où les données ne circulent pas et où les échecs ne sont pas correctement interceptés.

Avant de toucher au YAML, retenez cette distinction fondamentale :

  • needs = Dépendance Structurelle : Définit l'ordonnancement du graphe (le "Quand").
  • if = Condition Logique : Définit l'autorisation d'exécuter (le "Si").
"Needs définit l'ordre, If décide du droit de passage."

needs agit au niveau du scheduler de GitHub Actions. C'est lui qui dessine les boîtes et les flèches dans votre interface visuelle.

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - run: echo "Compilation terminée"

  test:
    needs: build # Dépendance explicite
    runs-on: ubuntu-latest
    steps:
      - run: echo "Exécution des tests"
      

Pourquoi l'utiliser ?

  • Chaînage : Pour accéder aux outputs du job précédent (impossible sans needs !).
  • Sécurité : Si le job build échoue, le job test est automatiquement annulé (skippé).

if intervient au moment de l'exécution. Le job est planifié, mais avant de démarrer, l'exécuteur vérifie la condition.

jobs:
  deploy:
    runs-on: ubuntu-latest
    # Condition basée sur le contexte, pas sur un autre job
    if: github.ref == 'refs/heads/main'
    steps:
      - run: echo "Déploiement en Prod"
      

Exemple de contexte métier :

Utilisez if: failure() pour envoyer une notification Slack uniquement si le pipeline plante.

Critère needs if
Niveau Structure du pipeline Logique d'exécution
Ordonnancement Oui (Graphe) Non
Accès aux outputs Oui Non
Usage principal Étapes logiques Règles métier / Branches

⚡ LE MANTRA À GRAVER DANS LE MARBRE :

  • 👉 Si un job dépend d’un autre (ordre) → utilisez needs
  • 👉 Si un job dépend d’un contexte (branche, tag, event) → utilisez if

Dans un environnement industriel, on ne choisit pas l'un contre l'autre. On les combine :

  deploy-prod:
    needs: [test, security-scan]        # ORDRE : J'attends que les tests soient verts
    if: github.ref == 'refs/heads/main' # CONTEXTE : Je ne déploie que si je suis sur Main
    runs-on: ubuntu-latest
    steps:
      - run: ./deploy.sh
      

C'est le modèle recommandé : needs garantit l'intégrité structurelle (le "quand"), et if garantit la conformité logique (le "pourquoi").

Au-delà de la syntaxe YAML, comprendre cette différence relève de la culture Craftsmanship.

  • 🛡️ Lisibilité : Un pipeline avec des needs bien placés est auto-documenté.
  • 🛡️ Intention : Ne cachez pas une dépendance derrière un if complexe. Rendez-la explicite.
  • 🛡️ Robustesse : Un pipeline "plat" (sans needs) est un risque de sécurité : vos jobs pourraient s'exécuter en parallèle et déployer un code non testé.

Besoin d'aller plus loin ? Dans un prochain article, nous aborderons les Anti-patterns GitHub Actions pour éviter les pièges du copier-coller StackOverflow.

[ EOF - Workflow Logic Validated ]