Debug workflow
Optimiser les workflows GitHub Actions
Mise à jour :
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.
Ce guide vous montre comment réduire drastiquement le temps d’exécution de vos workflows GitHub Actions.
Pourquoi optimiser ?
| Problème | Impact | Solution |
|---|---|---|
| Installation des dépendances à chaque run | +2-5 min | Cache |
| Téléchargement d’artifacts volumineux | +1-3 min | Artifacts optimisés |
| Workflows parallèles inutiles | Gaspillage de runners | Concurrency |
| Debug en aveugle | Temps perdu à investiguer | Logs structurés |
Guides par sujet
Gains rapides
1. Activer le cache intégré (setup-node, setup-python)
La plupart des actions setup-* ont un cache intégré :
# ❌ Pas de cache : npm ci à chaque run (30-60s)- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20'- run: npm ci
# ✅ Avec cache : npm ci sauté si cache hit (2-5s)- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20' cache: 'npm' # Active le cache !- run: npm ci2. Éviter les runs simultanés inutiles
# Annule les runs précédents sur la même brancheconcurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: trueGain : évite de gaspiller des runners sur des commits intermédiaires.
3. Checkout partiel
# ❌ Clone tout l'historique- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# ✅ Clone uniquement le dernier commit (plus rapide)- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 1Exception : gardez fetch-depth: 0 si vous avez besoin des tags ou de
l’historique (semantic-release, changelogs).
4. Paralléliser les jobs indépendants
jobs: # Ces jobs s'exécutent en parallèle lint: runs-on: ubuntu-latest steps: [...]
test: runs-on: ubuntu-latest steps: [...]
security: runs-on: ubuntu-latest steps: [...]
# Ce job attend les autres deploy: needs: [lint, test, security] runs-on: ubuntu-latest steps: [...]5. Filtrer les déclenchements
on: push: branches: [main] paths: - 'src/**' - 'package*.json' - '!**/*.md' # Ignore les changements de docsMétriques à surveiller
Temps d’exécution moyen
Dans l’onglet Actions, regardez la durée moyenne de vos workflows. Objectifs raisonnables :
| Type de workflow | Durée cible |
|---|---|
| Lint | < 1 min |
| Tests unitaires | < 5 min |
| Build | < 5 min |
| Tests E2E | < 15 min |
| Déploiement | < 5 min |
Taux de cache hit
Vérifiez dans les logs si le cache est utilisé :
Cache restored from key: npm-linux-abc123...Un taux de cache hit < 50% indique un problème de clé de cache.
Coût (minutes utilisées)
Repository → Settings → Actions → Usage and billing
Surveillez la consommation, surtout avec les runners macOS (10x plus cher).
Patterns anti-performance
❌ Recalculer ce qui n’a pas changé
# Inefficace : build complet à chaque commit- run: npm run build- run: npm testSolution : utilisez le cache pour les dépendances et le build incrémental.
❌ Jobs séquentiels sans raison
# Inefficace : lint attend test qui attend buildjobs: build: steps: [...] test: needs: build # Pourquoi ? steps: [...] lint: needs: test # Vraiment nécessaire ? steps: [...]Solution : parallélisez les jobs indépendants.
❌ Télécharger les mêmes artifacts plusieurs fois
# Inefficace : chaque job télécharge toutjobs: test-unit: steps: - run: npm ci # Télécharge 500MB test-integration: steps: - run: npm ci # Re-télécharge 500MB test-e2e: steps: - run: npm ci # Re-télécharge 500MBSolution : job de build partagé + artifacts ou cache.
❌ Images Docker non optimisées
# Inefficace : image lourde avec outils inutilescontainer: image: ubuntu:latest
# Mieux : image légère avec juste ce qu'il fautcontainer: image: node:20-alpineWorkflow optimisé (exemple complet)
name: CI
on: push: branches: [main] paths-ignore: - '**.md' - 'docs/**' pull_request: branches: [main] paths-ignore: - '**.md'
# Annule les runs précédents sur la même PR/brancheconcurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true
permissions: contents: read
jobs: # Jobs parallèles rapides lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 1
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20' cache: 'npm'
- run: npm ci - run: npm run lint
test: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 1
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20' cache: 'npm'
- run: npm ci - run: npm test
build: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 1
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20' cache: 'npm'
- run: npm ci - run: npm run build
# Upload du build pour les jobs suivants - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: build path: dist/ retention-days: 1
# Job final qui attend tous les autres deploy: needs: [lint, test, build] if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1 with: name: build path: dist/
- run: ./deploy.shLiens utiles
- Workflows GitHub Actions — guide principal