đŠ GitLab CI : comprendre le pipeline .gitlab-ci.yml, pour de bon
đ Introduction
La force de GitLab CI tient en une idĂ©e : tout le pipeline se dĂ©crit dans un seul fichier, .gitlab-ci.yml, versionnĂ© Ă la racine du dĂ©pĂŽt. Pas de configuration Ă©parpillĂ©e dans une interface web, pas dâoutil externe Ă brancher â GitLab dĂ©tecte ce fichier Ă chaque push et exĂ©cute ce quâil contient. La CI/CD vit avec le code, dans le mĂȘme commit.
Si vous avez dĂ©jĂ touchĂ© Ă une plateforme dâintĂ©gration continue â GitHub Actions par exemple â les concepts vous parleront, mĂȘme si le vocabulaire diffĂšre. Cet article pose les fondamentaux de GitLab CI : le modĂšle stages/jobs/runners, un premier pipeline complet, la distinction cache/artifacts qui pose souvent problĂšme, et le contrĂŽle du dĂ©clenchement avec rules. Les exemples sont volontairement agnostiques : ce qui compte, câest la mĂ©canique.
đ§± Le modĂšle : stages, jobs, runners
Trois notions structurent tout GitLab CI :
- Un job est lâunitĂ© de travail : un nom, une liste de commandes (
script), et lâenvironnement dans lequel elles tournent. - Un stage regroupe des jobs. Les stages sâexĂ©cutent en sĂ©quence (lâun aprĂšs lâautre), mais tous les jobs dâun mĂȘme stage tournent en parallĂšle. Câest le levier principal de rapiditĂ© : on parallĂ©lise ce qui peut lâĂȘtre.
- Un runner est lâagent qui exĂ©cute rĂ©ellement les jobs. GitLab.com fournit des runners partagĂ©s prĂȘts Ă lâemploi ; on peut aussi hĂ©berger les siens. Chaque runner utilise un executor â le plus courant est Docker, qui lance chaque job dans un conteneur frais Ă partir de lâimage dĂ©clarĂ©e.
Lâordre mental est donc : le pipeline enchaĂźne des stages, chaque stage lance ses jobs en parallĂšle, et chaque job sâexĂ©cute dans un conteneur sur un runner. Si aucun stage nâest dĂ©clarĂ©, GitLab en propose trois par dĂ©faut : build, test, deploy. Et un job sans stage explicite atterrit automatiquement dans test.
Au-delĂ des stages que vous dĂ©clarez, GitLab fournit deux stages implicites toujours disponibles, sans avoir Ă les lister : .pre et .post. .pre sâexĂ©cute avant tous les autres stages, .post aprĂšs tous les autres â et ce quelle que soit leur position dans le fichier. .pre est le stage de setup idĂ©al : prĂ©paration dâenvironnement, vĂ©rification de prĂ©requis, gĂ©nĂ©ration de variables Ă propager au reste du pipeline. .post sert plutĂŽt au nettoyage ou Ă des notifications de fin :
verifier-prerequis:
stage: .pre
script:
- ./scripts/check-env.sh
notifier:
stage: .post
when: always
script:
- ./scripts/notify.shđ Un premier .gitlab-ci.yml
Voici un pipeline complet et lisible. Il construit une application, la teste, puis la dĂ©ploie â chaque job dans un conteneur Node :
stages:
- build
- test
- deploy
default:
image: node:22-alpine
build:
stage: build
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
test:
stage: test
script:
- npm test
deploy:
stage: deploy
script:
- ./scripts/deploy.sh
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'Tout y est : le bloc default fixe lâimage de tous les jobs (image: peut aussi ĂȘtre dĂ©fini par job), chaque job dĂ©clare son stage et son script, le job build publie son rĂ©sultat en artifacts, et deploy ne se dĂ©clenche que sur la branche par dĂ©faut grĂące Ă rules. La variable $CI_DEFAULT_BRANCH fait partie des nombreuses variables prĂ©dĂ©finies fournies par GitLab (comme $CI_COMMIT_SHA ou $CI_REGISTRY_IMAGE).
đ§° Structurer un job : before_script, after_script, tags
Au-delĂ de script, deux mots-clĂ©s aident Ă factoriser les commandes rĂ©pĂ©tĂ©es. before_script sâexĂ©cute avant le script du job (prĂ©paration : login, dĂ©pendances systĂšmeâŠ), after_script aprĂšs, et mĂȘme si le job Ă©choue (nettoyage, remontĂ©e de logs). PlacĂ©s dans le bloc default, ils sâappliquent Ă tous les jobs :
default:
image: node:22-alpine
before_script:
- node --version
- npm ciLe mot-clĂ© tags, lui, choisit quel runner exĂ©cute le job. Chaque runner dĂ©clare des Ă©tiquettes, et un job ne part que sur un runner qui possĂšde toutes celles quâil rĂ©clame â indispensable pour cibler un runner self-hosted, une architecture prĂ©cise ou un environnement isolĂ© :
build-arm:
tags:
- arm64
- docker
script:
- ./build.shđ Cache ou artifacts : quelle diffĂ©rence ?
Câest la confusion la plus frĂ©quente, et les deux ne servent pas du tout Ă la mĂȘme chose.
Le cache sert Ă accĂ©lĂ©rer : il conserve des fichiers coĂ»teux Ă reconstituer â typiquement les dĂ©pendances tĂ©lĂ©chargĂ©es â dâun pipeline Ă lâautre. Câest un mĂ©canisme best-effort : le cache peut ĂȘtre absent (nouveau runner, expiration), et le job doit rester correct sans lui.
test:
stage: test
cache:
key:
files:
- package-lock.json
paths:
- .npm/
script:
- npm ci --cache .npm --prefer-offline
- npm testLes artifacts, eux, servent Ă transmettre : un job produit des fichiers (rĂ©sultat de build, rapports de test) que GitLab stocke, rend tĂ©lĂ©chargeables, et fournit aux jobs suivants qui en dĂ©pendent. Contrairement au cache, câest fiable et prĂ©vu pour circuler entre jobs et entre stages.
La rĂšgle mnĂ©motechnique : cache pour les dĂ©pendances, artifacts pour les rĂ©sultats. Un node_modules reconstructible va au cache ; un dist/ quâon veut dĂ©ployer va aux artifacts.
đŻ ContrĂŽler quand un job sâexĂ©cute : rules
Rares sont les jobs qui doivent tourner Ă chaque fois, sur toutes les branches. rules est lâoutil moderne pour dĂ©cider â il remplace lâancienne syntaxe only/except, encore fonctionnelle mais Ă Ă©viter pour un nouveau pipeline.
rules Ă©value une liste de conditions, dans lâordre, et sâarrĂȘte Ă la premiĂšre qui correspond :
deploy:
stage: deploy
script:
- ./scripts/deploy.sh
rules:
# déploie automatiquement sur la branche par défaut
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
# sur les autres branches, propose un déclenchement manuel
- if: '$CI_COMMIT_BRANCH'
when: manualOn combine des conditions if (sur les variables prĂ©dĂ©finies), des filtres changes (le job ne tourne que si certains fichiers ont changĂ©), des vĂ©rifications exists, et des clauses when (on_success, manual, neverâŠ). Câest expressif et centralisĂ©, lĂ oĂč only/except devenait vite illisible.
đ§© Aller plus loin : needs, variables, include
Trois mots-clĂ©s font passer un pipeline du niveau « ça marche » à « câest propre » :
needscasse la barriĂšre des stages pour crĂ©er un graphe de dĂ©pendances (DAG). Un job avecneeds: ['build']dĂ©marre dĂšs quebuildest fini, sans attendre la fin de tout le stage. Les pipelines deviennent nettement plus rapides.variablesdĂ©finit des valeurs rĂ©utilisables, globalement ou par job â pour ne pas rĂ©pĂ©ter une version, un chemin ou un nom dâimage.includeimporte de la configuration depuis lâextĂ©rieur, pour factoriser des pipelines entre projets. Il en existe plusieurs formes :include:local(un autre fichier du mĂȘme dĂ©pĂŽt),include:project(un fichier dâun autre projet GitLab),include:remote(une URL),include:template(un modĂšle fourni par GitLab) etinclude:component(un CI/CD component du catalogue).
include:
- local: '/ci/tests.yml'
- project: 'mon-groupe/ci-templates'
ref: main
file: '/deploy.yml'
- component: '$CI_SERVER_FQDN/mon-groupe/build@1.0'Les CI/CD components sont la brique moderne : des morceaux de pipeline rĂ©utilisables, versionnĂ©s et paramĂ©trables, publiĂ©s dans un catalogue et importĂ©s via include:component. Câest la direction que pousse GitLab pour mutualiser la CI proprement.
Ces trois leviers évitent la duplication, le péché mignon des fichiers CI qui grossissent.
â ïž Quelques prĂ©cautions
- Validez avant de pousser. GitLab fournit un outil CI Lint (dans le menu CI/CD du projet) qui vérifie la syntaxe du
.gitlab-ci.ymlsans lancer de pipeline. Un aller-retour de moins pour débusquer une indentation fautive. - Ne stockez jamais de secret en clair dans
.gitlab-ci.yml. Utilisez les variables CI/CD masquĂ©es et protĂ©gĂ©es dĂ©finies dans les rĂ©glages du projet, jamais une valeur codĂ©e en dur dans un fichier versionnĂ©. - Un cache nâest pas garanti. Ăcrivez vos jobs pour quâils fonctionnent mĂȘme cache vide. Si un fichier est indispensable au job suivant, câest un artifact, pas un cache.
- Ăpinglez vos images.
node:22-alpinereste prévisible ;node:latestchange sous vos pieds et rend les pipelines non reproductibles. - Surveillez la durée des artifacts. Ils consomment du stockage. Fixez une
expire_inraisonnable pour ceux qui nâont pas vocation Ă durer.
đ Conclusion
GitLab CI tient sur une poignĂ©e de concepts : des jobs regroupĂ©s en stages sĂ©quentiels, exĂ©cutĂ©s en parallĂšle par des runners dans des conteneurs. Autour de ce cĆur, quatre outils suffisent Ă couvrir lâessentiel : artifacts pour transmettre les rĂ©sultats, cache pour accĂ©lĂ©rer, rules pour dĂ©cider quand un job tourne, et needs/include pour garder le tout rapide et sans duplication.
Lâatout majeur reste la simplicitĂ© du modĂšle : un fichier, versionnĂ© avec le code, qui dĂ©crit tout le pipeline. Une fois le mental model en place, Ă©crire un .gitlab-ci.yml devient une formalitĂ© â et comme chaque job tourne dans une image Docker, une bonne maĂźtrise des fondamentaux de Docker rend lâexercice encore plus naturel.
đ Liens utiles
/faq
Questions fréquentes
OĂč se configure un pipeline GitLab CI ?
+
Dans un fichier nommĂ© « .gitlab-ci.yml » placĂ© Ă la racine du dĂ©pĂŽt. GitLab le dĂ©tecte automatiquement Ă chaque push et exĂ©cute le pipeline qu'il dĂ©crit. Tout â stages, jobs, cache, conditions de dĂ©clenchement â tient dans ce fichier versionnĂ© avec le code.
Quelle est la différence entre cache et artifacts dans GitLab CI ?
+
Le cache sert à réutiliser des dépendances (paquets téléchargés) entre pipelines pour accélérer les jobs, sans garantie de disponibilité. Les artifacts servent à transmettre des sorties d'un job à un autre (résultat de build, rapports) : ils sont stockés dans GitLab, téléchargeables et garantis pour les jobs qui en dépendent.
Qu'est-ce qu'un runner GitLab ?
+
Un runner est l'agent qui exécute concrÚtement les jobs. GitLab.com fournit des runners partagés clé en main ; on peut aussi héberger ses propres runners. Chaque runner utilise un « executor » (le plus courant est Docker, qui lance chaque job dans un conteneur à partir de l'image déclarée).
Faut-il utiliser rules ou only/except ?
+
rules est l'approche moderne et recommandée pour contrÎler quand un job s'exécute : elle combine conditions if, filtres de changements et clauses when dans une seule liste. only/except est l'ancienne syntaxe, encore fonctionnelle mais à éviter pour les nouveaux pipelines.