Le fichier .gitlab-ci.yml pilote toute ton intégration et ton déploiement continus sur GitLab. Mais entre rules, needs, cache, artifacts et extends, on oublie vite la bonne syntaxe. Cette antisèche réunit les mots-clés GitLab CI indispensables, avec des exemples prêts à copier et un pipeline complet pour un projet PHP.
GitLab CI transforme ton dépôt en usine automatique : à chaque git push, GitLab lance des jobs qui installent les dépendances, exécutent les tests, analysent le code et déploient l’application. Tout est décrit dans un seul fichier YAML, à la racine du projet : .gitlab-ci.yml.
Le problème, c’est que ce fichier accepte des dizaines de mots-clés, avec leurs options et leurs pièges. Cette antisèche se concentre sur ceux que l’on utilise vraiment, classés par usage, avec pour chacun un exemple court. Garde-la ouverte pendant que tu écris tes pipelines GitLab CI : tu gagneras un temps précieux.

Un pipeline GitLab CI, c’est des stages (étapes) qui contiennent des jobs (tâches). Les mots-clés à connaître en priorité : stages, image, script, rules, needs, cache, artifacts, variables et environment.
Les notions de base de GitLab CI
Avant les mots-clés, quatre notions structurent tout pipeline GitLab CI.
| Notion | Définition | Exemple |
|---|---|---|
| — | — | — |
| Pipeline | L’ensemble des jobs lancés pour un commit, une merge request ou une planification | Le pipeline du commit a1b2c3d |
| Stage | Une étape du pipeline ; les stages s’exécutent dans l’ordre | build, test, deploy |
| Job | Une tâche, avec ses commandes ; les jobs d’un même stage tournent en parallèle | tests-unitaires, lint |
| Runner | La machine qui exécute les jobs | Un runner partagé de GitLab.com ou ton propre serveur |
Le principe d’exécution est simple : tous les jobs d’un stage doivent réussir pour que le stage suivant démarre (sauf si tu utilises needs, qu’on verra plus loin). Si un job échoue, les stages suivants ne sont pas lancés.
Le pipeline GitLab CI minimal
Voici le plus petit .gitlab-ci.yml utile : un job qui exécute les tests d’un projet PHP à chaque push.
# .gitlab-ci.yml
stages:
- test
tests:
stage: test
image: php:8.4-cli
script:
- php -v
- php vendor/bin/phpunit
Dès que ce fichier est poussé, GitLab CI crée un pipeline. Tu le suis dans Build → Pipelines de ton projet, et chaque job affiche son journal en direct.
Mots-clés GitLab CI : structure du pipeline
| Mot-clé | Rôle | Exemple |
|---|---|---|
| — | — | — |
stages | Liste et ordre des étapes | stages: [build, test, deploy] |
stage | Étape à laquelle appartient un job | stage: test |
default | Valeurs par défaut pour tous les jobs | default: { image: php:8.4-cli } |
include | Inclure d’autres fichiers de configuration | include: { local: ci/tests.yml } |
workflow | Décider si un pipeline doit être créé | workflow: { rules: [...] } |
variables | Variables globales ou propres à un job | variables: { APP_ENV: test } |
default:
image: php:8.4-cli
before_script:
- composer install --no-interaction --prefer-dist
include:
- local: ci/tests.yml
- template: Jobs/SAST.gitlab-ci.yml
Le mot-clé include est précieux dès que ton fichier GitLab CI grossit : tu peux découper la configuration en plusieurs fichiers, réutiliser des modèles fournis par GitLab (template), ou partager une configuration commune entre plusieurs projets (project).
Mots-clés GitLab CI : définir un job
| Mot-clé | Rôle |
|---|---|
| — | — |
image | Image Docker dans laquelle le job s’exécute |
services | Conteneurs annexes disponibles pendant le job (base de données, Redis…) |
before_script | Commandes exécutées avant script |
script | Commandes principales du job (obligatoire) |
after_script | Commandes exécutées après, même en cas d’échec |
tags | Choisir un runner précis |
timeout | Durée maximale du job |
retry | Relancer automatiquement en cas d’échec |
allow_failure | Ne pas bloquer le pipeline si ce job échoue |
interruptible | Annuler le job si un pipeline plus récent démarre |
tests:
stage: test
image: php:8.4-cli
services:
- name: mysql:8.4
alias: db
variables:
MYSQL_DATABASE: app_test
MYSQL_ROOT_PASSWORD: root
DB_HOST: db
script:
- docker-php-ext-install pdo_mysql
- composer install --no-interaction
- php vendor/bin/phpunit
timeout: 15m
retry: 1
interruptible: true
Comme dans Docker Compose, le service est joignable par son alias (db), jamais par localhost. Si les commandes Docker te sont moins familières, notre antisèche des commandes Docker t’aidera à comprendre ce qui se passe dans ces conteneurs.
Mots-clés GitLab CI : quand lancer un job avec rules
rules est le mot-clé le plus puissant, et le plus important, de GitLab CI. Il décide si un job est ajouté au pipeline, et comment. Les règles sont évaluées dans l’ordre : la première qui correspond l’emporte.
| Clause | Rôle | Exemple |
|---|---|---|
| — | — | — |
if | Condition sur des variables | if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH |
changes | Fichiers modifiés | changes: [src/**/*.php] |
exists | Présence d’un fichier | exists: [composer.json] |
when | Comportement si la règle correspond | when: manual, when: never |
deploy:
stage: deploy
script: ./deploy.sh
rules:
# Jamais pour les pipelines planifiés
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
# Déploiement manuel depuis la branche principale
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: manual
Les valeurs de when les plus utiles :
on_success(par défaut) : lancer si les stages précédents ont réussi.manual: attendre un clic dans l’interface.always: lancer quoi qu’il arrive, par exemple pour un nettoyage.on_failure: lancer seulement si un job précédent a échoué, par exemple pour une notification.delayed: lancer après un délai, avecstart_in: 30 minutes.never: ne jamais ajouter le job.
Les anciens mots-clés only et except fonctionnent encore, mais ne sont plus développés par GitLab, et ne peuvent pas être combinés avec rules dans un même job. Pour toute nouvelle configuration GitLab CI, utilise rules.
Mots-clés GitLab CI : workflow et pipelines de merge request
workflow: rules s’applique au pipeline entier : il décide si un pipeline doit être créé. C’est la solution au problème classique des pipelines en double (un pour le push sur la branche, un pour la merge request).
workflow:
rules:
# Pipeline pour les merge requests
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# Pas de pipeline de branche si une merge request est ouverte
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
# Pipeline pour les autres branches et les tags
- if: $CI_COMMIT_BRANCH
- if: $CI_COMMIT_TAG

