Votre workflow CI échoue. Vous regardez les logs… et vous ne comprenez rien. Ou pire : le workflow ne se déclenche même pas, sans aucun message d'erreur. Comment savoir ce qui ne va pas ?
Ce guide vous donne les techniques de détective pour comprendre ce qui se passe dans vos workflows GitHub Actions et résoudre les problèmes efficacement.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Diagnostiquer un workflow qui ne se déclenche pas
- Lire les logs et activer le mode debug détaillé
- Inspecter les contexts et vérifier la présence des secrets
- Repérer les goulots d'étranglement d'un workflow lent
- Tester en local avec act pour éviter les allers-retours
Pourquoi le debug est difficile ?
Section intitulée « Pourquoi le debug est difficile ? »Contrairement au code local que vous pouvez exécuter pas à pas avec un débogueur, les workflows GitHub Actions s'exécutent sur des machines distantes auxquelles vous n'avez pas accès direct.
Les défis spécifiques :
| Défi | Conséquence |
|---|---|
| Exécution distante | Pas de console.log en temps réel |
| Environnement éphémère | La VM disparaît après le run |
| Logs limités | Par défaut, seuls les messages standards sont visibles |
| Pas de breakpoints | Impossible de mettre le workflow en pause |
Les trois types de problèmes
Section intitulée « Les trois types de problèmes »Avant de debugger, identifiez le type de problème :
🔴 Le workflow ne se déclenche pas
Le workflow existe mais rien ne se passe quand vous poussez du code.
🟠 Le workflow échoue
Le workflow démarre mais un ou plusieurs jobs échouent.
🟡 Le workflow est trop lent
Le workflow fonctionne mais prend beaucoup trop de temps.
Chaque type de problème nécessite une approche différente.
Problème 1 : Le workflow ne se déclenche pas
Section intitulée « Problème 1 : Le workflow ne se déclenche pas »C'est souvent le plus frustrant : vous poussez du code, mais rien ne se passe dans l'onglet Actions.
Étape 1 : Vérifier que le fichier est au bon endroit
Section intitulée « Étape 1 : Vérifier que le fichier est au bon endroit »Le workflow doit être dans .github/workflows/ et avoir l'extension .yml
ou .yaml.
# Vérifier la structurels -la .github/workflows/
# Vous devez voir vos fichiers de workflow# ci.yml deploy.yml etc.Erreur courante : le fichier est dans .github/workflow/ (sans le "s")
ou dans un autre dossier.
Étape 2 : Vérifier la syntaxe YAML
Section intitulée « Étape 2 : Vérifier la syntaxe YAML »Une erreur de syntaxe empêche GitHub de charger le workflow. Utilisez actionlint pour valider :
# Installer actionlintbrew install actionlint
# Valider tous les workflowsactionlint
# Valider un fichier spécifiqueactionlint .github/workflows/ci.ymlErreurs courantes :
# ❌ Mauvaise indentation (2 espaces attendus)jobs: build: # 1 espace au lieu de 2 runs-on: ubuntu-24.04
# ❌ Guillemets manquants autour des caractères spéciauxon: push: branches: - feature/* # Le * doit être entre guillemets : "feature/*"
# ❌ Deux-points manquantjobs: build runs-on: ubuntu-24.04 # Erreur : "build" sans ":"Étape 3 : Vérifier les filtres de déclenchement
Section intitulée « Étape 3 : Vérifier les filtres de déclenchement »Votre workflow peut être configuré pour ne réagir qu'à certains événements ou certaines branches.
# Ce workflow ne se déclenche que sur mainon: push: branches: - main # Si vous êtes sur develop, rien ne se passe !
# Ce workflow ne se déclenche que si des fichiers .py changenton: push: paths: - '**/*.py' # Un changement dans package.json est ignoréComment vérifier ?
- Regardez la section
on:de votre workflow - Comparez avec la branche/l'événement que vous testez
- Vérifiez les filtres
paths:etpaths-ignore:
Étape 4 : Vérifier l'onglet Actions
Section intitulée « Étape 4 : Vérifier l'onglet Actions »Parfois le workflow est désactivé ou en attente d'approbation :
- Allez dans l'onglet Actions de votre repository
- Regardez la liste des workflows à gauche
- Si le workflow n'apparaît pas → erreur de syntaxe
- Si le workflow apparaît en gris → il est désactivé (cliquez pour activer)
- Si vous voyez "Workflows require approval" → vous devez approuver
Étape 5 : Vérifier les événements spéciaux
Section intitulée « Étape 5 : Vérifier les événements spéciaux »Certains événements ont des comportements particuliers :
| Événement | Piège courant |
|---|---|
pull_request | Ne se déclenche pas sur les PRs de forks (pour les secrets) |
pull_request_target | Se déclenche sur le repo cible, pas le fork |
schedule | Peut être retardé si GitHub est surchargé |
workflow_dispatch | Doit être déclenché manuellement via l'interface |
Problème 2 : Le workflow échoue
Section intitulée « Problème 2 : Le workflow échoue »Le workflow démarre mais un step échoue. Voici comment trouver la cause.
Comprendre la structure des logs
Section intitulée « Comprendre la structure des logs »Quand vous cliquez sur un run échoué, vous voyez une hiérarchie :
Run (ensemble du workflow)└── Job (ex: build, test, deploy) └── Step 1: Checkout code ✅ └── Step 2: Setup Node.js ✅ └── Step 3: Install dependencies ✅ └── Step 4: Run tests ❌ ← Le problème est ici └── Step 5: Upload coverage (skipped)Cliquez sur le step qui a échoué pour voir les détails.
Activer les logs de debug
Section intitulée « Activer les logs de debug »Par défaut, GitHub n'affiche que les messages standards. Pour voir plus de détails, activez le mode debug.
Méthode 1 : Re-run avec debug
- Allez sur le run échoué
- Cliquez sur Re-run all jobs (menu en haut à droite)
- Cochez Enable debug logging
- Relancez
Méthode 2 : Variables d'environnement
Ajoutez ces variables à votre workflow :
name: CI
on: push
permissions: {}
env: # Active les logs détaillés du runner (la machine qui exécute) ACTIONS_RUNNER_DEBUG: true # Active les logs détaillés de chaque step ACTIONS_STEP_DEBUG: true
jobs: build: runs-on: ubuntu-24.04 permissions: contents: read steps: # ...Utiliser les commandes de workflow
Section intitulée « Utiliser les commandes de workflow »GitHub Actions reconnaît des commandes spéciales dans les logs. Utilisez-les pour créer des messages visibles :
- name: Diagnostic run: | # Message de debug (visible seulement en mode debug) echo "::debug::Variable PATH = $PATH"
# Notice (information visible dans les logs) echo "::notice::Compilation réussie en 45 secondes"
# Warning (triangle jaune dans l'interface) echo "::warning::La dépendance lodash est obsolète"
# Error (croix rouge, fait échouer le step) echo "::error::Fichier de configuration manquant"Résultat dans l'interface :
::debug::→ Visible uniquement avecACTIONS_STEP_DEBUG: true::notice::→ Annotation bleue dans le résumé du run::warning::→ Annotation jaune, n'échoue pas le workflow::error::→ Annotation rouge, fait échouer le step
Inspecter les contexts
Section intitulée « Inspecter les contexts »Les contexts (github, env, secrets, etc.) contiennent les informations
disponibles pendant l'exécution. Affichez-les pour comprendre l'état :
- name: Afficher le contexte GitHub env: # Les valeurs de contexte passent par env: (jamais interpolées dans run:) REPO: ${{ github.repository }} BRANCH: ${{ github.ref }} COMMIT: ${{ github.sha }} EVENT: ${{ github.event_name }} ACTOR: ${{ github.actor }} run: | echo "Repository: $REPO" echo "Branche: $BRANCH" echo "Commit: $COMMIT" echo "Événement: $EVENT" echo "Acteur: $ACTOR"Pour tout voir d'un coup (utile en debug) :
- name: Dump tous les contexts env: # On passe par une variable pour éviter les problèmes d'échappement ALL_CONTEXTS: | github: ${{ toJSON(github) }} env: ${{ toJSON(env) }} job: ${{ toJSON(job) }} steps: ${{ toJSON(steps) }} run: echo "$ALL_CONTEXTS"Vérifier si un secret existe
Section intitulée « Vérifier si un secret existe »Les secrets sont masqués dans les logs (remplacés par ***). Pour vérifier
qu'un secret est bien configuré sans l'exposer :
- name: Vérifier les secrets env: # Le secret passe par env: — jamais interpolé directement dans run: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: | if [ -n "$NPM_TOKEN" ]; then echo "NPM_TOKEN est configuré" else echo "NPM_TOKEN est vide ou non configuré" exit 1 fiGarder des preuves en cas d'échec
Section intitulée « Garder des preuves en cas d'échec »Quand un test échoue, les fichiers de log sont perdus avec la VM. Configurez un upload automatique :
- name: Exécuter les tests run: npm test
- name: Sauvegarder les logs en cas d'échec if: failure() # Ne s'exécute que si le step précédent a échoué uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: debug-logs-${{ github.run_id }} path: | logs/ coverage/ npm-debug.log test-results/ retention-days: 5 # Garde les logs 5 joursLes artifacts sont téléchargeables depuis la page du run.
Continuer malgré une erreur
Section intitulée « Continuer malgré une erreur »Parfois vous voulez voir ce qui se passe après une erreur :
- name: Step qui peut échouer id: risky-step run: ./script-instable.sh continue-on-error: true # Le workflow continue même si ce step échoue
- name: Analyser le résultat run: | echo "Résultat du step précédent: ${{ steps.risky-step.outcome }}" # outcome = 'success' ou 'failure'
if [ "${{ steps.risky-step.outcome }}" == "failure" ]; then echo "Le script a échoué, mais on continue pour collecter des infos" fiProblème 3 : Le workflow est trop lent
Section intitulée « Problème 3 : Le workflow est trop lent »Votre workflow fonctionne, mais il prend 15 minutes au lieu de 3. Voici comment identifier les goulots d'étranglement.
Analyser la durée des steps
Section intitulée « Analyser la durée des steps »GitHub affiche la durée de chaque step dans l'interface. Cliquez sur un job pour voir le détail :
✓ Checkout (2s)✓ Setup Node.js (5s)✓ Install dependencies (4m 30s) ← Suspect !✓ Run tests (1m 15s)✓ Build (45s)Dans cet exemple, l'installation des dépendances prend 4 minutes 30. C'est probablement un problème de cache.
Vérifier l'utilisation du cache
Section intitulée « Vérifier l'utilisation du cache »Cherchez ces messages dans les logs :
# ✅ Cache utiliséCache restored from key: npm-linux-abc123def456
# ❌ Cache non trouvéCache not found for input keys: npm-linux-xyz789Si le cache n'est pas trouvé, vérifiez :
- La clé de cache correspond-elle à votre configuration ?
- Le cache a-t-il expiré (7 jours sans utilisation) ?
- Le cache a-t-il été invalidé par un changement de lockfile ?
Voir le guide Artifacts vs Cache pour optimiser.
Mesurer précisément avec des timestamps
Section intitulée « Mesurer précisément avec des timestamps »Pour les opérations longues, ajoutez des mesures :
- name: Début du timer run: echo "START_TIME=$(date +%s)" >> "$GITHUB_ENV"
- name: Opération longue run: npm ci
- name: Fin du timer run: | END_TIME=$(date +%s) DURATION=$((END_TIME - START_TIME)) echo "::notice::Installation des dépendances : ${DURATION} secondes"Identifier les problèmes réseau
Section intitulée « Identifier les problèmes réseau »Les téléchargements lents sont une cause fréquente de lenteur :
- name: Diagnostic réseau run: | echo "=== Test DNS ===" time nslookup registry.npmjs.org
echo "=== Test de téléchargement ===" time curl -s -o /dev/null -w "Temps: %{time_total}s\n" https://registry.npmjs.orgLimiter le temps d'exécution
Section intitulée « Limiter le temps d'exécution »Pour éviter les workflows qui tournent indéfiniment :
jobs: build: runs-on: ubuntu-24.04 timeout-minutes: 30 # Le job entier ne peut pas dépasser 30 min
steps: - name: Opération risquée timeout-minutes: 5 # Ce step spécifique ne peut pas dépasser 5 min run: ./script-potentiellement-long.shMessages d'erreur courants
Section intitulée « Messages d'erreur courants »Quatre messages reviennent sans cesse dans les workflows. Les reconnaître fait gagner un temps précieux : derrière chaque libellé cryptique se cache une cause précise et une correction connue.
"Resource not accessible by integration"
Section intitulée « "Resource not accessible by integration" »Error: Resource not accessible by integrationCe que ça signifie : Le workflow n'a pas la permission de faire ce qu'il essaie de faire (commenter une PR, créer un label, etc.).
Solution : Ajouter les permissions nécessaires :
permissions: contents: read # Lire le code pull-requests: write # Commenter les PRs issues: write # Créer/modifier les issues"Workflow does not have permission"
Section intitulée « "Workflow does not have permission" »Ce que ça signifie : Similaire au précédent, mais au niveau du repository.
Solution :
- Allez dans Settings → Actions → General
- Vérifiez "Workflow permissions"
- Sélectionnez "Read and write permissions" si nécessaire
"The workflow is not valid"
Section intitulée « "The workflow is not valid" »Ce que ça signifie : Erreur de syntaxe YAML.
Solution : Utilisez actionlint pour trouver l'erreur exacte.
"Context access might be invalid"
Section intitulée « "Context access might be invalid" »Ce que ça signifie : Vous essayez d'accéder à une propriété qui n'existe peut-être pas.
# ❌ Risqué si le step n'a pas d'outputs- run: echo ${{ steps.build.outputs.version }}
# ✅ Plus sûr avec une valeur par défaut- run: echo ${{ steps.build.outputs.version || 'unknown' }}Workflow de diagnostic
Section intitulée « Workflow de diagnostic »Voici un workflow complet à déclencher manuellement pour diagnostiquer votre environnement :
name: Diagnostic
on: workflow_dispatch: # Déclenchement manuel uniquement
# Aucun droit n'est nécessaire : le job ne fait que de l'introspectionpermissions: {}
jobs: diagnostic: runs-on: ubuntu-24.04 timeout-minutes: 10
steps: - name: Informations système run: | echo "=== Système d'exploitation ===" uname -a cat /etc/os-release
echo "=== Ressources ===" echo "CPU: $(nproc) cores" free -h df -h
echo "=== Outils installés ===" echo "Node: $(node --version 2>/dev/null || echo 'non installé')" echo "Python: $(python3 --version 2>/dev/null || echo 'non installé')" echo "Docker: $(docker --version 2>/dev/null || echo 'non installé')" echo "Git: $(git --version)"
- name: Contexte GitHub Actions env: # Les valeurs de contexte passent par env:, jamais dans run: en clair REPO: ${{ github.repository }} REF: ${{ github.ref }} COMMIT: ${{ github.sha }} ACTOR: ${{ github.actor }} EVENT: ${{ github.event_name }} RUN_ID: ${{ github.run_id }} RUN_NUMBER: ${{ github.run_number }} run: | echo "Repository: $REPO" echo "Branche/Tag: $REF" echo "Commit SHA: $COMMIT" echo "Acteur: $ACTOR" echo "Événement: $EVENT" echo "Run ID: $RUN_ID" echo "Run Number: $RUN_NUMBER"
- name: Test réseau run: | echo "=== DNS ===" nslookup github.com
echo "=== Connectivité ===" curl -s -o /dev/null -w "GitHub API: %{http_code}\n" https://api.github.com curl -s -o /dev/null -w "npm Registry: %{http_code}\n" https://registry.npmjs.org curl -s -o /dev/null -w "PyPI: %{http_code}\n" https://pypi.org
- name: Variables d'environnement run: | echo "=== Variables GitHub ===" env | grep GITHUB_ | sort
echo "=== PATH ===" echo "$PATH" | tr ':' '\n'Pour l'exécuter : Actions → Diagnostic → Run workflow.
Tester localement avec act
Section intitulée « Tester localement avec act »Plutôt que de pousser et attendre à chaque modification, utilisez act pour exécuter vos workflows sur votre machine.
# Installer actbrew install act
# Exécuter le workflow par défautact
# Exécuter un job spécifiqueact -j build
# Mode verbeux pour le debugact -vVoir le guide complet act.
À retenir
Section intitulée « À retenir »Le debug d'un workflow repose sur quatre réflexes : valider tôt, rendre les logs bavards, garder des traces, et raccourcir la boucle de test.
Valider la syntaxe
Utilisez actionlint avant de pousser pour éviter les erreurs évidentes.
Activer le debug
Les variables ACTIONS_RUNNER_DEBUG et ACTIONS_STEP_DEBUG révèlent les détails cachés.
Sauvegarder les artifacts
Utilisez if: failure() pour uploader les logs quand ça échoue.
Tester localement
act vous fait gagner du temps en évitant les allers-retours avec GitHub.
Checklist de debug :
- ✅ Vérifier que le workflow est dans
.github/workflows/ - ✅ Valider la syntaxe avec actionlint
- ✅ Vérifier les filtres de déclenchement (
on:,branches:,paths:) - ✅ Regarder l'onglet Actions (workflow désactivé ?)
- ✅ Activer les logs de debug si le problème persiste
- ✅ Inspecter les contexts pour comprendre l'état
- ✅ Sauvegarder les artifacts en cas d'échec