Chaque workflow GitHub Actions que vous avez écrit est un fichier YAML. Tout — les déclencheurs, les jobs, les étapes, les variables d'environnement, la stratégie matrix — est exprimé en YAML. Ce qui signifie que comprendre YAML en profondeur n'est pas seulement académique : c'est la différence entre une CI qui fonctionne de manière fiable et une CI qui plante mystérieusement à 16h un vendredi quand vous essayez de livrer une release.

GitHub Actions dispose d'excellentes docs sur la syntaxe des workflows, mais elles se concentrent sur les fonctionnalités Actions plutôt que sur les mécaniques YAML sous-jacentes. Cet article couvre les deux — la structure du workflow, et les schémas YAML spécifiques (et les pièges) qui font ou défont les configurations CI.

Structure du workflow : les clés de niveau supérieur

Un fichier de workflow GitHub Actions réside dans .github/workflows/ et possède trois clés obligatoires de niveau supérieur. La vue d'ensemble officielle des workflows explique où le fichier se trouve dans votre dépôt et comment GitHub le découvre :

yaml
name: CI Pipeline          # optional but shown in the Actions UI

on:                        # triggers
  push:
    branches: [main]
  pull_request:

jobs:                      # the actual work
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm test
Attention à on comme booléen YAML : En YAML 1.1, le mot nu on est interprété comme le booléen true. Le parseur de GitHub gère cela correctement, mais si vous voyez jamais votre fichier de workflow signalé par un linter YAML générique, c'est pourquoi. La forme sûre est de le mettre entre guillemets : "on": — bien que GitHub Actions lui-même n'exige pas les guillemets.

Déclencheurs : la clé on:

La clé on: contrôle quand votre workflow s'exécute. La liste complète des événements déclencheurs couvre tout, des revues de pull requests aux dispatches de dépôt. Voici les schémas les plus courants :

yaml
on:
  # Push to specific branches
  push:
    branches:
      - main
      - "release/**"       # glob pattern — quotes needed for /**
    paths-ignore:
      - "docs/**"
      - "*.md"

  # PRs targeting main
  pull_request:
    branches: [main]
    types: [opened, synchronize, reopened]

  # Scheduled (cron syntax)
  schedule:
    - cron: "0 2 * * 1"   # every Monday at 2am UTC

  # Manual trigger with input
  workflow_dispatch:
    inputs:
      environment:
        description: "Target environment"
        required: true
        default: staging
        type: choice
        options: [staging, production]

Commandes run: multi-lignes et blocs scalaires YAML

La clé run: est là où le bloc scalaire littéral de YAML (|) prouve sa valeur — consultez la référence yaml-multiline.info pour toutes les variations de blocs et scalaires pliés. Sans lui, vous enchaîneriez les commandes avec && sur une seule ligne, ce qui est illisible :

yaml
steps:
  # Single line — works but hard to read
  - name: Build
    run: npm ci && npm run lint && npm run test && npm run build

  # Multi-line with literal block scalar — much better
  - name: Build
    run: |
      npm ci
      npm run lint
      npm run test -- --coverage
      npm run build

  # Folded scalar (>) joins lines with spaces — NOT what you want for shell
  # This would run as a single command with spaces where the newlines are:
  - name: Wrong for shell
    run: >
      npm ci
      npm test
Utilisez toujours | pour les scripts shell multi-lignes, jamais >. Le scalaire plié replie les sauts de ligne en espaces, ce qui signifie que vos commandes shell sont jointes en une longue chaîne. Cela provoque des erreurs cryptiques. Le bloc scalaire littéral | préserve exactement les sauts de ligne, donc chaque ligne s'exécute comme une commande shell séparée.

Variables d'environnement et secrets

Les variables d'environnement dans GitHub Actions utilisent YAML en combinaison avec le contexte Actions et la syntaxe d'expression. Voici comment ils s'articulent :

yaml
env:
  NODE_ENV: production         # workflow-level env var
  API_VERSION: "2.1"          # quoted to force string type

jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      DEPLOY_ENV: staging      # job-level env var (overrides workflow-level)

    steps:
      - name: Deploy to staging
        env:
          API_KEY: ${{ secrets.STAGING_API_KEY }}     # step-level, from secret
          DATABASE_URL: ${{ vars.STAGING_DB_URL }}    # step-level, from variable
        run: |
          echo "Deploying to $DEPLOY_ENV"
          ./scripts/deploy.sh

