Aller au contenu
CI/CD & Automatisation medium

Pipelines multi-projet GitLab CI/CD (trigger downstream)

11 min de lecture

logo gitlab

Votre application frontend doit déclencher le déploiement du backend après un build réussi ? Les pipelines multi-projet (trigger: project:) permettent de lancer le pipeline d’un autre projet depuis le vôtre. Vous pouvez propager des variables, attendre le résultat et construire des chaînes de déploiement entre projets indépendants.

Si les pipelines parent-enfant orchestrent des sous-pipelines dans le même projet (monorepo), les pipelines multi-projet orchestrent des projets différents qui ont chacun leur propre .gitlab-ci.yml.

  • Déclencher le pipeline d’un autre projet avec trigger: project:
  • Propager des variables vers le projet cible
  • Attendre le résultat du pipeline downstream avec strategy: depend
  • Choisir entre parent-enfant et multi-projet selon votre architecture
  • Sécuriser les déclenchements entre projets

Vos projets GitLab sont découpés en repositories séparés (frontend, backend, infra, docs). Quand le backend change, vous devez relancer les tests d’intégration du frontend. Quand une image Docker est publiée, le projet de déploiement doit enchaîner.

Ce guide est fait pour vous si :

  • Vous avez un projet API qui, après build, doit déclencher le déploiement
  • Votre bibliothèque partagée doit tester les projets qui en dépendent
  • Votre pipeline de release coordonne plusieurs microservices
  • Vous voulez un pipeline d’intégration qui valide la compatibilité entre projets

Avant de commencer, clarifions la différence :

CritèreParent-enfantMulti-projet
ScopeMême projet (même repo)Projets différents (repos différents)
.gitlab-ci.ymlLe parent génère/référence les enfantsChaque projet a son propre pipeline
Cas d’usageMonorepo, sous-modulesMicroservices, chaîne de déploiement
Syntaxetrigger: include:trigger: project:
LimitesMax 2 niveaux de profondeurPas de limite de chaîne
VariablesHéritage automatiquePropagation explicite

Si votre code est dans un seul repo, utilisez parent-enfant (V2-07).

.gitlab-ci.yml du projet A (source)
stages:
- build
- deploy
build:
stage: build
script:
- npm run build
trigger:deploy:
stage: deploy
trigger:
project: devops/deploy-service
branch: main

Ce qui se passe :

  1. Le pipeline du projet A exécute le job build
  2. Le job trigger:deploy déclenche le pipeline du projet devops/deploy-service sur la branche main
  3. Le pipeline de A continue sans attendre le résultat (par défaut)

Pour transmettre des informations au projet cible, utilisez variables: :

Projet source
trigger:deploy:
stage: deploy
trigger:
project: devops/deploy-service
branch: main
variables:
UPSTREAM_PROJECT: $CI_PROJECT_PATH
UPSTREAM_REF: $CI_COMMIT_REF_NAME
UPSTREAM_SHA: $CI_COMMIT_SHORT_SHA
APP_VERSION: $BUILD_VERSION

Le projet cible reçoit ces variables comme des variables d’environnement classiques :

Projet cible (devops/deploy-service)
deploy:
stage: deploy
script:
- echo "Triggered by $UPSTREAM_PROJECT @ $UPSTREAM_SHA"
- echo "Deploying version $APP_VERSION"
- ./deploy.sh --version "$APP_VERSION"

Par défaut, le job trigger passe au statut success dès que le pipeline downstream est créé (pas terminé). Pour attendre :

trigger:deploy:
stage: deploy
trigger:
project: devops/deploy-service
branch: main
strategy: depend
variables:
APP_VERSION: $BUILD_VERSION

Avec strategy: depend :

Statut downstreamStatut du job trigger
Succès✅ Succès
Échec❌ Échec
En cours🔄 En attente

C’est presque toujours ce que vous voulez. Sans strategy: depend, votre pipeline source affiche “succès” alors que le déploiement downstream a peut-être échoué.

# Branche fixe
trigger:
project: devops/deploy-service
branch: main
# Même branche que le source (si elle existe dans le projet cible)
trigger:
project: devops/deploy-service
branch: $CI_COMMIT_REF_NAME
Projet orchestrateur
stages:
- trigger
trigger:api:
stage: trigger
trigger:
project: team/api-service
strategy: depend
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+/
trigger:frontend:
stage: trigger
trigger:
project: team/frontend-app
strategy: depend
variables:
API_VERSION: $CI_COMMIT_TAG
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+/
trigger:docs:
stage: trigger
trigger:
project: team/documentation
# Pas de strategy:depend — on n'attend pas les docs
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+/

