Développement Web

Créer son premier workflow GitHub Actions

14 min de lecture

Vous poussez un commit, et trois minutes plus tard un petit rond vert apparaît à côté de votre branche. Ce rond vert, c’est GitHub qui vient de récupérer votre code, d’installer vos dépendances et de vérifier que rien n’est cassé — sans que vous ayez touché à votre terminal. C’est ça, un workflow GitHub Actions : une suite d’instructions que GitHub exécute pour vous à chaque événement sur votre dépôt. Dans ce tutoriel, vous écrivez le vôtre, de la première ligne de YAML jusqu’au premier rond vert.

📍 Article principal de la série : GitHub Actions : le guide CI/CD pour bien démarrer
Ce tutoriel fait partie de la série « CI/CD avec GitHub Actions ». Pour la vue d’ensemble des concepts et le parcours complet, lisez d’abord le guide principal.

🎯 Ce que vous allez apprendre

  • Reconnaître les cinq briques d’un workflow : événement, job, step, runner, action — et savoir laquelle fait quoi.
  • Écrire un fichier .github/workflows/ci.yml valide qui se déclenche tout seul à chaque git push.
  • Lire les journaux d’exécution dans l’onglet Actions pour comprendre pourquoi un job passe ou échoue.
  • Déclencher un workflow sur plusieurs événements (push, pull request, lancement manuel) en choisissant le bon.
  • Afficher un badge de statut dans votre README pour montrer que le projet est sous intégration continue.

🛠️ Ce que vous allez construire

Notre fil rouge pour toute la série est Récolte, une petite API REST en Node.js qui enregistre les livraisons d’une coopérative agricole (un producteur, un produit, une quantité en kilos, un prix). Ici, on ne code pas encore l’API : on lui pose son premier garde-fou automatique. À la fin, chaque commit poussé sur GitHub déclenchera un job qui récupère le code, installe Node 24, restaure les dépendances et lance une vérification. Vous obtiendrez votre premier rond vert et un badge CI passing à afficher fièrement.

Prérequis

  • Un compte GitHub (gratuit) et un dépôt — public de préférence : sur un dépôt public, les minutes d’exécution sont illimitées et gratuites.
  • Node.js 24 installé en local pour créer le projet (vérifiez avec node --version).
  • Git configuré et la base de ses commandes : clone, add, commit, push.
  • Test express : si vous savez créer un dépôt, y pousser un package.json et lancer npm install, vous êtes prêt. Sinon, parcourez d’abord notre guide Git & GitHub.
  • ⏱️ Temps estimé : ~35 minutes.

Étape 1 — Le modèle mental : événement → job → step

Avant d’écrire la moindre ligne, il faut une image claire de ce qui se passe. GitHub Actions repose sur une cascade simple. Un événement se produit sur votre dépôt (un push, l’ouverture d’une pull request, une heure programmée). Cet événement déclenche un ou plusieurs workflows — des fichiers YAML rangés dans .github/workflows/. Chaque workflow contient des jobs, et chaque job s’exécute sur un runner : une machine virtuelle neuve, fournie par GitHub, créée pour l’occasion et détruite à la fin. Dans un job, on enchaîne des steps : soit une commande shell (run), soit une action réutilisable que quelqu’un a déjà écrite (uses).

La distinction run contre uses est la première à intégrer. run exécute une commande comme vous le feriez dans un terminal. uses appelle une brique packagée, versionnée, publiée sur le GitHub Marketplace — par exemple actions/checkout pour récupérer votre code, ou actions/setup-node pour installer Node. On ne réinvente pas ces briques : on les compose. Un job, c’est donc une recette ; les steps en sont les gestes, dans l’ordre.

Retenez aussi que chaque job démarre sur une machine vierge. Le runner ne connaît rien de votre projet tant que vous ne lui avez pas demandé de cloner le dépôt. C’est la cause numéro un des premiers échecs : on oublie de récupérer le code, puis on s’étonne que npm ne trouve aucun fichier.

