Aller au contenu
CI/CD & Automatisation medium

Optimiser les workflows GitHub Actions

9 min de lecture

Un workflow lent, c’est du temps perdu pour toute l’équipe. Entre l’attente des résultats de tests et les déploiements qui traînent, une CI mal optimisée peut coûter des heures chaque semaine.

Cette section vous montre comment réduire drastiquement le temps d’exécution de vos workflows GitHub Actions.

  1. Activez le cache des dépendances

    C’est le gain le plus immédiat. Une ligne suffit pour passer de 45 secondes à 3 secondes sur l’installation des dépendances.

  2. Partagez les résultats entre jobs avec les artifacts

    Un job build crée dist/, les jobs test et deploy le réutilisent. Vous ne buildez qu’une seule fois pour tout le pipeline.

  3. Comprenez la différence cache vs artifacts

    Le cache réutilise des fichiers entre les runs. Les artifacts partagent des fichiers entre les jobs d’un même run. Confondre les deux = problèmes garantis.

  4. Apprenez à diagnostiquer les problèmes

    Workflow qui ne se déclenche pas, échecs mystérieux, lenteurs inexpliquées : les techniques de debug vous feront gagner des heures.

Le cache réutilise les dépendances entre les runs. Vous pushez 3 commits successifs ? Les node_modules sont téléchargés une seule fois.

Cache : les bases

Comprendre les clés, restore-keys, stratégies de cache et sécurité. Le guide complet pour maîtriser le cache GitHub Actions.

Lire le guide →

Les artifacts transportent des fichiers entre les jobs d’un même run. Un job build crée dist/, les jobs suivants le téléchargent.

Upload, download, optimisations et patterns pour partager builds, rapports et binaires entre les jobs de votre workflow.

Lire le guide →

Déboguer les workflows

Workflow qui ne démarre pas ? Échec sans message clair ? Techniques de détective pour comprendre ce qui se passe sur les runners distants.

Lire le guide →

Les actions setup-* intègrent le cache en une ligne :

# Node.js
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
# Python
- uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
# Java
- uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: 'maven'

Gain typique : Installation de dépendances de 45s → 3s

Au lieu de rebuilder dans chaque job, buildez une fois et partagez :

jobs:
build:
steps:
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
retention-days: 1
test:
needs: build
steps:
- uses: actions/download-artifact@v4
with:
name: dist
- run: npm test

Gain typique : Workflow de 10 min → 6 min

Évitez de gaspiller des runners sur des commits intermédiaires :

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

Gain : Économie de minutes de build, surtout sur les branches actives.

Lint, tests et build peuvent souvent s’exécuter en parallèle :

jobs:
lint:
runs-on: ubuntu-24.04
steps:
- run: npm run lint
test:
runs-on: ubuntu-24.04
steps:
- run: npm test
build:
runs-on: ubuntu-24.04
steps:
- run: npm run build
deploy:
needs: [lint, test, build] # Attend que tout soit terminé
runs-on: ubuntu-24.04
steps:
- run: ./deploy.sh

Gain typique : 3 jobs séquentiels (15 min) → 3 jobs parallèles (5 min)

Inutile de lancer la CI pour un changement de README :

on:
push:
paths-ignore:
- '**.md'
- 'docs/**'
- '.github/**'
branches:
- main
- develop

Gain : Moins de runs inutiles = moins d’attente et de consommation de minutes.

MétriqueOù la trouverObjectif
Durée du workflowOnglet Actions< 10 min pour un workflow standard
Taux de cache hitLogs du job> 80% (cache efficace)
Minutes consomméesSettings → Actions → Usage< 50% du quota mensuel
Temps d’installationLogs setup-*< 5s avec cache
Taux d’échecInsights → Actions< 5% (qualité stable)

Avant de déployer un workflow en production :

  • Cache activé pour les dépendances (cache: 'npm', cache: 'pip', etc.)
  • Builds partagés via artifacts (pas de rebuild inutile)
  • Jobs indépendants en parallèle (lint, test, build)
  • concurrency configuré pour annuler les runs obsolètes
  • Déclenchements filtrés (paths-ignore pour MD, docs…)
  • Permissions minimales (permissions: read-all)
  • Durée totale < 10 min pour un workflow standard

Voici un workflow complet qui applique toutes les bonnes pratiques :

name: CI/CD Optimisé
on:
push:
branches: [main]
paths-ignore:
- '**.md'
- 'docs/**'
pull_request:
# Annule les runs obsolètes
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# Permissions minimales
permissions:
contents: read
jobs:
# Jobs en parallèle pour gagner du temps
lint:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm' # Cache activé
- run: npm ci
- run: npm run lint
test:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm test
build:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run build
# Partage du build via artifact
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
retention-days: 1
# Déploiement après validation
deploy:
needs: [lint, test, build]
runs-on: ubuntu-24.04
if: github.ref == 'refs/heads/main'
permissions:
contents: read
id-token: write # Pour OIDC
steps:
# Récupère le build
- uses: actions/download-artifact@v4
with:
name: dist
- run: ./deploy.sh

Gains de ce workflow :

  • Cache : installation de 45s → 3s
  • Parallélisation : lint+test+build simultanés (5 min au lieu de 15 min)
  • Artifacts : pas de rebuild pour le déploiement
  • Concurrency : annulation automatique des runs obsolètes
  • Filtres : pas de run sur les changements de documentation

Durée totale : ~5-6 min au lieu de 15-20 min sans optimisation.

Durée totale : ~5-6 min au lieu de 15-20 min sans optimisation.

Cache = entre runs

Pour réutiliser les dépendances entre les exécutions du workflow. Gain immédiat sur npm ci, pip install, etc.

Artifacts = entre jobs

Pour partager les résultats (builds, rapports) entre les jobs d’un même run. Évite les rebuilds inutiles.

Paralléliser

Lint, test et build peuvent souvent s’exécuter en même temps. Le déploiement attend la fin avec needs:.

Annuler l'obsolète

concurrency: cancel-in-progress pour éviter de gaspiller des runners sur des commits intermédiaires.

Les 3 optimisations prioritaires :

  1. Cache : Ajoutez cache: 'npm' (ou pip, maven…) dans setup-*
  2. Artifacts : Buildez une fois, partagez avec upload-artifact/download-artifact
  3. Concurrency : Annulez les runs obsolètes automatiquement

Ces trois actions seules peuvent diviser par 2 ou 3 le temps de vos workflows.