Aller au contenu
CI/CD & Automatisation medium

Lab 02 — Lire un échec et le corriger

14 min de lecture

logo gitlab

Un collègue a poussé du code et le pipeline est tout rouge. Trois jobs échouent, chacun pour une raison différente. Personne ne comprend pourquoi, et le réflexe est de relancer le pipeline « au cas où ». Spoiler : relancer ne corrige rien. Dans ce lab, vous allez apprendre à lire les logs d’un pipeline GitLab pour identifier précisément ce qui casse, puis corriger chaque erreur.

  • Lire les logs d’un job GitLab CI/CD pour identifier l’erreur exacte
  • Distinguer les types d’erreurs : lint (code), runtime (import manquant), configuration CI (stage invalide)
  • Corriger un pipeline cassé en modifiant le code et la configuration CI
  • Comprendre les exit codes et leur impact sur le statut d’un job

En entreprise, le pipeline rouge est le quotidien. Un collègue pousse du code sans tester localement, une dépendance disparaît, un copier-coller introduit une typo dans le .gitlab-ci.yml. Si vous ne savez pas lire les logs, vous perdez du temps à deviner, relancer, et deviner encore.

Situations réelles où ce lab vous aide :

  • Un développeur junior a poussé du code qui casse le lint et ne comprend pas le message de ruff
  • Une dépendance a été retirée de requirements.txt par erreur lors d’un merge
  • Un job échoue avec un message unknown stage après un renommage
  • L’équipe relance les pipelines « au cas où » au lieu de lire les logs
  • Lab 01 complété — ou partir directement de la branche starter/lab-02
  • Savoir naviguer dans l’interface GitLab (Build > Pipelines > cliquer sur un job)
  • Avoir lu Debug : lire les logs d’un pipeline (conseillé)

Si c’est votre premier lab, lisez d’abord la section Comment ça marche pour savoir comment forker et cloner le dépôt Pipeline Craft.

  1. Passez sur la branche de départ de ce lab

    Fenêtre de terminal
    cd pipeline-craft
    git checkout starter/lab-02

    Cette branche contient le .gitlab-ci.yml du Lab 01 — mais aussi 3 bugs que vous allez devoir trouver en lisant les logs du pipeline.

  2. Poussez la branche pour déclencher le pipeline sur votre fork

    Fenêtre de terminal
    git push origin starter/lab-02
  3. Observez le résultat dans Build > Pipelines sur votre fork GitLab

    Le pipeline démarre et… échoue. Vous voyez du rouge — c’est normal, c’est le but de ce lab.

Le pipeline contient un .gitlab-ci.yml fonctionnel (celui du Lab 01), mais 3 erreurs ont été introduites. Chaque erreur affecte un aspect différent du pipeline :

BugQuel job est touchéType d’erreur
🔴 Bug 1ruff-lintErreur de code (lint)
🔴 Bug 2ruff-lintDépendance manquante (import)
🔴 Bug 3pytestConfiguration CI invalide (stage)

Votre mission : identifier et corriger les 3 erreurs en lisant les logs.

  1. Ouvrez les logs du job ruff-lint

    Allez dans Build > Pipelines, cliquez sur le pipeline en échec, puis sur le job ruff-lint. Cherchez les lignes en rouge dans la sortie.

  2. Identifiez l’erreur

    Ruff signale deux erreurs dans app/main.py :

    app/main.py:3:8: F401 [*] `os` imported but unused
    app/main.py:3:1: I001 [*] Import block is un-sorted or un-formatted

    Ruff est un outil d’analyse statique de code Python (un “linter”). Il lit votre code et signale les problèmes sans l’exécuter. Ici, il a trouvé deux problèmes :

    • F401 : le code import os est présent en début de fichier, mais os n’est utilisé nulle part dans le reste du fichier. C’est un import mort. Ruff le signale parce qu’un import inutilisable peut masquer une vraie dépendance manquante.
    • I001 : l’import inutile désorganise l’ordre alphabetique des imports, ce que ruff exige aussi.

    Le format app/main.py:3:8 se lit : fichier app/main.py, ligne 3, colonne 8. C’est l’adresse exacte du problème dans le code.

  3. Corrigez

    Ouvrez app/main.py et supprimez la ligne import os :

    """Pipeline Craft — API FastAPI fil rouge pour les labs GitLab CI/CD."""
    from fastapi import FastAPI
    from app.config import settings
    from app.routes import health, items, version

Bug 2 — Un import manquant dans le code de production

Section intitulée « Bug 2 — Un import manquant dans le code de production »
  1. Cherchez dans les logs du job ruff-lint

    Ruff signale aussi une erreur dans app/routes/health.py :

    app/routes/health.py:4:8: F401 [*] `httpx` imported but unused

    Le fichier health.py importe httpx — une bibliothèque de requêtes HTTP — mais ne l’utilise pas. De plus, httpx est uniquement dans requirements-dev.txt (dépendances de développement), pas dans requirements.txt (production). Si ce code arrivait en production, le docker build échouerait avec un ModuleNotFoundError.

  2. Corrigez

    Ouvrez app/routes/health.py et supprimez la ligne import httpx :

    """Endpoint de health check."""
    from fastapi import APIRouter
    from app.models import HealthResponse
  1. Regardez la vue d’ensemble du pipeline dans Build > Pipelines

    Ce bug est différent des deux premiers. Au lieu d’un message d’erreur dans les logs d’un job, vous allez voir le job pytest marqué comme impossible à créer directement au niveau du pipeline.

    Voici la différence :

    • Bugs 1 et 2 : le job démarre, tourne, et échoue — vous lisez l’erreur dans les logs du job
    • Bug 3 : GitLab refuse de créer le job à cause d’une configuration invalide — il n’y a pas de logs de job à lire, l’erreur apparaît directement dans la description du pipeline

    Cherchez le message d’erreur en haut de la page du pipeline ou cliquez sur le job pytest qui affiche un statut particulier (orange ou une icône de configuration erronée).

  2. Identifiez l’erreur dans .gitlab-ci.yml

    Le job pytest déclare stage: tests (avec un s) — mais le stage défini dans stages: s’appelle test (sans s) :

    stages:
    - lint
    - test # ← défini comme "test"
    - build
    pytest:
    stage: tests # ← référence "tests" → n'existe pas !

    GitLab vérifie la configuration du .gitlab-ci.yml avant de lancer quoi que ce soit. Si un job référence un stage qui n’existe pas dans stages:, le pipeline s’arrête avant même d’essayer d’exécuter ce job. C’est une erreur de configuration, pas une erreur de code.

  3. Corrigez

    Remplacez stage: tests par stage: test dans le job pytest :

    pytest:
    stage: test
    image: python:3.12-slim
    before_script:
    - pip install -r requirements-dev.txt
    script:
    - pytest -v
  1. Vérifiez localement que le lint passe

    Fenêtre de terminal
    ruff check app/ tests/

    Sortie attendue : All checks passed!

  2. Committez et poussez

    Fenêtre de terminal
    git add app/main.py app/routes/health.py .gitlab-ci.yml
    git commit -m "fix: remove unused imports, fix stage name typo"
    git push origin starter/lab-02
  3. Vérifiez le pipeline dans GitLab

    Un nouveau pipeline se déclenche automatiquement. Cette fois, les 3 jobs doivent passer au vert.

  • Les 3 erreurs identifiées uniquement via les logs (pas en parcourant le code au hasard)
  • ruff check passe localement sans erreur
  • Le pipeline GitLab affiche 3 jobs verts après le fix
  • Vous savez expliquer la différence entre F401 (import inutilisé), un stage inconnu et un import de dépendance absente
app/main.py
import os
from fastapi import FastAPI
# app/routes/health.py
import httpx
from fastapi import APIRouter
# .gitlab-ci.yml
pytest:
stage: tests
stage: test

Trois modifications minimales — mais chacune corrige un type d’erreur différent :

FichierCorrectionType
app/main.pySuppression de import os inutiliséErreur de lint (F401)
app/routes/health.pySuppression de import httpx inutiliséDépendance fantôme
.gitlab-ci.ymlteststestErreur de configuration CI

Quand un job échoue, les logs GitLab peuvent faire plusieurs centaines de lignes. Voici comment les lire sans se perdre :

  1. Allez directement à la fin — l’erreur fatale est presque toujours dans les dernières lignes
  2. Cherchez le code de sortieexit code 1 signifie « erreur dans le script », exit code 127 signifie « commande introuvable »
  3. Repérez les sections — GitLab structure les logs en sections pliables (before_script, script, after_script). L’erreur est dans la section rouge
  4. Lisez le message complet — ne vous arrêtez pas à la première ligne d’erreur. Souvent, l’explication vient juste en dessous (ruff donne le numéro de ligne, pytest affiche la trace complète)
Exit codeSignification
0Succès — le job est vert
1Erreur dans le script (test échoué, lint en erreur, build cassé)
127Commande introuvable (outil non installé)
137Killed — le job a dépassé la limite mémoire (OOM)
SymptômeCauseSolution
« Relancer résoudra le problème »Faux — si le code est cassé, relancer ne change rienLire les logs d’abord, corriger, puis pousser
Le pipeline échoue avant même de lancer un jobErreur de syntaxe YAML ou stage inexistantVérifier le YAML dans Build > Pipeline editor
Ruff signale F401 mais ça ne casse pas pytestLe lint et les tests sont indépendants — une erreur de lint n’empêche pas les tests de tournerCorriger les deux : un code propre passe tous les jobs
ModuleNotFoundError dans le build DockerUn import Python référence un paquet absent de requirements.txtSoit ajouter le paquet dans requirements.txt, soit supprimer l’import inutile
  • Validez votre YAML localement avec la CLI glab : glab ci lint .gitlab-ci.yml vérifie la syntaxe et les stages sans pousser. Voir Valider un .gitlab-ci.yml.
  • Explorez allow_failure: true : ajoutez cette clé à un job pour que le pipeline continue même si le job échoue (le job apparaît en orange). Utile pour les vérifications non bloquantes.
  • Comparez avec solution/lab-02 : git diff starter/lab-02..solution/lab-02 montre exactement les 3 corrections attendues.
  • Lisez les logs, ne devinez pas — l’erreur exacte est toujours dans la sortie du job
  • Un import inutilisé (F401) n’est pas juste du bruit : il peut masquer une dépendance fantôme qui cassera en production
  • Un stage mal nommé empêche GitLab de créer le job — vérifiez que les noms dans stage: correspondent exactement à ceux de stages:
  • La commande glab ci lint permet de détecter les erreurs de configuration CI avant de pousser
  • Ne relancez jamais un pipeline sans avoir d’abord lu les logs du précédent échec

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn