Retour au blog
juil. 2026·4 min de lectureGénéré par IA
Langue:DeutschEnglishFrançaisÖsterreichischKlingonian Version originale: English

Écrire votre première GitHub Action

#ci-cd#github#devops

La plupart des équipes débutent avec GitHub Actions en copiant-collant un workflow d'un autre dépôt en espérant qu'il s'applique encore. Ça marche jusqu'au jour où ça ne marche plus, et où il faut vraiment comprendre ce qui déclenche une exécution, ce que sont un job et une étape, et comment passer des données de l'un à l'autre. Ce guide construit un vrai workflow à partir de rien : exécuter les tests à chaque pull request et publier un paquet lors des releases taguées.

Anatomie d'un workflow

Un workflow est un fichier YAML dans .github/workflows/. Il comporte trois éléments essentiels : les déclencheurs (on) décident quand il s'exécute, les jobs sont des groupes d'étapes exécutés chacun sur leur propre machine virtuelle, et les étapes sont les commandes ou actions individuelles à l'intérieur d'un job.

name: CI

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

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm test

actions/checkout@v4 clone votre dépôt dans le runner : sans lui, le runner est une VM vide sans accès à votre code. actions/setup-node installe une version précise de Node. npm ci (et non npm install) est important en CI : il installe exactement ce qui figure dans package-lock.json et échoue si le lockfile n'est pas synchronisé, au lieu de le mettre à jour en silence.

Exécuter des jobs en parallèle avec une matrice

Si vous devez tester plusieurs versions de Node ou plusieurs systèmes d'exploitation, une matrice transforme une définition de job en plusieurs exécutions parallèles :

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

Cela lance trois jobs indépendants, un par version de Node, tous en parallèle. ${{ matrix.node-version }} est la syntaxe d'expression de GitHub Actions : elle injecte la valeur courante de la matrice dans l'étape.

Mettre les dépendances en cache

Chaque job démarre sur une VM neuve, donc npm ci retélécharge tous les paquets à chaque exécution, sauf si vous les mettez en cache :

- uses: actions/setup-node@v4
  with:
    node-version: '20'
    cache: 'npm'

L'option cache intégrée à setup-node gère cela pour npm, yarn et pnpm : elle indexe le cache sur le hash de votre lockfile, de sorte qu'un succès de cache n'a lieu que si les dépendances n'ont pas changé.

Passer des données entre les étapes

Les étapes d'un même job partagent un système de fichiers, mais pas des variables : pour passer une valeur d'une étape à la suivante, on écrit dans un fichier de sortie spécial :

steps:
  - id: get_version
    run: echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"

  - run: echo "Building version ${{ steps.get_version.outputs.version }}"

id: get_version donne à l'étape un nom que l'on peut référencer plus tard sous la forme steps.get_version.outputs.version. Ce schéma (lire quelque chose, l'écrire dans $GITHUB_OUTPUT, le référencer en aval) est la façon dont la plupart des workflows non triviaux font circuler les données.

Secrets

N'écrivez jamais d'identifiants en dur dans un fichier de workflow : il est commité dans le dépôt et visible par quiconque a un accès en lecture. Stockez-les dans Settings → Secrets and variables → Actions du dépôt, et référencez-les via le contexte secrets :

- name: Publish package
  run: npm publish
  env:
    NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

Les secrets sont masqués automatiquement dans les logs : si une étape en affiche un par accident, GitHub le remplace par *** dans la sortie.

Déclencher uniquement sur les releases taguées

Combinez on.push.tags avec un job conditionnel pour ne publier que lorsque vous poussez un tag de version, tout en exécutant les tests à chaque push :

name: Release

on:
  push:
    tags:
      - 'v*'

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          registry-url: 'https://registry.npmjs.org'
          cache: 'npm'
      - run: npm ci
      - run: npm test
      - run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

Pousser un tag comme v1.2.0 lance ce workflow ; un commit ordinaire sur main ne le lance pas, puisque le déclencheur porte sur tags, pas sur branches.

Conditions if: pour un contrôle plus fin

Parfois, un déclencheur seul n'est pas assez précis. if: permet de conditionner une étape ou un job par une expression :

- name: Notify on failure
  if: failure()
  run: echo "Build failed on ${{ github.ref }}"

failure() est l'une des fonctions intégrées (avec success(), always() et cancelled()) qui vérifient le résultat des étapes précédentes du job. C'est utile pour envoyer une notification uniquement quand quelque chose casse, sans workflow séparé.

Déboguer un workflow

Deux choses font gagner le plus de temps quand un workflow se comporte mal :

  • act : exécute les workflows GitHub Actions en local dans Docker, ce qui permet d'itérer sans pousser un commit pour chaque faute de frappe.
  • Le déclencheur workflow_dispatch : ajoutez on: workflow_dispatch à n'importe quel workflow pour obtenir un bouton « Run workflow » dans l'interface GitHub, afin de le relancer manuellement sans nouveau push :
on:
  workflow_dispatch:
  push:
    branches: [main]

À retenir

Un workflow GitHub Actions n'est que du YAML décrivant des déclencheurs, des jobs et des étapes, exécutés sur des VM éphémères qui démarrent avec uniquement ce que leur donne actions/checkout. Une fois que vous lisez couramment on:, jobs:, steps: et la syntaxe d'expression ${{ }}, chaque workflow trouvé en ligne cesse de ressembler à de la magie et devient un fichier de configuration que vous pouvez réellement modifier.

Plus récentComprendre le pool de connexions de base de donnéesPlus ancienComprendre la boucle d'événements JavaScript