Mots-clés GitLab CI : accélérer avec cache, artifacts et needs
Trois mots-clés permettent de rendre un pipeline GitLab CI beaucoup plus rapide. On les confond souvent, alors voici la différence.
| Mot-clé | À quoi il sert | Exemple typique |
|---|---|---|
| — | — | — |
cache | Réutiliser des fichiers d’un pipeline à l’autre pour gagner du temps | Le dossier vendor/ de Composer, node_modules/ |
artifacts | Transmettre des fichiers d’un job à l’autre dans le même pipeline, ou les télécharger | Le dossier dist/ compilé, un rapport de tests |
needs | Lancer un job dès que ceux dont il dépend sont terminés, sans attendre la fin du stage | Lancer le déploiement dès que le build est prêt |
build:
stage: build
image: node:24
cache:
key:
files:
- package-lock.json
paths:
- node_modules/
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 week
deploy:
stage: deploy
needs: [build]
script:
- ls dist/
La clé cache:key:files est une astuce importante : le cache est recréé uniquement quand le fichier package-lock.json change. Tant que tes dépendances ne bougent pas, GitLab CI réutilise le cache et l’installation devient quasi instantanée.
Utiliser cache pour transmettre le résultat d’un build au job de déploiement. Le cache n’est pas garanti : il peut être absent ou provenir d’un autre runner. Pour passer des fichiers entre jobs, utilise toujours artifacts.
Mots-clés GitLab CI : réutiliser la configuration
Quand plusieurs jobs se ressemblent, évite le copier-coller. GitLab CI offre trois mécanismes de réutilisation.
# 1. Un job caché (commence par un point) + extends
.php-base:
image: php:8.4-cli
before_script:
- composer install --no-interaction
tests-unitaires:
extends: .php-base
script: php vendor/bin/phpunit --testsuite unit
analyse:
extends: .php-base
script: php vendor/bin/phpstan analyse src
# 2. !reference : réutiliser une partie précise d'un autre job
lint:
script:
- !reference [.php-base, before_script]
- php vendor/bin/php-cs-fixer check
# 3. parallel:matrix : le même job pour plusieurs versions
compat:
image: php:${PHP_VERSION}-cli
parallel:
matrix:
- PHP_VERSION: ["8.3", "8.4", "8.5"]
script: php -v
Le job compat est lancé trois fois, une par version de PHP, en parallèle. C’est idéal pour vérifier la compatibilité d’une bibliothèque avec plusieurs versions.
Les variables prédéfinies GitLab CI à connaître
GitLab CI fournit automatiquement des dizaines de variables dans chaque job. Voici les plus utiles au quotidien.
| Variable | Contenu |
|---|---|
| — | — |
$CI_COMMIT_BRANCH | Nom de la branche (absente pour les tags et les merge requests) |
$CI_COMMIT_TAG | Nom du tag, si le pipeline a été lancé par un tag |
$CI_DEFAULT_BRANCH | Branche par défaut du projet (souvent main) |
$CI_PIPELINE_SOURCE | Origine du pipeline : push, merge_request_event, schedule, web… |
$CI_COMMIT_SHORT_SHA | Les 8 premiers caractères du commit |
$CI_COMMIT_REF_SLUG | Nom de branche ou de tag simplifié, utilisable dans une URL |
$CI_REGISTRY_IMAGE | Adresse de l’image dans le registre de conteneurs du projet |
$CI_JOB_TOKEN | Jeton temporaire pour accéder à l’API ou au registre |
Les secrets (mots de passe de déploiement, clés d’API) ne s’écrivent jamais dans le fichier .gitlab-ci.yml. Déclare-les dans Settings → CI/CD → Variables, en cochant Masked (masquée dans les journaux) et Protected (disponible uniquement sur les branches protégées). C’est le même principe que pour un fichier .env : les secrets restent hors du dépôt.
Exemple complet : pipeline GitLab CI pour un projet PHP
Voici un pipeline GitLab CI complet et réaliste pour une application PHP : installation, tests et analyse en parallèle, construction d’une image Docker, puis déploiement manuel en production.
stages:
- install
- test
- build
- deploy
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_COMMIT_BRANCH
default:
image: php:8.4-cli
interruptible: true
composer:
stage: install
image: composer:2
script:
- composer install --no-interaction --prefer-dist
cache:
key:
files: [composer.lock]
paths: [vendor/]
artifacts:
paths: [vendor/]
expire_in: 1 day
phpunit:
stage: test
needs: [composer]
script:
- php vendor/bin/phpunit --log-junit rapport.xml
artifacts:
reports:
junit: rapport.xml
phpstan:
stage: test
needs: [composer]
script:
- php vendor/bin/phpstan analyse src --no-progress
image-docker:
stage: build
image: docker:27
services: [docker:27-dind]
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
production:
stage: deploy
needs: [image-docker]
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: manual
environment:
name: production
url: https://mon-app.fr
script:
- ./deploy.sh $CI_COMMIT_SHORT_SHA
Ce pipeline illustre la plupart des mots-clés de cette antisèche. Grâce à artifacts:reports:junit, les résultats des tests s’affichent directement dans la merge request. Grâce à environment, GitLab garde l’historique des déploiements et propose un lien direct vers l’application.