Étape 2 — Créer le fichier de workflow (quick win)

GitHub découvre automatiquement les workflows dans un dossier précis et nulle part ailleurs : .github/workflows/, à la racine du dépôt. Le nom du fichier importe peu (il finit en .yml ou .yaml) ; c’est son contenu qui compte. Créons le projet minimal de Récolte et son premier workflow.

# En local, on prépare un projet Node minimal
mkdir recolte-api && cd recolte-api
git init
npm init -y
# on génère un package-lock.json, indispensable pour `npm ci` plus tard
npm install
mkdir -p .github/workflows

Le npm install initial crée le fichier package-lock.json. Ce verrou liste les versions exactes de chaque dépendance : c’est lui qui rendra nos installations reproductibles côté runner. Créons maintenant le workflow dans .github/workflows/ci.yml :

name: CI

on: push

jobs:
  verifier:
    runs-on: ubuntu-latest
    steps:
      - name: Récupérer le code
        uses: actions/checkout@v6

      - name: Installer Node.js 24
        uses: actions/setup-node@v6
        with:
          node-version: 24

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

      - name: Vérifier l'environnement
        run: |
          node --version
          npm --version
          echo "Récolte : environnement prêt ✅"

Décortiquons. name: CI est l’étiquette affichée dans l’onglet Actions. on: push dit « déclenche-toi à chaque poussée de commits ». Le job verifier tourne sur ubuntu-latest (aujourd’hui Ubuntu 24.04). Les quatre steps s’enchaînent : on clone le dépôt avec checkout@v6, on installe Node 24 avec setup-node@v6, on restaure les dépendances avec npm ci, puis on affiche les versions pour prouver que tout est en place. Le | après run indique un bloc multiligne : chaque ligne devient une commande.

Poussez le tout sur GitHub :

git add .
git commit -m "Ajout du premier workflow CI"
git branch -M main
git remote add origin https://github.com/VOTRE-COMPTE/recolte-api.git
git push -u origin main

Point d’étape — Ouvrez votre dépôt sur github.com, onglet Actions. Un workflow « CI » doit apparaître, en cours puis terminé. Pour vérifier le succès : un rond vert à côté du commit. Si vous voyez un rond rouge, ouvrez le job et lisez le step en échec — on traite les causes classiques en fin d’article.

Étape 3 — Lire les journaux et comprendre le statut

Le rond vert ne suffit pas : un développeur efficace sait lire ce qui s’est passé. Dans l’onglet Actions, cliquez sur l’exécution la plus récente, puis sur le job verifier. GitHub affiche chaque step dans un accordéon dépliable, avec sa durée et sa sortie console complète. Dépliez « Vérifier l’environnement » : vous devez y lire v24.x.x et le message « Récolte : environnement prêt ».

Cette page est votre meilleur outil de diagnostic. Quand un pipeline échoue, GitHub déplie automatiquement le step fautif et surligne la ligne d’erreur. Le code de sortie y est roi : un step réussit si sa dernière commande renvoie 0, et échoue dès qu’une commande renvoie un code non nul. C’est pour cela qu’un npm ci qui plante arrête tout le job — inutile de continuer si les dépendances ne sont pas installées. Comprendre cette règle vous évitera des heures de confusion : GitHub Actions ne « devine » jamais l’échec, il lit des codes de sortie.

Étape 4 — Choisir les bons événements déclencheurs

Se déclencher à chaque push sur chaque branche est rarement ce qu’on veut en pratique. On préfère vérifier la branche principale et les propositions de modification (pull requests), et garder la possibilité de lancer le workflow à la main pour le tester. Remplaçons la ligne on: push par une configuration plus fine :

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

Trois déclencheurs cohabitent désormais. push limité à main : la CI tourne quand du code arrive sur la branche de référence. pull_request ciblant main : dès qu’un contributeur propose une fusion, ses commits sont testés avant d’entrer dans main — c’est le cœur de l’intégration continue. workflow_dispatch (sans valeur) ajoute un bouton « Run workflow » dans l’onglet Actions, pratique pour relancer manuellement sans pousser de commit.

Il existe bien d’autres événements — schedule pour une exécution programmée façon cron, release quand vous publiez une version, issues ou label pour automatiser la gestion du dépôt. Mais pour un pipeline de qualité du code, ce trio couvre la quasi-totalité des besoins réels. Poussez la modification, ouvrez une branche de test, créez une pull request : vous verrez la CI se lancer automatiquement sur la PR, avec son verdict affiché directement dans la conversation.

Étape 5 — Ajouter une vérification utile et un badge

Afficher des versions, c’est un quick win, pas un garde-fou. Donnons à la CI une vraie mission : refuser tout code dont la syntaxe ne tient pas. On ajoute un script de contrôle dans package.json qui demande à Node de vérifier que chaque fichier source se charge sans erreur de syntaxe.

{
  "name": "recolte-api",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "check": "node --check server.js"
  }
}

La commande node --check analyse un fichier sans l’exécuter et renvoie un code non nul à la moindre faute de syntaxe — parfait pour un premier filet de sécurité. Créez un server.js volontairement minimal (console.log("Récolte") suffit pour l’instant), puis branchez le script dans le workflow en remplaçant le dernier step :

      - name: Contrôler la syntaxe
        run: npm run check

Désormais, si quelqu’un pousse un server.js avec une accolade oubliée, le job vire au rouge et la pull request est marquée comme non mergeable d’un coup d’œil. C’est le premier maillon d’une chaîne qu’on étoffera dans le tutoriel suivant avec de vrais tests. Reste à le rendre visible : ajoutez un badge dans votre README.md.