Quand votre bibliothèque change, lancez les tests des projets qui l’utilisent :

Projet de la bibliothèque
test:library:
stage: test
script:
- npm test
# Après les tests, vérifier que les consommateurs ne cassent pas
verify:app-a:
stage: verify
trigger:
project: team/app-a
strategy: depend
variables:
LIB_VERSION: $CI_COMMIT_SHA
verify:app-b:
stage: verify
trigger:
project: team/app-b
strategy: depend
variables:
LIB_VERSION: $CI_COMMIT_SHA

Pipeline inversé : le cible déclenche via l’API

Section intitulée « Pipeline inversé : le cible déclenche via l’API »

Parfois c’est le projet cible qui doit écouter les changements du source. Utilisez un webhook ou un pipeline trigger token :

Projet source — déclencher via l'API dans un script
notify:deploy:
stage: notify
script:
- |
curl --request POST \
--form "token=$DEPLOY_TRIGGER_TOKEN" \
--form "ref=main" \
--form "variables[UPSTREAM_SHA]=$CI_COMMIT_SHORT_SHA" \
"https://gitlab.example.com/api/v4/projects/42/trigger/pipeline"

Les jobs trigger supportent rules: comme tout autre job :

trigger:staging:
trigger:
project: devops/deploy-service
strategy: depend
variables:
ENVIRONMENT: staging
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
trigger:production:
trigger:
project: devops/deploy-service
strategy: depend
variables:
ENVIRONMENT: production
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
when: manual
allow_failure: false

Le pipeline downstream est créé au nom de l’utilisateur qui a déclenché le pipeline source. Cet utilisateur doit avoir au minimum le rôle Developer dans le projet cible.

Rôle dans le projet ciblePeut déclencher ?
Guest
Reporter
Developer
Maintainer
Owner

Depuis GitLab 16.3+, le CI_JOB_TOKEN peut être utilisé pour l’authentification cross-projet. Configurez dans le projet cible : Settings > CI/CD > Token Access et ajoutez le projet source à la liste des projets autorisés.

LimiteValeur
Profondeur de chaîne downstreamPas de limite stricte, mais chaque niveau ajoute de la latence
Pipelines simultanés par projetSelon votre licence et la configuration du projet
Variables transmisesPas de limite, mais seules les variables déclarées dans variables: sont propagées
  • Toujours utiliser strategy: depend sauf pour les triggers non critiques (docs, notifications)
  • Nommer les jobs clairement : trigger:deploy-staging, pas downstream_1
  • Propager le minimum de variables nécessaires — pas de secrets du projet source
  • Documenter les dépendances entre projets dans le README
  • Versionner via les tags : cibler branch: main pour le dernier état, un tag pour une version précise
SymptômeCause probableSolution
403 ForbiddenL’utilisateur n’a pas les droits sur le projet cibleVérifier le rôle (minimum Developer)
Pipeline downstream non crééLe projet cible n’existe pas ou est privéVérifier le chemin project: et les permissions
Job trigger “success” mais downstream en échecstrategy: depend non configuréAjouter strategy: depend
Variables non disponibles dans le downstreamNon déclarées dans variables:Ajouter explicitement chaque variable à transmettre
Boucle infinie de triggersProjet A trigger B qui trigger AAjouter une condition rules pour casser la boucle
Pipeline downstream sur la mauvaise branchebranch: absentSpécifier branch: explicitement
  • trigger: project: déclenche un pipeline dans un autre projet GitLab
  • strategy: depend fait attendre le résultat — sans ça, le job trigger passe en succès dès la création
  • Les variables doivent être propagées explicitement — pas d’héritage automatique
  • L’utilisateur qui déclenche doit avoir le rôle Developer minimum dans le projet cible
  • Parent-enfant = même repo (monorepo), multi-projet = repos différents (microservices)
  • Les jobs trigger ne peuvent pas avoir de script: — c’est un déclencheur, pas un exécuteur
  • Documentez toujours les dépendances entre projets — les triggers créent un couplage implicite

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