Les erreurs GitLab CI les plus fréquentes
| Message ou symptôme | Cause probable | Solution |
|---|---|---|
| — | — | — |
jobs config should contain at least one visible job | Tous les jobs commencent par un point, ou aucun n’est défini | Ajoute au moins un job sans point au début de son nom |
job: chosen stage does not exist | Le stage du job n’est pas déclaré dans stages | Ajoute le stage à la liste stages |
mapping values are not allowed here | Erreur d’indentation YAML | Indente avec des espaces (jamais de tabulations), deux par niveau |
| Le job n’apparaît pas dans le pipeline | Une règle rules ne correspond pas, ou when: never | Vérifie l’ordre des règles et les variables utilisées |
| Les fichiers du build ont disparu au job suivant | Utilisation de cache au lieu d’artifacts | Déclare les fichiers dans artifacts:paths |
vendor/bin/phpunit: not found | Les dépendances ne sont pas installées dans ce job | Ajoute composer install ou récupère vendor/ via artifacts et needs |
L’indentation est de loin la première source d’erreurs dans un fichier GitLab CI. YAML est très strict : un espace de trop ou de moins change complètement le sens d’une ligne. Configure ton éditeur pour afficher les espaces et utiliser deux espaces par niveau, et l’essentiel de ces erreurs disparaîtra. L’éditeur de pipeline de GitLab signale d’ailleurs la ligne exacte de chaque erreur de syntaxe, avant même que tu ne lances le pipeline.
Autre réflexe utile : quand un pipeline GitLab CI se comporte de façon inattendue, ouvre l’onglet Full configuration de l’éditeur de pipeline. Il affiche la configuration finale après fusion de tous les include et extends. C’est souvent là qu’on découvre qu’un modèle inclus redéfinit une valeur ou qu’une règle héritée bloque un job.
Déboguer un pipeline GitLab CI
- Valide ta syntaxe avant de pousser : l’éditeur de pipeline de GitLab (Build → Pipeline editor) vérifie le fichier en direct et affiche la configuration finale,
includecompris. - Lis le journal complet du job : l’erreur se trouve souvent quelques lignes au-dessus de la dernière.
- Ajoute temporairement des commandes de diagnostic :
env | sort,ls -la,php -v. - Un job ne démarre jamais ? Vérifie les
rules(une règlewhen: neverplacée trop haut) et lestags(aucun runner ne correspond). - Un job « en attente » sans fin ? Aucun runner disponible : vérifie les runners du projet dans Settings → CI/CD → Runners.
Commence petit : un seul job de tests. Ajoute ensuite le cache, puis l’analyse de code, puis le déploiement. Un fichier GitLab CI construit progressivement est beaucoup plus facile à déboguer qu’une configuration complète copiée d’un coup. Et garde notre antisèche Git à côté pour les commandes de branches et de tags.
FAQ
Quelle différence entre cache et artifacts dans GitLab CI ?
Le cache accélère les pipelines en réutilisant des fichiers d’un pipeline à l’autre, sans garantie de disponibilité. Les artifacts transmettent des fichiers entre les jobs d’un même pipeline, de façon garantie, et peuvent être téléchargés depuis l’interface.
Faut-il utiliser rules ou only/except ?
Utilise rules. Les mots-clés only et except sont encore acceptés mais ne sont plus développés, et ils ne peuvent pas être mélangés avec rules dans un même job. Toute nouvelle configuration GitLab CI devrait reposer sur rules.
Comment éviter les pipelines en double avec les merge requests ?
Ajoute un bloc workflow:rules qui crée un pipeline pour les merge requests et bloque le pipeline de branche quand une merge request est ouverte, grâce à la variable $CI_OPEN_MERGE_REQUESTS.
Où stocker les mots de passe utilisés par un pipeline GitLab CI ?
Dans les variables CI/CD du projet (Settings, CI/CD, Variables), avec les options Masked et Protected. Ne les écris jamais dans le fichier .gitlab-ci.yml, qui est versionné avec le code.
Pour tirer le meilleur de cette antisèche GitLab CI, garde-la ouverte à côté de l’éditeur de pipeline pendant tes premières semaines. Chaque fois que tu écris un nouveau job, vérifie les mots-clés utilisés, puis observe le résultat dans le pipeline : tu retiendras la syntaxe beaucoup plus vite qu’en lisant toute la documentation d’un coup.
Et quand un pipeline réussit enfin, prends une minute pour relire ton fichier : supprime les lignes inutiles et ajoute un commentaire sur chaque règle un peu subtile.
GitLab CI : le résumé à retenir
- Un pipeline GitLab CI est composé de stages exécutés dans l’ordre, qui contiennent des jobs exécutés en parallèle.
- Chaque job a au minimum un
script, et souvent uneimage, desruleset desvariables. rulesdécide quand un job s’exécute,workflow:rulesdécide si le pipeline est créé.cacheaccélère,artifactstransmet,needsenchaîne sans attendre la fin du stage.- Les secrets vont dans les variables CI/CD masquées et protégées, jamais dans le fichier.
Avec ces mots-clés GitLab CI, tu peux écrire l’essentiel des pipelines dont un projet web a besoin, de la simple exécution des tests au déploiement en production.
Conclusion
Un bon pipeline GitLab CI change la façon de travailler : chaque modification est testée automatiquement, les erreurs sont détectées avant d’atteindre la production, et le déploiement devient un simple clic. Commence par un job de tests, enrichis-le progressivement avec cette antisèche, et tu auras en quelques heures une chaîne d’intégration continue digne d’une équipe professionnelle. Pour préparer ton environnement local avant d’automatiser, notre guide Docker pour développeur web est le complément idéal.
Sources
- Documentation GitLab : référence de la syntaxe .gitlab-ci.yml
- Documentation GitLab : variables prédéfinies
- Documentation GitLab : rules
- Documentation GitLab : cache et artifacts

