// GitHub & Git

GitHub Actions : automatiser ses workflows (CI/CD)

Tester son code, le construire, le déployer : ces tâches répétitives sont exactement celles qu’on veut automatiser. GitHub Actions est l’outil intégré à GitHub pour ça. À chaque push, chaque pull request ou selon un calendrier, il exécute des workflows définis dans votre dépôt. Ce guide explique les concepts, la syntaxe YAML, et construit un pipeline complet build + test + déploiement que vous pourrez adapter.

À quoi sert GitHub Actions

GitHub Actions permet de faire de l’intégration continue (CI) et du déploiement continu (CD). Concrètement :

  • CI : à chaque modification, on lance automatiquement les tests et le build pour vérifier que rien n’est cassé.
  • CD : quand tout passe au vert, on déploie automatiquement la nouvelle version.

L’intérêt : on détecte les régressions tôt, on évite les déploiements manuels source d’erreurs, et chaque contributeur reçoit un retour immédiat sur son code.

Le vocabulaire à connaître

Quatre concepts structurent tout GitHub Actions. Les confondre est la première source d’erreurs, alors posons-les clairement.

ConceptRôle
WorkflowLe processus complet, décrit dans un fichier YAML. Un dépôt peut en avoir plusieurs.
JobUn ensemble d’étapes qui s’exécutent sur une même machine. Les jobs tournent en parallèle par défaut.
StepUne étape individuelle : une commande shell ou une action réutilisable.
RunnerLa machine (fournie par GitHub ou auto-hébergée) qui exécute un job.

Une action (avec un « a » minuscule) est un composant réutilisable publié par la communauté ou par GitHub, qu’on appelle avec le mot-clé uses. Par exemple actions/checkout récupère votre code sur le runner.

Où placer le fichier

Les workflows vivent dans le dossier .github/workflows/ à la racine du dépôt. Chaque fichier .yml y est un workflow indépendant.

.github/
└── workflows/
    ├── ci.yml
    └── deploy.yml

Anatomie d’un workflow minimal

Voici le plus petit workflow utile : à chaque push, il récupère le code et affiche un message.

name: Premier workflow

on: push

jobs:
  bonjour:
    runs-on: ubuntu-latest
    steps:
      - name: Récupérer le code
        uses: actions/checkout@v4
      - name: Dire bonjour
        run: echo "Le workflow tourne !"

Décomposons :

  • name : le nom affiché dans l’onglet Actions.
  • on : le déclencheur (ici, tout push).
  • jobs : la liste des jobs ; bonjour est un identifiant libre.
  • runs-on : le type de runner (ubuntu-latest, windows-latest, macos-latest).
  • steps : les étapes. uses appelle une action, run exécute une commande shell.

Les déclencheurs (triggers)

Le mot-clé on définit quand le workflow s’exécute. Les plus courants :

on:
  push:
    branches: [main]          # uniquement sur main
  pull_request:
    branches: [main]          # sur les PR visant main
  schedule:
    - cron: '0 6 * * 1'       # tous les lundis à 6h UTC
  workflow_dispatch:          # déclenchement manuel via l'interface

workflow_dispatch est particulièrement pratique : il ajoute un bouton « Run workflow » dans l’onglet Actions, utile pour les déploiements à la demande.

Un pipeline concret : build, test, déploiement

Assemblons maintenant un workflow réaliste pour un projet Node.js. Il installe les dépendances, lance les tests, construit le projet, puis déploie — mais seulement si le tout réussit et si on est sur main.

name: CI/CD

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

jobs:
  build-et-test:
    runs-on: ubuntu-latest
    steps:
      - name: Récupérer le code
        uses: actions/checkout@v4

      - name: Installer Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Installer les dépendances
        run: npm ci

      - name: Lancer les tests
        run: npm test

      - name: Construire le projet
        run: npm run build

  deploiement:
    needs: build-et-test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - name: Récupérer le code
        uses: actions/checkout@v4

      - name: Déployer
        run: echo "Déploiement en cours..."
        env:
          API_TOKEN: ${{ secrets.API_TOKEN }}

Deux mots-clés méritent attention :

  • needs: build-et-test rend le job deploiement dépendant du succès du premier. Sans lui, les deux tourneraient en parallèle.
  • if: github.ref == 'refs/heads/main' limite le déploiement à la branche main. Une pull request lance les tests mais ne déploie pas.

Bonne pratique — Utilisez npm ci plutôt que npm install dans un pipeline. Cette commande installe exactement les versions du package-lock.json, garantissant des builds reproductibles.

Les secrets : ne jamais coder ses clés en dur

Un déploiement a souvent besoin de tokens, mots de passe ou clés d’API. On ne les écrit jamais dans le fichier YAML, qui est versionné et visible. GitHub fournit un coffre : Settings > Secrets and variables > Actions.

On y ajoute un secret, par exemple API_TOKEN, puis on le référence dans le workflow :

env:
  API_TOKEN: ${{ secrets.API_TOKEN }}

La valeur est chiffrée et masquée dans les logs. Ce même mécanisme protège vos identifiants de déploiement, vos clés Cloudflare ou vos tokens de registre Docker.

La matrice : tester sur plusieurs versions

Besoin de valider votre code sur plusieurs versions de Node.js ou plusieurs OS ? La stratégie de matrice génère automatiquement une combinaison de jobs.

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        node: [18, 20, 22]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: npm ci && npm test

Ce bloc lance six jobs (2 OS × 3 versions) en parallèle. Idéal pour les bibliothèques qui doivent fonctionner partout.

Bonnes pratiques

Quelques réflexes qui font la différence entre un pipeline fragile et un pipeline fiable :

  • Épinglez les versions d’actions (actions/checkout@v4) plutôt que d’utiliser une branche mouvante, pour éviter les surprises.
  • Activez le cache (cache: 'npm') pour accélérer les runs et économiser du temps de calcul.
  • Découpez les responsabilités : un workflow de CI léger sur les PR, un workflow de déploiement séparé sur main.
  • Utilisez workflow_dispatch pour garder un déclenchement manuel de secours.
  • Limitez les permissions du GITHUB_TOKEN avec le bloc permissions au strict nécessaire.

Aller plus loin

GitHub Actions ne sert pas qu’au code applicatif : on l’emploie pour publier sur GitHub Pages, générer des releases, lint la documentation, ou envoyer des notifications. Le principe reste toujours le même — un événement déclenche un workflow, qui enchaîne des jobs sur des runners.

Le meilleur apprentissage reste l’itération : commencez par un workflow qui ne fait que lancer vos tests, vérifiez qu’il passe au vert, puis ajoutez le build, puis le déploiement. Chaque brique validée avant de passer à la suivante vous évitera de déboguer un pipeline entier d’un coup.

À lire ensuite