
Votre pipeline a 50 jobs et devient ingérable ? Les pipelines parent-enfant permettent de découper un pipeline complexe en sous-pipelines indépendants. Le parent orchestre, les enfants exécutent.
Ce guide est fait pour vous si...
Section intitulée « Ce guide est fait pour vous si... »Les pipelines parent-enfant répondent à quatre situations bien distinctes, et vous n'avez probablement pas besoin des quatre. Chaque carte ci-dessous mène directement à la section correspondante : suivez celle qui décrit votre problème plutôt que de lire la page dans l'ordre.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »À la fin de ce module, vous saurez :
- Déclencher un pipeline enfant :
trigger: includeavec un fichier local - Contrôler l'attente :
strategy: dependvsstrategy: mirror - Passer des variables : explicites ou via dotenv
- Partager des artefacts :
needs:pipeline:jobentre parent et enfant - Déclencher multi-projet :
trigger: projectvers un autre repo - Organiser un monorepo : un pipeline par composant
Prérequis
Section intitulée « Prérequis »Avant de continuer, assurez-vous de maîtriser :
Pourquoi des pipelines parent-enfant ?
Section intitulée « Pourquoi des pipelines parent-enfant ? »Un pipeline enfant est un pipeline à part entière, avec ses propres stages, ses propres jobs et son propre identifiant, déclenché depuis un autre pipeline. Cette séparation change trois choses : le fichier de configuration se scinde, l'interface GitLab affiche chaque composant isolément, et un échec reste circonscrit à son périmètre. Le prix à payer est une frontière réelle entre les deux pipelines, que ni les variables ni les artefacts ne franchissent tout seuls.
Le problème : un pipeline monolithique
Section intitulée « Le problème : un pipeline monolithique »Sans découpage, votre .gitlab-ci.yml ressemble à ça :
# ❌ Un fichier de 500 lignes avec TOUT dedansbuild_frontend: script: npm run buildbuild_backend: script: go buildbuild_api: script: python setup.pytest_frontend: script: npm testtest_backend: script: go testtest_api: script: pytestdeploy_frontend: # ... et ça continueProblèmes concrets :
- Maintenance : Qui est responsable de quoi ? Tout le monde modifie le même fichier.
- Lisibilité : 50 jobs dans un seul fichier = cauchemar à débugger.
- Performance : Le backend n'a pas changé ? Dommage, on le rebuild quand même.
- Isolation : Le test frontend échoue ? Impossible de déployer le backend qui est OK.
La solution : découper par composant
Section intitulée « La solution : découper par composant »Le découpage suit l'organisation du dépôt : un fichier de configuration par répertoire applicatif, maintenu par l'équipe qui possède ce code. Le fichier racine ne contient plus que les jobs de déclenchement, ce qui le maintient lisible même quand le projet grossit.
| Sans parent-enfant | Avec parent-enfant |
|---|---|
Un seul .gitlab-ci.yml géant | Fichiers séparés par composant |
| Difficile à maintenir | Responsabilité claire (l'équipe front gère frontend/.gitlab-ci.yml) |
| Tout s'exécute toujours | Exécution conditionnelle par composant |
| Un échec bloque tout | Isolation des problèmes |

Configuration de base
Section intitulée « Configuration de base »Le montage minimal tient en deux fichiers : un parent qui déclenche, un enfant qui travaille. Aucun des deux ne demande de configuration particulière du côté de GitLab, tout se joue dans le YAML. Le seul mot-clé nouveau à connaître est trigger:.
C'est quoi un "trigger" ?
Section intitulée « C'est quoi un "trigger" ? »Un trigger est un job spécial qui ne fait qu'une chose : lancer un autre pipeline. Il ne contient pas de script:, juste une instruction trigger: qui dit "à ce moment, démarre ce pipeline enfant".
Pipeline parent : uniquement des jobs de déclenchement
Section intitulée « Pipeline parent : uniquement des jobs de déclenchement »Le fichier .gitlab-ci.yml à la racine du projet ne contient plus aucune tâche de build ou de test : il se limite à déclarer quels enfants lancer et à quel moment. Un seul stage suffit dans le cas le plus simple, puisque les jobs de déclenchement s'exécutent en parallèle :
# .gitlab-ci.yml (racine du projet)
stages: - triggers # Un seul stage : déclencher les enfants
# 🎭 Job qui déclenche le pipeline frontendtrigger_frontend: stage: triggers trigger: # 👈 Mot-clé magique : ce n'est pas un job normal include: frontend/.gitlab-ci.yml # 👈 Chemin vers le fichier CI de l'enfant strategy: depend # 👈 "Attends que l'enfant finisse"
# 🎭 Job qui déclenche le pipeline backendtrigger_backend: stage: triggers trigger: include: backend/.gitlab-ci.yml strategy: dependDécortiquons :
trigger:, Ce mot-clé transforme le job en "lanceur de pipeline". Pas descript:, pas deimage:.include: frontend/.gitlab-ci.yml, Le chemin du fichier CI enfant, relatif à la racine du repo.strategy: depend, Le parent attend la fin de l'enfant avant de continuer. Sans ça, il passe immédiatement au job suivant.
Pipeline enfant : un pipeline normal
Section intitulée « Pipeline enfant : un pipeline normal »Le fichier enfant est un .gitlab-ci.yml classique. Il ne sait même pas qu'il est "enfant", il s'exécute normalement :
stages: - build - test
build: stage: build image: node:20 # Son propre environnement script: - npm ci - npm run build artifacts: paths: - dist/
test: stage: test image: node:20@sha256:8f693eaa7e0a8e71560c9a82b55fd54c2ae920a2ba5d2cde28bac7d1c01c9ba5 script: - npm testAvantage : L'équipe frontend peut modifier ce fichier sans toucher au reste. Chaque composant a son propre "mini-pipeline".
Options de trigger
Section intitulée « Options de trigger »Trois options suffisent à couvrir la quasi-totalité des besoins. include désigne le fichier de l'enfant, strategy décide si le parent attend son résultat, forward contrôle la transmission des variables. La deuxième est celle qu'on oublie le plus souvent, avec les conséquences les plus fâcheuses.
include : fichier local
Section intitulée « include : fichier local »La forme la plus simple, l'enfant est un fichier dans le même repo :
trigger_job: trigger: include: path/to/child.yml # Chemin relatif depuis la racine du repostrategy: depend, le paramètre le plus important
Section intitulée « strategy: depend, le paramètre le plus important »Sans strategy: depend, voici ce qui se passe :
Parent : trigger_frontend → ✅ success (immédiatement !)Enfant : → build → test → ❌ échoueRésultat : le parent est VERT alors que l'enfant a échoué !Avec strategy: depend :
Parent : trigger_frontend → ⌛ attend...Enfant : → build → test → ❌ échoueRésultat : le parent passe en ❌ échec aussitrigger_job: trigger: include: child.yml strategy: depend # ✅ Attend la fin et hérite du statutstrategy: depend vs strategy: mirror, quelle différence ?
Section intitulée « strategy: depend vs strategy: mirror, quelle différence ? »Les deux attendent l'enfant, mais diffèrent sur les cas limites :
| Situation | depend | mirror |
|---|---|---|
| Enfant réussit | Parent ✅ | Parent ✅ |
| Enfant échoue | Parent ❌ | Parent ❌ |
| Enfant annulé (cancel) | Parent ❌ (failed) | Parent ⏹ (cancelled) |
| Enfant en warning | Parent ✅ | Parent ⚠️ (warning) |
En pratique :
depend: le plus courant, convient à 99% des casmirror: reflet exact du statut enfant (utile avec les pipelines auto-cancelés)
trigger_job: trigger: include: child.yml strategy: mirror # Miroir strict du statut enfantforward : transmettre automatiquement les variables
Section intitulée « forward : transmettre automatiquement les variables »Par défaut, l'enfant ne reçoit pas les variables du parent. Avec forward:, vous pouvez transmettre automatiquement :
trigger_job: trigger: include: child.yml forward: yaml_variables: true # Variables définies dans le YAML parent pipeline_variables: true # Variables passées via l'interface web ou APIQuand utiliser forward: ?
- Vous avez beaucoup de variables à passer
- Vous voulez que l'enfant hérite du contexte complet du parent
Quand utiliser variables: explicites ? (voir section suivante)
- Vous voulez contrôler précisément ce qui est passé
- Vous avez besoin de renommer ou transformer des variables
Passer des variables à l'enfant
Section intitulée « Passer des variables à l'enfant »Deux méthodes coexistent et répondent à des moments différents. La première déclare les valeurs dans le job de déclenchement, elle convient quand elles sont connues au moment d'écrire le YAML. La seconde s'appuie sur un rapport dotenv, un fichier de paires clé-valeur produit par un job précédent, pour transmettre une information calculée pendant l'exécution.
Le problème : l'enfant est isolé
Section intitulée « Le problème : l'enfant est isolé »Un pipeline enfant s'exécute dans son propre contexte. Il ne voit pas automatiquement les variables du parent. Si le parent connaît la version à déployer (VERSION=1.2.3), comment la transmettre ?
Méthode 1 : Variables explicites (recommandé)
Section intitulée « Méthode 1 : Variables explicites (recommandé) »Définissez les variables directement dans le job trigger :
trigger_frontend: variables: ENVIRONMENT: "staging" # Valeur fixe VERSION: $CI_COMMIT_SHA # Valeur dynamique du parent DEBUG: "true" # Configuration pour l'enfant trigger: include: frontend/.gitlab-ci.yml strategy: dependDans l'enfant, ces variables sont disponibles comme n'importe quelle variable :
deploy: script: - echo "Déploiement version $VERSION sur $ENVIRONMENT" - ./deploy.shMéthode 2 : Variables depuis un fichier dotenv
Section intitulée « Méthode 2 : Variables depuis un fichier dotenv »Parfois, la valeur à passer n'est connue qu'après l'exécution d'un job. Par exemple : la version est calculée dynamiquement, ou un ID est généré.
Étape 1 : Générer le fichier dotenv dans un job du parent
prepare: stage: prepare script: # Calcule la version dynamiquement - VERSION=$(./scripts/compute-version.sh) # Écrit dans le fichier dotenv (format : CLÉ=valeur) - echo "VERSION=$VERSION" >> build.env - echo "BUILD_DATE=$(date +%Y-%m-%d)" >> build.env artifacts: reports: dotenv: build.env # 👈 GitLab charge ces variables automatiquementÉtape 2 : Utiliser ces variables dans le trigger
trigger_deploy: stage: deploy needs: ["prepare"] # Important : doit attendre le job qui crée le dotenv variables: VERSION: $VERSION # Provient de build.env BUILD_DATE: $BUILD_DATE trigger: include: deploy.yml strategy: dependPasser des artefacts à l'enfant
Section intitulée « Passer des artefacts à l'enfant »Les artefacts sont les fichiers qu'un job conserve pour les jobs suivants. Leur transmission entre un parent et son enfant demande une syntaxe particulière, car les deux pipelines portent des identifiants différents. La méthode se résume à deux gestes : le parent communique son identifiant de pipeline, l'enfant s'en sert pour aller chercher les fichiers.
Le piège : needs ne traverse pas les pipelines
Section intitulée « Le piège : needs ne traverse pas les pipelines »La déclaration needs habituelle résout les noms de jobs dans le pipeline courant uniquement : y placer le nom d'un job du parent produit une erreur de configuration, pas un téléchargement.
Pourquoi ? Parent et enfant sont des pipelines distincts, avec leurs propres IDs. Le mot-clé needs: ["job"] cherche un job dans le même pipeline.
Solution : needs:pipeline:job
Section intitulée « Solution : needs:pipeline:job »GitLab fournit une syntaxe spéciale pour récupérer des artefacts entre pipelines.
Parent → Child (même projet) : needs:pipeline:job
Section intitulée « Parent → Child (même projet) : needs:pipeline:job »L'identifiant du pipeline parent n'est connu qu'à l'exécution : il transite donc comme une variable ordinaire, que l'enfant réutilise ensuite dans sa déclaration needs.
Étape 1 : Le parent produit un artefact ET passe son ID de pipeline
# Dans le parentbuild_artifacts: stage: build script: - echo "artifact from parent" > artifact.txt - ./compile.sh artifacts: paths: - artifact.txt - dist/
trigger_child: stage: deploy trigger: include: path/to/child-pipeline.yml strategy: depend variables: PARENT_PIPELINE_ID: $CI_PIPELINE_ID # 👈 Passe l'ID du pipeline parentÉtape 2 : L'enfant récupère l'artefact en référençant le pipeline parent
# Dans l'enfant (child-pipeline.yml)test_child: stage: test script: - ls -la # Vérifie que l'artefact est là - cat artifact.txt # Utilise l'artefact needs: - pipeline: $PARENT_PIPELINE_ID # 👈 ID du pipeline source job: build_artifacts # 👈 Nom du job qui a créé l'artefactComment ça marche :
$CI_PIPELINE_IDcontient l'ID unique du pipeline parent (ex:123456)- On passe cet ID à l'enfant via
variables: - L'enfant utilise
needs:pipeline:pour dire "va chercher les artefacts de ce pipeline-là" - GitLab télécharge l'artefact du job
build_artifactsdu pipeline123456
Multi-projet : needs:project
Section intitulée « Multi-projet : needs:project »Pour récupérer un artefact d'un autre projet (pas juste un autre pipeline), utilisez needs:project :
# Dans le pipeline du projet Btest_downstream: stage: test script: - ls -la artifact.txt - ./use-artifact.sh needs: - project: my-group/upstream_project # Chemin du projet source job: build_artifacts # Job qui a produit l'artefact ref: main # Branche du projet source artifacts: true # Télécharger les artefactsDéclencher un pipeline dans un autre projet
Section intitulée « Déclencher un pipeline dans un autre projet »Le mot-clé trigger: sait aussi viser un dépôt distinct : on parle alors de pipeline multi-projet et non de pipeline enfant. La différence n'est pas seulement de vocabulaire. Le pipeline déclenché tourne dans son propre projet, avec sa configuration, ses runners et ses variables, et l'opération met en jeu des autorisations d'accès entre les deux dépôts.
Cas d'usage
Section intitulée « Cas d'usage »Votre application est découpée en plusieurs repos :
my-company/frontend, l'application Reactmy-company/backend, l'API Gomy-company/deployment, les scripts de déploiement Kubernetes
Quand le frontend est buildé, vous voulez déclencher le déploiement dans le repo deployment.
Syntaxe project
Section intitulée « Syntaxe project »Le chemin attendu est celui du dépôt, groupe compris, tel qu'il apparaît dans l'URL du projet. La branche est obligatoire dès que la cible n'est pas la branche par défaut, et c'est le fichier de configuration de cette branche qui sera exécuté.
trigger_deployment: trigger: project: my-company/deployment # Chemin complet du projet cible branch: main # Branche à déclencher strategy: depend # Attend la finDifférence avec include: :
include:→ fichier dans le même repo → child pipelineproject:→ pipeline dans un autre repo → multi-project pipeline
Avec des variables
Section intitulée « Avec des variables »Passez du contexte au pipeline cible :
deploy_production: variables: DEPLOY_ENV: "production" # Où déployer APP_VERSION: $CI_COMMIT_TAG # Quelle version SOURCE_PROJECT: $CI_PROJECT_PATH # D'où ça vient trigger: project: my-company/deployment branch: main strategy: dependExemple monorepo
Section intitulée « Exemple monorepo »Cet exemple assemble tout ce qui précède sur un cas réel : un dépôt unique contenant deux applications, dont on ne veut reconstruire que la partie modifiée. La détection des changements se fait dans un premier job, qui écrit son verdict dans un rapport dotenv, et les jobs de déclenchement s'appuient sur ces variables dans leurs rules:. Un composant intact ne déclenche aucun pipeline enfant.
Structure :
monorepo/├── .gitlab-ci.yml # Parent├── frontend/│ ├── .gitlab-ci.yml # Enfant frontend│ └── src/├── backend/│ ├── .gitlab-ci.yml # Enfant backend│ └── src/└── shared/ └── utils/Parent (racine)
Section intitulée « Parent (racine) »Le fichier racine se lit de haut en bas comme une chaîne de décision : un job changes détermine d'abord ce qui a bougé, puis chaque job de déclenchement porte sa propre condition rules: pour ne lancer que le pipeline enfant concerné.
stages: - prepare - build - deploy
# Déterminer ce qui a changéchanges: stage: prepare script: - | if git diff --name-only HEAD~1 | grep -q "^frontend/"; then echo "FRONTEND_CHANGED=true" >> build.env fi if git diff --name-only HEAD~1 | grep -q "^backend/"; then echo "BACKEND_CHANGED=true" >> build.env fi artifacts: reports: dotenv: build.env
# Déclencher frontend si modifiétrigger_frontend: stage: build needs: ["changes"] trigger: include: frontend/.gitlab-ci.yml strategy: depend rules: - if: $FRONTEND_CHANGED == "true"
# Déclencher backend si modifiétrigger_backend: stage: build needs: ["changes"] trigger: include: backend/.gitlab-ci.yml strategy: depend rules: - if: $BACKEND_CHANGED == "true"Enfant frontend
Section intitulée « Enfant frontend »Rien ne distingue ce fichier d'un pipeline autonome : mêmes stages, même cache, mêmes artefacts. C'est précisément l'intérêt du découpage, l'équipe qui le maintient n'a pas à connaître l'existence du parent.
stages: - install - build - test
install: stage: install script: npm ci cache: key: frontend-deps paths: - .npm/ variables: npm_config_cache: '$CI_PROJECT_DIR/.npm'
build: stage: build script: npm run build artifacts: paths: - dist/
test: stage: test script: npm testLimites et bonnes pratiques
Section intitulée « Limites et bonnes pratiques »Le découpage a des bornes techniques imposées par GitLab, qu'il vaut mieux connaître avant de concevoir une arborescence de pipelines. Elles poussent naturellement vers des hiérarchies plates : un parent, des enfants, et rien de plus profond. Les recommandations qui suivent découlent de ces contraintes et de la lisibilité recherchée.
Ces valeurs sont celles d'une instance GitLab par défaut ; les administrateurs d'une instance auto-hébergée peuvent ajuster la taille de la hiérarchie, mais pas la profondeur.
| Limite | Valeur |
|---|---|
| Profondeur child pipelines (parent → child → grandchild) | 2 niveaux max |
| Taille de la hiérarchie downstream | 1000 pipelines par défaut (paramétrable) |
| Fichiers include par child pipeline | 3 fichiers max |
Bonnes pratiques
Section intitulée « Bonnes pratiques »Ces cinq règles évitent les problèmes les plus coûteux : un statut vert mensonger, un fichier racine qui redevient illisible et des pipelines déclenchés pour rien. La première est la seule qui soit vraiment non négociable.
-
Toujours
strategy: dependsauf si vous voulez explicitement ne pas attendre -
Un fichier CI par composant :
frontend/.gitlab-ci.yml,backend/.gitlab-ci.yml -
Conditions sur les triggers : ne déclenchez que ce qui a changé
-
Variables explicites : documentez ce que vous passez aux enfants
-
Nommez clairement :
trigger_frontend,trigger_backend, pasjob1,job2
Erreurs fréquentes
Section intitulée « Erreurs fréquentes »Six symptômes reviennent systématiquement, et ils ont tous une cause simple. Un point commun les relie : la frontière entre les deux pipelines, qui bloque ce qu'on croyait partagé, ou qui laisse passer un statut qu'on croyait vérifié. Repérez votre symptôme dans les intitulés ci-dessous.
1. Le parent est vert mais l'enfant a échoué
Section intitulée « 1. Le parent est vert mais l'enfant a échoué »Symptôme : Le pipeline parent affiche ✅ success, mais en regardant les détails, l'enfant est en ❌ failed.
Cause : Vous avez oublié strategy: depend.
Solution :
trigger_job: trigger: include: child.yml strategy: depend # 👈 Ajoutez ceci2. Variable non trouvée dans l'enfant
Section intitulée « 2. Variable non trouvée dans l'enfant »Symptôme : L'enfant affiche $VERSION littéralement au lieu de la valeur.
Cause : La variable n'est pas passée au trigger.
Solution : Ajoutez-la dans variables: du job trigger :
trigger_job: variables: VERSION: $VERSION # 👈 Passez explicitement trigger: include: child.yml3. "maximum depth exceeded"
Section intitulée « 3. "maximum depth exceeded" »Symptôme : GitLab refuse de créer le pipeline.
Cause : Vous avez parent → enfant → petit-enfant → arrière-petit-enfant... GitLab limite à 2 niveaux.
Solution : Restructurez pour avoir au max parent → enfant → petit-enfant.
4. Fichier enfant non trouvé
Section intitulée « 4. Fichier enfant non trouvé »Symptôme : file not found ou invalid config.
Cause : Le chemin dans include: est incorrect.
Solution : Le chemin est relatif à la racine du repo, pas au fichier parent :
# ❌ Si le parent est dans ci/parent.ymltrigger: include: ../frontend/.gitlab-ci.yml # NE FONCTIONNE PAS
# ✅ Toujours depuis la racinetrigger: include: frontend/.gitlab-ci.yml # OK5. Artefacts non disponibles dans l'enfant
Section intitulée « 5. Artefacts non disponibles dans l'enfant »Symptôme : needs: ["build"] échoue avec "job not found".
Cause : needs classique ne traverse pas les pipelines.
Solution : Utilisez needs:pipeline:job (voir section Passer des artefacts).
6. needs:project échoue avec 403
Section intitulée « 6. needs:project échoue avec 403 »Symptôme : Erreur d'autorisation.
Cause : Le projet source n'autorise pas le projet destination.
Solution : Configurez la Job token scope allowlist côté projet source (Settings → CI/CD → Token access).
À retenir
Section intitulée « À retenir »trigger: includecrée un pipeline enfant à partir d'un fichier localstrategy: dependfait attendre le parent ;mirrorpour un reflet strictvariables:passe des variables à l'enfant- Artefacts : utilisez
needs:pipeline:job(parent→child) ouneeds:project(multi-projet) trigger: projectdéclenche un pipeline dans un autre projet- Limite : 2 niveaux de profondeur, 1000 pipelines downstream max
$CI_PIPELINE_SOURCEvautparent_pipelinedans un child pipeline
On passe à la pratique
Section intitulée « On passe à la pratique »Mettez ce modèle en oeuvre dans le Lab 16, Pipeline parent-enfant.
Testez vos connaissances
Section intitulée « Testez vos connaissances »Dix questions portant sur les points où l'on se trompe en production : le comportement de strategy, la circulation des variables et la récupération des artefacts entre pipelines.
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