![CI](https://github.com/VOTRE-COMPTE/recolte-api/actions/workflows/ci.yml/badge.svg)

Ce badge reflète en direct l’état du dernier run sur main. Vert quand tout passe, rouge sinon. Sur un dépôt public, c’est un signal de sérieux immédiat pour quiconque visite votre projet.

Point d’étape — Votre dépôt doit maintenant : se vérifier à chaque push et chaque PR sur main, refuser une syntaxe cassée, et afficher un badge vert. Pour le tester, poussez volontairement un server.js avec une faute de syntaxe et observez le rouge — puis corrigez.

🐞 Pièges fréquents

Symptôme / erreur Cause probable Correctif
Aucun workflow n’apparaît dans l’onglet Actions Fichier hors de .github/workflows/ ou extension erronée Vérifier le chemin exact et l’extension .yml ; le dossier .github commence bien par un point
npm ci can only install with an existing package-lock.json Le verrou n’a pas été commité Lancer npm install en local puis git add package-lock.json
You have an error in your YAML syntax Indentation mélangée (tabulations) ou deux-points mal placés Indenter avec des espaces uniquement (2 par niveau), jamais de tabulation
Le job échoue sur npm run check : « command not found » Script absent du package.json Ajouter la clé dans scripts et committer le fichier
Le workflow ne se déclenche pas sur une autre branche branches: [main] filtre les push Ouvrir une pull request vers main, ou élargir le filtre de branches

🌍 Adaptation au contexte ouest-africain

C’est l’un des rares outils où l’infrastructure ne coûte rien si l’on joue bien. Sur un dépôt public, GitHub offre des minutes d’exécution illimitées sur ses runners standard : vous pouvez faire tourner votre CI autant que vous voulez depuis Dakar, Cotonou ou Niamey sans sortir un franc. Cela compte quand le budget cloud est serré et que chaque outil payant pèse. Pour un dépôt privé, le plan gratuit inclut 2 000 minutes par mois — largement suffisant pour un projet personnel ou un petit collectif.

Autre avantage décisif quand la machine de travail est modeste : c’est le runner de GitHub qui fait le gros œuvre, pas votre ordinateur. Installer Node, compiler, tester — tout se passe sur une VM distante. Un vieux portable suffit pour pousser du code et lire un journal. Côté bande passante, le runner clone le dépôt depuis l’infrastructure de GitHub, pas depuis chez vous : une connexion intermittente n’affecte que votre git push, pas l’exécution du pipeline.

✅ Récapitulatif

Vous êtes parti d’un dépôt nu et vous en sortez avec un pipeline d’intégration continue fonctionnel. Vous savez désormais nommer les briques — événement, job, step, runner, action — et vous comprenez pourquoi un job démarre toujours par un checkout. Vous avez écrit un ci.yml qui se déclenche sur push, sur pull request et à la demande, qui installe Node 24 de façon reproductible avec npm ci, et qui refuse une syntaxe cassée. Vous savez lire un journal d’exécution et interpréter un code de sortie. Le badge dans le README boucle la boucle : votre projet annonce publiquement qu’il est testé en continu. C’est la fondation sur laquelle reposent tous les tutoriels suivants.

🧾 Aide-mémoire

Élément Rôle
.github/workflows/*.yml Emplacement obligatoire des workflows
on: Liste des événements déclencheurs (push, pull_request, workflow_dispatch…)
runs-on: ubuntu-latest Type de runner (machine virtuelle Ubuntu 24.04)
uses: actions/checkout@v6 Cloner le dépôt sur le runner
uses: actions/setup-node@v6 Installer une version précise de Node.js
run: Exécuter une commande shell
npm ci Installation reproductible à partir du verrou

💪 À vous de jouer

Deux défis pour ancrer ce que vous venez d’apprendre.

1. Faites en sorte que la CI se déclenche aussi sur les branches dont le nom commence par feature/, en plus de main.

2. Ajoutez un step qui affiche le nom de la branche et l’auteur du commit, en utilisant les informations que GitHub injecte automatiquement.

Voir une solution
on:
  push:
    branches:
      - main
      - 'feature/**'
  pull_request:
    branches: [main]
  workflow_dispatch:

# ... dans les steps :
      - name: Contexte du commit
        run: |
          echo "Branche : ${{ github.ref_name }}"
          echo "Auteur  : ${{ github.actor }}"

Le motif 'feature/**' capture toutes les branches sous feature/. Les expressions ${{ github.ref_name }} et ${{ github.actor }} puisent dans le contexte github, un ensemble de variables que la plateforme remplit pour chaque exécution.

Tutoriels frères

Pour aller plus loin

FAQ

Faut-il payer pour utiliser GitHub Actions ?
Non sur un dépôt public : minutes illimitées sur les runners standard. Sur un dépôt privé, le plan gratuit inclut 2 000 minutes par mois, ce qui suffit largement pour débuter.

Quelle différence entre un workflow et un job ?
Un workflow est le fichier YAML complet, déclenché par un événement. Un job est une unité de travail à l’intérieur, qui tourne sur son propre runner. Un workflow peut contenir plusieurs jobs, exécutés en parallèle par défaut.

Pourquoi npm ci plutôt que npm install dans la CI ?
npm ci installe exactement les versions figées dans package-lock.json, sans jamais le modifier. C’est plus rapide et surtout reproductible : la CI installe la même chose que vous, à la virgule près.

Mon workflow ne se lance pas, pourquoi ?
Vérifiez trois choses : le fichier est bien dans .github/workflows/, son YAML est valide (indentation par espaces), et l’événement correspond à ce que vous faites (un push sur une branche filtrée hors de la liste ne déclenchera rien).

Le runner garde-t-il mes fichiers entre deux exécutions ?
Non. Chaque exécution part d’une machine vierge. Tout ce dont le job a besoin doit être récupéré (checkout) ou installé à chaque fois. Pour conserver des résultats, on utilise les artefacts, vus dans le tutoriel sur les tests.

Mots-clés : premier workflow GitHub Actions, fichier ci.yml, événements push pull_request, runner ubuntu-latest, actions/checkout, actions/setup-node, intégration continue Node.js.

Partager