GitHub Actions : multi-jobs, artefacts et workflows réutilisables
🎯 Objectifs
À la fin de ce module, vous serez capable de :
- ✅ Créer des pipelines multi-jobs avec dépendances
- ✅ Partager des fichiers entre jobs avec les artefacts
- ✅ Accélérer les pipelines avec le cache
- ✅ Contrôler l'exécution avec des conditions (
if:) - ✅ Créer et utiliser des workflows réutilisables
- ✅ Déclencher des workflows manuellement avec des inputs
📋 Prérequis
| Requis | Niveau |
|---|---|
| GitHub Actions (workflow basique) | Complété (module débutant) |
| Git (branches, PR) | Intermédiaire |
| Docker (bases) | Débutant |
🔗 Pipelines Multi-Jobs
Un workflow réaliste contient plusieurs jobs qui s'exécutent en parallèle ou séquentiellement.
Jobs en parallèle
Par défaut, les jobs s'exécutent en parallèle :
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm testlint et test démarrent en même temps → pipeline plus rapide.
Jobs séquentiels avec needs
Utilisez needs: pour créer des dépendances entre jobs :
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm test
build:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run build
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- run: echo "Déploiement..."Flux d'exécution
test → build → deploy| Mot-clé | Comportement |
|---|---|
needs: test | Attend que test réussisse |
needs: [lint, test] | Attend que les deux réussissent |
Pas de needs | S'exécute immédiatement (parallèle) |
💡 Si un job échoue, tous les jobs qui en dépendent sont annulés automatiquement.
📦 Artefacts
Les artefacts permettent de partager des fichiers entre jobs. Chaque job s'exécute sur un runner différent, donc sans artefacts ils ne partagent rien.
Upload un artefact
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: app-build
path: dist/
retention-days: 7Download un artefact
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: app-build
path: dist/
- run: ls -la dist/Cas d'usage courants
| Usage | Upload dans | Download dans |
|---|---|---|
| Build une fois, déployer partout | Job build | Jobs deploy-staging, deploy-prod |
| Rapports de tests | Job test | Consultable dans l'onglet Actions |
| Couverture de code | Job test | Job coverage-report |
💡
retention-dayscontrôle combien de temps l'artefact est conservé (défaut : 90 jours).
⚡ Cache
Le cache réutilise des fichiers entre exécutions du même workflow pour accélérer les builds.
Cache vs Artefacts
| Aspect | Cache | Artefacts |
|---|---|---|
| But | Accélérer les jobs | Passer des fichiers entre jobs |
| Persistance | Entre exécutions du workflow | Dans la même exécution |
| Fiabilité | Best-effort (peut être manquant) | Garanti |
| Usage typique | node_modules/, ~/.npm | dist/, rapports |
Mettre en cache les dépendances npm
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-| Paramètre | Rôle |
|---|---|
path | Dossier à mettre en cache |
key | Identifiant unique (change quand le lock file change) |
restore-keys | Clés de fallback si la clé exacte n'existe pas |
Cache intégré aux actions setup
Les actions setup-* proposent un cache intégré plus simple :
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'💡 Préférez le cache intégré des actions
setup-*quand il est disponible - moins de configuration.
🎯 Exécution Conditionnelle (if:)
Contrôlez quels jobs ou steps s'exécutent selon le contexte.
Condition sur un job
jobs:
deploy:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: echo "Déploiement uniquement sur main"Condition sur un step
steps:
- run: npm test
- name: Upload coverage
if: success()
run: echo "Tests réussis, upload de la couverture"
- name: Notify failure
if: failure()
run: echo "Les tests ont échoué !"Conditions courantes
| Expression | Quand |
|---|---|
github.ref == 'refs/heads/main' | Push sur main |
github.event_name == 'pull_request' | Déclenché par une PR |
success() | Le step précédent a réussi |
failure() | Un step précédent a échoué |
always() | Toujours (même si un step a échoué) |
contains(github.event.head_commit.message, '[skip ci]') | Le message de commit contient [skip ci] |
💡
if: always()est utile pour les steps de nettoyage qui doivent s'exécuter quoi qu'il arrive.
🔄 Workflows Réutilisables
Les workflows réutilisables évitent la duplication entre projets. Un workflow appelle un autre workflow.
Créer un workflow réutilisable (appelé)
# .github/workflows/reusable-test.yml
name: Tests réutilisables
on:
workflow_call:
inputs:
node-version:
description: 'Version de Node.js'
required: false
default: '20'
type: string
secrets:
npm-token:
required: false
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
- run: npm ci
- run: npm testAppeler un workflow réutilisable (appelant)
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
jobs:
tests:
uses: ./.github/workflows/reusable-test.yml
with:
node-version: '20'
secrets:
npm-token: ${{ secrets.NPM_TOKEN }}| Mot-clé | Rôle |
|---|---|
workflow_call | Déclare que le workflow est appelable |
inputs | Paramètres passés par l'appelant |
secrets | Secrets transmis explicitement |
uses: ./.github/workflows/... | Appelle un workflow du même dépôt |
💡 Vous pouvez aussi appeler des workflows d'autres dépôts :
uses: org/repo/.github/workflows/test.yml@main.
🖱️ Workflow Dispatch (déclenchement manuel)
Déclenchez un workflow manuellement depuis l'interface GitHub avec des paramètres.
name: Deploy
on:
workflow_dispatch:
inputs:
environment:
description: 'Environnement cible'
required: true
type: choice
options:
- staging
- production
version:
description: 'Version à déployer'
required: true
type: string
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- run: echo "Déploiement de ${{ inputs.version }} sur ${{ inputs.environment }}"Types d'inputs disponibles
| Type | Rendu dans l'interface |
|---|---|
string | Champ texte libre |
choice | Menu déroulant |
boolean | Case à cocher |
environment | Sélecteur d'environnement GitHub |
💡
workflow_dispatchest parfait pour les déploiements manuels ou les tâches ponctuelles.
🚦 Groupes de Concurrence
Évitez les exécutions redondantes quand plusieurs pushs arrivent rapidement.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true| Paramètre | Rôle |
|---|---|
group | Identifiant du groupe (même groupe = même file) |
cancel-in-progress: true | Annule l'exécution en cours si une nouvelle arrive |
Exemple : vous poussez 3 commits en 2 minutes. Sans concurrence, 3 pipelines s'exécutent. Avec concurrence, seul le dernier s'exécute.
💡 Placez
concurrencyau niveau du workflow (global) ou au niveau d'un job spécifique.
🔧 Pipeline Complet Intermédiaire
Voici un pipeline combinant toutes les notions de ce module :
name: CI/CD
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm test
build:
needs: [lint, test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: app-build
path: dist/
deploy:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: app-build
path: dist/
- run: echo "Déploiement de dist/ en production..."Flux d'exécution
lint ─┐
├→ build → deploy (seulement sur main)
test ─┘❌ Erreurs Courantes
| Erreur | Cause | Solution |
|---|---|---|
Artifact not found | Nom d'artefact différent entre upload et download | Vérifiez que name est identique |
Cache not found | Clé de cache qui ne match pas | Vérifiez le hashFiles() |
| Job ignoré sans raison | Condition if: trop restrictive | Testez avec if: always() temporairement |
Workflow not found | Mauvais chemin pour uses: | Vérifiez le chemin relatif du workflow |
| Boucle infinie | Workflow réutilisable qui s'appelle lui-même | Utilisez des événements différents |
📌 Points Clés
needs:crée des dépendances entre jobs (séquentiel)- Les artefacts partagent des fichiers entre jobs d'une même exécution
- Le cache accélère les builds en réutilisant des fichiers entre exécutions
if:contrôle l'exécution des jobs et steps selon le contexte- Les workflows réutilisables (
workflow_call) évitent la duplication concurrencyannule les exécutions redondantes
📚 Ressources
🚀 Prochaines étapes
Vous maîtrisez les pipelines multi-jobs et les workflows réutilisables. Allez plus loin :
- GitHub Actions avancé : secrets, matrices et déploiement - Secrets, matrices, environnements et stratégies de déploiement