
Votre pipeline lance tous les jobs à chaque commit, même quand ce n’est pas nécessaire ? Les rules permettent de contrôler précisément quand un job s’exécute — sur quelle branche, pour quel type de changement, avec quelle approbation.
Ce guide vous montre comment optimiser vos pipelines en exécutant uniquement ce qui est nécessaire, et comment éviter le piège classique des pipelines qui “skip” sans raison apparente.
Ce guide est fait pour vous si…
Section intitulée « Ce guide est fait pour vous si… »Prérequis
Section intitulée « Prérequis »Avant de continuer, assurez-vous de maîtriser :
- Variables GitLab CI/CD (les rules utilisent des variables)
- Structure de base d’un
.gitlab-ci.yml
Pourquoi les rules sont essentielles
Section intitulée « Pourquoi les rules sont essentielles »Sans rules, tous les jobs s’exécutent à chaque pipeline. C’est un gaspillage de ressources et de temps :
- Tests complets alors que seul le README a changé
- Build Docker alors que le code n’a pas bougé
- Déploiement automatique sans validation humaine
Les rules permettent d’exécuter uniquement ce qui est nécessaire, quand c’est nécessaire.
Les règles de base : if, changes, exists
Section intitulée « Les règles de base : if, changes, exists »if : condition sur une variable
Section intitulée « if : condition sur une variable »La règle la plus utilisée. Teste une expression qui renvoie vrai ou faux.
job: script: echo "Déploiement" rules: - if: '$CI_COMMIT_BRANCH == "main"'Opérateurs disponibles :
| Opérateur | Signification | Exemple |
|---|---|---|
== | Égal à | $VAR == "value" |
!= | Différent de | $VAR != "skip" |
=~ | Match regex | $VAR =~ /^feature-/ |
!~ | Ne match pas regex | $VAR !~ /wip/ |
&& | ET logique | $A == "x" && $B == "y" |
| ` | ` |
Variables les plus utilisées dans les rules :
| Variable | Valeur | Cas d’usage |
|---|---|---|
$CI_COMMIT_BRANCH | Nom de la branche | Limiter à main, develop |
$CI_COMMIT_TAG | Nom du tag (si tag) | Déployer uniquement les releases |
$CI_PIPELINE_SOURCE | Source du pipeline | push, merge_request_event, schedule |
$CI_MERGE_REQUEST_ID | ID de la MR | Jobs spécifiques aux MRs |
# Exemples pratiquesrules: # Sur la branche main uniquement - if: '$CI_COMMIT_BRANCH == "main"'
# Sur un tag de release (v1.0.0, v2.3.4...) - if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/'
# Uniquement pour les merge requests - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
# Pipeline planifié (cron) - if: '$CI_PIPELINE_SOURCE == "schedule"'changes : condition sur les fichiers modifiés
Section intitulée « changes : condition sur les fichiers modifiés »Exécute le job uniquement si certains fichiers ont été modifiés dans le commit.
build_frontend: script: npm run build rules: - changes: - "frontend/**/*" - "package.json" - "package-lock.json"Patterns supportés :
| Pattern | Signification |
|---|---|
src/*.js | Fichiers .js dans src/ |
src/**/*.js | Fichiers .js dans src/ et sous-dossiers |
*.md | Fichiers .md à la racine |
**/*.md | Tous les fichiers .md du projet |
exists : condition sur l’existence d’un fichier
Section intitulée « exists : condition sur l’existence d’un fichier »Exécute le job si un fichier existe dans le repository.
docker_build: script: docker build -t myapp . rules: - exists: - DockerfileUtile pour les monorepos où tous les projets n’ont pas les mêmes fichiers.
Combiner les conditions
Section intitulée « Combiner les conditions »Vous pouvez combiner if, changes et exists dans une même règle :
deploy_docs: script: ./deploy-docs.sh rules: # Sur main ET si des fichiers docs ont changé - if: '$CI_COMMIT_BRANCH == "main"' changes: - "docs/**/*" - "mkdocs.yml"Attention : dans une règle, les conditions sont en ET. Pour un OU, utilisez plusieurs règles :
job: rules: # Sur main OU sur un tag de release - if: '$CI_COMMIT_BRANCH == "main"' - if: '$CI_COMMIT_TAG =~ /^v\d+/'Contrôler le déclenchement avec when
Section intitulée « Contrôler le déclenchement avec when »when définit comment le job démarre si la règle matche.
Les valeurs de when
Section intitulée « Les valeurs de when »| Valeur | Comportement |
|---|---|
on_success | Démarre automatiquement si les jobs précédents ont réussi (défaut) |
on_failure | Démarre uniquement si un job précédent a échoué |
always | Démarre toujours, quel que soit le résultat des jobs précédents |
manual | Attend un clic dans l’interface pour démarrer |
delayed | Démarre automatiquement après un délai |
never | Ne démarre jamais (exclut le job) |
Exemples pratiques
Section intitulée « Exemples pratiques »Déploiement manuel en production :
deploy_prod: script: ./deploy.sh production rules: - if: '$CI_COMMIT_BRANCH == "main"' when: manualNotification en cas d’échec :
notify_failure: script: ./send-slack-alert.sh rules: # Condition explicite + when: on_failure - if: '$CI_PIPELINE_SOURCE' when: on_failureDéploiement différé (canary) :
deploy_canary: script: ./deploy.sh canary rules: - if: '$CI_COMMIT_BRANCH == "main"' when: delayed start_in: 30 minutesExclure explicitement :
heavy_tests: script: ./run-all-tests.sh rules: # Pas sur les branches WIP - if: '$CI_COMMIT_BRANCH =~ /^wip-/' when: never # Sinon, exécuter normalement - when: on_successworkflow:rules : contrôler le pipeline entier
Section intitulée « workflow:rules : contrôler le pipeline entier »workflow:rules détermine si le pipeline lui-même doit être créé. C’est différent des rules au niveau des jobs qui contrôlent chaque job individuellement.
Pourquoi c’est important
Section intitulée « Pourquoi c’est important »Sans workflow:rules, GitLab crée un pipeline pour chaque push, même si aucun job ne doit s’exécuter. Cela crée du bruit dans l’interface.
Avec workflow:rules, vous pouvez empêcher la création du pipeline dans certains cas.
Exemple : éviter les pipelines en double
Section intitulée « Exemple : éviter les pipelines en double »workflow: rules: # Pas de pipeline si c'est un tag (on déploie via autre workflow) - if: '$CI_COMMIT_TAG' when: never # Pas de pipeline si la branche a une MR ouverte # (le pipeline MR suffit) - if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS' when: never # Pour les merge requests - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' # Pour les pushs sur les branches - if: '$CI_COMMIT_BRANCH'Le piège classique : pipeline qui “skip”
Section intitulée « Le piège classique : pipeline qui “skip” »Symptôme : vous poussez du code, le pipeline apparaît comme “skipped” ou ne démarre pas du tout.
Cause probable : workflow:rules empêche la création du pipeline.
Diagnostic :
- Vérifiez votre section
workflow:rules - Identifiez quelle règle matche avec vos conditions actuelles
- Si aucune règle ne matche, le pipeline est skipped
# ❌ Problème : ce workflow ne matche jamais pour les pushs simplesworkflow: rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
# ✅ Solution : ajouter les autres casworkflow: rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - if: '$CI_COMMIT_BRANCH'Exemples pratiques
Section intitulée « Exemples pratiques »Pipeline optimisé par type de changement
Section intitulée « Pipeline optimisé par type de changement »workflow: rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - if: '$CI_COMMIT_BRANCH == "main"' - if: '$CI_COMMIT_TAG'
stages: - lint - build - test - deploy
# Lint : toujours (rapide, peu coûteux)lint: stage: lint script: npm run lint
# Build : seulement si le code a changébuild: stage: build script: npm run build rules: - if: '$CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event"' changes: - "src/**/*" - "package*.json"
# Tests : seulement si le code a changétest: stage: test script: npm test rules: - if: '$CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event"' changes: - "src/**/*" - "tests/**/*" - "package*.json"
# Deploy staging : auto sur maindeploy_staging: stage: deploy script: ./deploy.sh staging environment: name: staging rules: - if: '$CI_COMMIT_BRANCH == "main"'
# Deploy prod : manuel sur tagsdeploy_prod: stage: deploy script: ./deploy.sh production environment: name: production rules: - if: '$CI_COMMIT_TAG =~ /^v\d+/' when: manualÉviter les exécutions redondantes
Section intitulée « Éviter les exécutions redondantes »workflow: rules: # Un tag déclenche son propre pipeline, pas besoin du push - if: '$CI_COMMIT_TAG' # Pour les MRs, utiliser le pipeline MR - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' # Pour les pushs sur branches sans MR ouverte - if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS' when: never - if: '$CI_COMMIT_BRANCH'Erreurs fréquentes
Section intitulée « Erreurs fréquentes »| Symptôme | Cause probable | Solution |
|---|---|---|
| Pipeline entier “skipped” | workflow:rules ne matche pas | Ajouter une règle pour votre cas |
| Job jamais exécuté | Ordre des règles (never en dernier) | Mettre les exclusions en premier |
| Job toujours exécuté | Pas de règle, comportement par défaut | Ajouter rules: explicites |
changes toujours vrai | Pipeline schedule ou web | changes ne fonctionne qu’avec push/MR |
| Variables non définies dans rules | Variable inexistante | Tester avec $VAR (vide = faux) |
Migrer depuis only/except
Section intitulée « Migrer depuis only/except »Si vous avez des pipelines avec only/except, migrez vers rules (plus flexible et plus clair).
# ❌ Ancien style (deprecated)deploy: script: ./deploy.sh only: - main except: - schedules
# ✅ Nouveau styledeploy: script: ./deploy.sh rules: - if: '$CI_PIPELINE_SOURCE == "schedule"' when: never - if: '$CI_COMMIT_BRANCH == "main"'À retenir
Section intitulée « À retenir »rulescontrôle quand un job s’exécute,workflow:rulescontrôle quand le pipeline est créé.- Première règle qui matche gagne — ordonnez vos règles du plus spécifique au plus général.
ifteste des variables,changesteste les fichiers modifiés,existsteste l’existence.when: neveren premier pour exclure,when: on_successen dernier par défaut.changesne fonctionne pas avec les pipelinesscheduleouweb.- Pipeline “skipped” = vérifier
workflow:rulesen premier.
Testez vos connaissances
Section intitulée « Testez vos connaissances »Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications