Retour au cours

infra / github-actions

Reusable workflows et composite actions

Leçon 101 exercice

Explication

Ce que vous allez apprendre

  • Comprendre le coût de maintenance de la duplication entre plusieurs workflows similaires
  • Créer un reusable workflow appelable via workflow_call, avec entrées, secrets et sorties
  • Créer une composite action pour factoriser quelques steps récurrents dans un job
  • Choisir entre reusable workflow (plusieurs jobs) et composite action (quelques steps)
  • Appeler un reusable workflow depuis un autre dépôt, épinglé à une version précise

Dans quel contexte ?

Une entreprise gère cinq microservices, chacun avec son propre pipeline de déploiement. Les cinq fichiers deploy.yml sont quasi identiques : build de l'image Docker, push vers le registre, déploiement sur le cluster. Un jour, il faut changer la façon dont l'authentification au registre fonctionne : la mise à jour doit se faire manuellement dans les cinq fichiers, et un développeur en oublie un, qui continue de pousser avec l'ancienne méthode pendant plusieurs semaines sans que personne ne le remarque. Les reusable workflows et composite actions existent précisément pour éliminer ce genre de duplication dangereuse.

Le problème : la duplication entre pipelines

D'abord, dès qu'un projet a plusieurs workflows, déploiement staging, déploiement production, plusieurs microservices similaires, on retrouve vite les mêmes suites d'étapes copiées-collées d'un fichier YAML à l'autre.

Le coût de cette duplication

Cette duplication devient un vrai coût de maintenance : corriger un bug ou changer une étape doit alors se faire partout, avec le risque d'en oublier une.

Un premier mécanisme de réutilisation

Un "reusable workflow", déclenché via workflow_call, réutilise un fichier de workflow entier, plusieurs jobs, avec des entrées, des secrets, et des sorties typés comme une vraie fonction.

MécanismeNiveau de réutilisationDéclencheur
Reusable workflowUn ou plusieurs jobs entiersworkflow_call
Composite actionQuelques steps à l'intérieur d'un jobuses: comme une action classique

Un deuxième mécanisme, à un niveau plus fin

Une "composite action" réutilise, elle, une suite de quelques étapes à l'intérieur d'un job, plus légère, pensée pour factoriser un bloc récurrent comme "installer Node.js et les dépendances avec cache".

La bonne façon de penser ces deux mécanismes

Il faut les voir comme des fonctions réutilisables : elles déclarent explicitement ce qu'elles attendent en entrée, inputs, secrets, et ce qu'elles renvoient en sortie, outputs.

Prérequis

Cette leçon suppose les triggers (workflow_call, leçon 3) et les jobs/outputs (leçon 4) déjà acquis : un reusable workflow combine directement ces deux notions pour se comporter comme une vraie fonction appelable.

Ce que ça change par rapport au copier-coller

Cela rend le comportement prévisible et testable, contrairement à un simple copier-coller qui diverge silencieusement avec le temps.

Bonne pratique

Dès qu'une même suite d'étapes apparaît dans deux workflows ou plus, extrais-la en reusable workflow ou composite action. C'est le même réflexe que factoriser une fonction dupliquée en programmation classique : corriger un bug une seule fois plutôt que dans cinq fichiers différents.

La portée : locale ou partagée

Un reusable workflow peut être appelé depuis le même dépôt, avec ./, ou depuis un dépôt distinct, épinglé à une version précise, org/repo@v2.

Ce que cette portée élargie permet

C'est un moyen puissant de centraliser des pipelines standards partagés par plusieurs projets d'une même organisation, tout en gardant le contrôle de quelle version est utilisée où.

Maintenant que tu sais factoriser des pipelines, la leçon suivante s'attaque à un besoin d'infrastructure différent : exécuter des jobs sur ta propre machine plutôt que sur celles de GitHub, avec les self-hosted runners.

Commandes & code

Reusable workflows & composite actions

yaml
# .github/workflows/reusable-deploy.yml - workflow appelable depuis d'autres workflows
name: Reusable Deploy
on:
  workflow_call:
    inputs:
      environment:
        required: true
        type: string
    secrets:
      deploy_token:
        required: true
    outputs:
      deployed_url:
        value: ${{ jobs.deploy.outputs.url }}

jobs:
  deploy:
    runs-on: ubuntu-latest
    outputs:
      url: ${{ steps.deploy.outputs.url }}
    steps:
      - uses: actions/checkout@v4
      - id: deploy
        run: |
          ./scripts/deploy.sh ${{ inputs.environment }}
          echo "url=https://${{ inputs.environment }}.example.com" >> "$GITHUB_OUTPUT"
        env:
          DEPLOY_TOKEN: ${{ secrets.deploy_token }}
yaml
# .github/workflows/deploy-staging.yml - appelle le workflow réutilisable ci-dessus
name: Deploy Staging
on:
  push:
    branches: [main]

jobs:
  call-deploy:
    uses: ./.github/workflows/reusable-deploy.yml
    with:
      environment: staging
    secrets:
      deploy_token: ${{ secrets.STAGING_DEPLOY_TOKEN }}

  # Peut aussi appeler un workflow d'un AUTRE dépôt versionné :
  # uses: myorg/shared-workflows/.github/workflows/reusable-deploy.yml@v2
yaml
# .github/actions/setup-project/action.yml - composite action : regroupe des steps répétitifs
name: "Setup project"
description: "Checkout + install Node + install dépendances, avec cache"
inputs:
  node-version:
    required: false
    default: "20"
runs:
  using: "composite"
  steps:
    - uses: actions/setup-node@v4
      with:
        node-version: ${{ inputs.node-version }}
        cache: "npm"
    - run: npm ci
      shell: bash                     # obligatoire pour chaque step "run" d'une composite action
yaml
# Utilisation de la composite action dans un workflow classique
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: ./.github/actions/setup-project
        with:
          node-version: "22"
      - run: npm test

Résumé

  • workflow_call transforme un workflow en composant réutilisable, avec inputs/secrets/outputs typés.
  • Un reusable workflow peut être appelé localement (./) ou depuis un autre dépôt (org/repo@ref).
  • Une composite action regroupe des steps répétitifs en une seule "action" invocable via uses:.
  • Chaque step run: d'une composite action doit préciser shell: explicitement.

Exercices pratiques

1 disponible
1

Mission : cinq pipelines de déploiement à ne plus dupliquer

Objectif : Extraire la logique commune de cinq workflows quasi identiques en un reusable workflow appelable avec des paramètres.

Contexte

Une entreprise gère cinq microservices, chacun avec son propre deploy.yml quasi identique (build de l'image Docker, push vers le registre, déploiement). Un changement récent dans la méthode d'authentification au registre a dû être répliqué manuellement dans les cinq fichiers, et un développeur en a oublié un, qui a continué de pousser avec l'ancienne méthode pendant plusieurs semaines sans que personne ne le remarque.

Résoudre l’exercice →