La syntaxe d'expression ${{ }} est le propre langage de template de GitHub Actions superposé sur YAML. Elle est évaluée avant l'analyse YAML dans certains contextes, ce qui peut interagir de manière inattendue avec les propres règles de guillemets de YAML. En cas de doute, encadrez les valeurs qui commencent par ${{ de guillemets doubles.

Stratégie matrix : construire sur plusieurs configurations

La stratégie matrix est l'une des fonctionnalités les plus puissantes de GitHub Actions — et elle est exprimée entièrement en YAML. Elle exécute votre job une fois pour chaque combinaison de valeurs matrix :

yaml
jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false         # don't cancel other matrix jobs on failure
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node: ["18", "20", "22"]
        exclude:
          - os: windows-latest
            node: "18"         # skip this combination

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: npm ci && npm test

Cette seule définition de job produit jusqu'à 9 exécutions parallèles (3 OS × 3 versions Node, moins 1 exclue). Les valeurs matrix YAML sont de simples tableaux — la seule chose à surveiller est que les numéros de version comme 18 doivent être entre guillemets comme "18" pour rester des chaînes. Sans guillemets, YAML les analyse comme des entiers et certaines Actions peuvent se plaindre.

Étapes conditionnelles avec if:

La clé if: vous permet de sauter des étapes selon des conditions. Elle utilise le langage d'expression de GitHub, pas des valeurs YAML simples :

yaml
steps:
  - name: Run tests
    run: npm test

  - name: Upload coverage
    if: success() && github.ref == 'refs/heads/main'
    uses: codecov/codecov-action@v4

  - name: Notify on failure
    if: failure()
    uses: slackapi/slack-github-action@v1
    with:
      slack-message: "Build failed on ${{ github.ref }}"
      channel-id: "C12345ABC"
    env:
      SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}

  - name: Deploy (only on tag push)
    if: startsWith(github.ref, 'refs/tags/v')
    run: ./scripts/deploy.sh production

Workflows réutilisables

Pour éliminer les doublons entre dépôts (pas seulement au sein d'un fichier), GitHub Actions supporte les workflows réutilisables. Le workflow appelé utilise on: workflow_call: et l'appelant utilise uses: au niveau du job — pas au niveau de l'étape :

yaml
# .github/workflows/reusable-test.yml (the reusable workflow)
on:
  workflow_call:
    inputs:
      node-version:
        required: false
        type: string
        default: "20"
    secrets:
      NPM_TOKEN:
        required: true

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
      - run: npm ci && npm test
        env:
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
yaml
# .github/workflows/ci.yml (the caller)
on: [push, pull_request]

jobs:
  run-tests:
    uses: my-org/shared-workflows/.github/workflows/reusable-test.yml@main
    with:
      node-version: "22"
    secrets:
      NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Les erreurs YAML les plus courantes dans GitHub Actions

  • Mauvaise indentation des étapes. Les étapes doivent être indentées sous steps: avec des espaces cohérents. Un espace en trop ou en moins sort une étape de son job.
  • Numéros de version non quotés. node-version: 20 passe un entier ; certaines actions attendent une chaîne. Utilisez node-version: "20" par sécurité.
  • Utiliser > au lieu de | pour les scripts shell. Les scalaires pliés suppriment les sauts de ligne. Votre script multi-ligne devient une longue chaîne et échoue.
  • Guillemets manquants sur les motifs glob. Des motifs comme release/** contiennent * que YAML peut interpréter comme un alias. Mettez toujours les motifs glob entre guillemets.
  • Secrets utilisés dans les conditions if:. GitHub masque les secrets dans les journaux mais ne les autorise pas dans les expressions if:. Utilisez plutôt une variable d'environnement.
  • Oubli de fail-fast: false dans les jobs matrix. Par défaut, si un job matrix échoue, tous les autres sont annulés. Ce n'est généralement pas ce que vous voulez lors du débogage.

Conclusion

Les workflows GitHub Actions sont fondamentalement des fichiers YAML — comprendre les blocs scalaires littéraux de YAML, les règles de guillemets et la coercition de types se traduit directement par une CI plus fiable. Les échecs les plus courants viennent des erreurs d'indentation, des valeurs non quotées qui se coercent vers le mauvais type, et de l'utilisation du mauvais opérateur de chaîne multi-ligne pour les scripts shell. Maîtrisez ces trois points et la plupart du débogage de workflows devient simple. Utilisez le Validateur YAML pour détecter les erreurs de syntaxe avant de pousser, et le Formateur YAML pour imposer une indentation cohérente dans vos fichiers de workflow.