Date de publication : 6 mai 2026

Temps de lecture : 16 min

5 modèles de pipeline GitLab pour résoudre vos enjeux d'ingénierie

Découvrez comment faire évoluer votre approche CI/CD avec des modèles composables pour les monorepos, les microservices, les environnements et la gouvernance.

La plupart des outils CI/CD savent exécuter un build et lancer un déploiement. La différence se fait lorsque vos besoins de livraison deviennent concrets : un monorepo avec une dizaine de services, des microservices répartis sur plusieurs dépôts, des déploiements vers des dizaines d'environnements, ou une équipe plateforme qui cherche à appliquer des normes sans devenir un goulot d'étranglement.

Le modèle d'exécution de pipelines de GitLab a été conçu pour cette complexité. Les pipelines parent-enfant, l'exécution du graphe orienté acyclique (DAG), la génération dynamique de pipelines, les déclencheurs multi-projets, les pipelines de merge request avec résultats fusionnés et les composants CI/CD répondent chacun à une catégorie distincte de problèmes. Parce qu'ils se combinent entre eux, la compréhension du modèle complet offre bien plus qu'une accélération du pipeline. Dans cet article, vous découvrirez cinq modèles dans lesquels les pipelines se distinguent, chacun associé à un scénario d'ingénierie concret avec la configuration correspondante.

Les configurations ci-dessous sont fournies à titre illustratif. Les scripts utilisent des commandes echo pour maintenir un rapport signal/bruit faible. Remplacez-les par vos véritables étapes de build, de test et de déploiement pour qu'elles soient prêtes à l'emploi.

1. Monorepos : pipelines parent-enfant et exécution du DAG

Le problème : votre monorepo contient un frontend, un backend et un site de documentation. Chaque commit déclenche une reconstruction complète de l'ensemble, même lorsque seul un fichier README a été modifié.

GitLab résout ce problème grâce à deux fonctionnalités complémentaires : les pipelines parent-enfant (qui permettent à un pipeline de niveau supérieur de créer des sous-pipelines isolés) et l'exécution du DAG via needs (qui rompt le classement rigide étape par étape et permet aux jobs de démarrer dès que leurs dépendances sont terminées).

Un pipeline parent détecte les modifications et ne déclenche que les pipelines enfants concernés :

      # .gitlab-ci.yml
stages:
  - trigger

trigger-services:
  stage: trigger
  trigger:
    include:
      - local: '.gitlab/ci/api-service.yml'
      - local: '.gitlab/ci/web-service.yml'
      - local: '.gitlab/ci/worker-service.yml'
    strategy: depend

    

Chaque pipeline enfant est entièrement indépendant avec ses propres étapes, jobs et artefacts. Le pipeline parent attend la fin de l'ensemble via strategy: depend, ce qui vous donne un signal vert/rouge unique au niveau supérieur, avec une vue détaillée de chaque pipeline de service. Cette séparation organisationnelle est le gain le plus important pour les grandes équipes : chaque service est propriétaire de sa configuration de pipeline, les modifications d'une configuration n'entraînent pas l'échec d'une autre, et la complexité reste gérable à mesure que le dépôt grandit.

Un point important : lorsque vous transmettez plusieurs fichiers à un même trigger: include:, GitLab les fusionne dans une seule configuration de pipeline enfant. Cela signifie que les jobs définis dans ces fichiers partagent le même contexte de pipeline et peuvent se référencer mutuellement avec needs:, ce qui rend l'optimisation du DAG possible. Si vous les séparez dans des jobs de déclenchement distincts, chaque fichier constituerait son propre pipeline isolé, et les références needs: entre fichiers ne fonctionneraient pas.

Combinez cette approche avec needs: à l'intérieur de chaque pipeline enfant pour exécuter le DAG. Vos tests d'intégration peuvent démarrer dès que le build est terminé, sans attendre les autres jobs de la même étape.

      # .gitlab/ci/api-service.yml
stages:
  - build
  - test

build-api:
  stage: build
  script:
    - echo "Building API service"

test-api:
  stage: test
  needs: [build-api]
  script:
    - echo "Running API tests"

    

Pourquoi c'est important : les équipes qui disposent de monorepos volumineux constatent généralement des réductions significatives du temps d'exécution des pipelines après le passage à l'exécution du DAG, car les jobs n'attendent plus des tâches sans rapport dans la même étape. Les pipelines parent-enfant constituent la couche organisationnelle qui facilite la gestion de la configuration à mesure que le dépôt et l'équipe grandissent.

Pipelines downstream locauxPipelines downstream locaux

2. Microservices : pipelines multi-projets inter-dépôts

Le problème : votre frontend se trouve dans un dépôt, et votre backend dans un autre. Lorsque l'équipe frontend livre une modification, elle n'a aucune visibilité sur les éventuelles défaillances du backend, et inversement.

Les pipelines multi-projets de GitLab permettent à un projet de déclencher un pipeline dans un projet totalement distinct et d'en attendre le résultat. Le projet déclencheur obtient un pipeline downstream lié directement dans sa propre vue de pipeline.

Le pipeline frontend construit un artefact de contrat d'API et le publie, puis déclenche le pipeline backend. Le backend récupère cet artefact directement via l'API Jobs et le valide avant de poursuivre. Si une modification incompatible est détectée, le pipeline backend échoue, tout comme le pipeline frontend.

      # frontend repo: .gitlab-ci.yml
stages:
  - build
  - test
  - trigger-backend

build-frontend:
  stage: build
  script:
    - echo "Building frontend and generating API contract..."
    - mkdir -p dist
    - |
      echo '{
        "api_version": "v2",
        "breaking_changes": false
      }' > dist/api-contract.json
    - cat dist/api-contract.json
  artifacts:
    paths:
      - dist/api-contract.json
    expire_in: 1 hour

test-frontend:
  stage: test
  script:
    - echo "All frontend tests passed!"

trigger-backend-pipeline:
  stage: trigger-backend
  trigger:
    project: my-org/backend-service
    branch: main
    strategy: depend
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

    
      # backend repo: .gitlab-ci.yml
stages:
  - build
  - test

build-backend:
  stage: build
  script:
    - echo "All backend tests passed!"

integration-test:
  stage: test
  rules:
    - if: $CI_PIPELINE_SOURCE == "pipeline"
  script:
    - echo "Fetching API contract from frontend..."
    - |
      curl --silent --fail \
        --header "JOB-TOKEN: $CI_JOB_TOKEN" \
        --output api-contract.json \
        "${CI_API_V4_URL}/projects/${FRONTEND_PROJECT_ID}/jobs/artifacts/main/raw/dist/api-contract.json?job=build-frontend"
    - cat api-contract.json
    - |
      if grep -q '"breaking_changes": true' api-contract.json; then
        echo "FAIL: Breaking API changes detected - backend integration blocked!"
        exit 1
      fi
      echo "PASS: API contract is compatible!"

    

Quelques points à noter dans cette configuration. Le job integration-test utilise $CI_PIPELINE_SOURCE == "pipeline" pour s'assurer qu'il ne s'exécute que lorsqu'il est déclenché par un pipeline amont, et non lors d'un push direct sur le dépôt backend. L'identifiant du projet frontend est référencé via $FRONTEND_PROJECT_ID, qui doit être défini comme variable CI/CD dans les paramètres du projet backend afin d'éviter de le coder en dur.

Pourquoi c'est important : les échecs inter-services qui ne se manifestaient auparavant qu'en production sont désormais détectés dans le pipeline. La dépendance entre services, auparavant invisible, devient visible, traçable et corrigeable.

Pipelines multi-projetsPipelines multi-projets

3. Déploiements multilocataires et de matrice : pipelines enfants dynamiques

Le problème : vous déployez la même application vers 15 environnements clients, trois régions cloud ou encore des environnements de développement/préproduction/production. Mettre à jour une étape de déploiement sur l'ensemble de ces environnements un par un entraîne une dérive de configuration, tandis que créer un pipeline distinct pour chaque environnement est impossible à maintenir.

Les pipelines enfants dynamiques de GitLab permettent de générer un pipeline au moment de l'exécution. Un job exécute un script qui produit un fichier YAML, qui devient le pipeline de l'étape suivante. La structure même du pipeline devient une donnée.

      # .gitlab-ci.yml
stages:
  - generate
  - trigger-environments

generate-config:
  stage: generate
  script:
    - |
      # ENVIRONMENTS can be passed as a CI variable or read from a config file.
      # Default to dev, staging, prod if not set.
      ENVIRONMENTS=${ENVIRONMENTS:-"dev staging prod"}
      for ENV in $ENVIRONMENTS; do
        cat > ${ENV}-pipeline.yml << EOF
      stages:
        - deploy
        - verify
      deploy-${ENV}:
        stage: deploy
        script:
          - echo "Deploying to ${ENV} environment"
      verify-${ENV}:
        stage: verify
        script:
          - echo "Running smoke tests on ${ENV}"
      EOF
      done
  artifacts:
    paths:
      - "*.yml"
    exclude:
      - ".gitlab-ci.yml"

.trigger-template:
  stage: trigger-environments
  trigger:
    strategy: depend

trigger-dev:
  extends: .trigger-template
  trigger:
    include:
      - artifact: dev-pipeline.yml
        job: generate-config

trigger-staging:
  extends: .trigger-template
  needs: [trigger-dev]
  trigger:
    include:
      - artifact: staging-pipeline.yml
        job: generate-config

trigger-prod:
  extends: .trigger-template
  needs: [trigger-staging]
  trigger:
    include:
      - artifact: prod-pipeline.yml
        job: generate-config
  when: manual

    

Le script de génération parcourt une variable ENVIRONMENTS plutôt que de coder en dur chaque environnement séparément. Transmettez une liste différente via une variable CI ou lisez-la depuis un fichier de configuration, et le pipeline s'adapte sans toucher au fichier YAML. Les jobs de déclenchement utilisent extends: pour hériter de la configuration partagée de .trigger-template, de sorte que strategy: depend est défini une seule fois au lieu d'être répété sur chaque job de déclenchement. Pour ajouter un nouvel environnement, il suffit de mettre à jour la variable, sans dupliquer la configuration du pipeline. Ajoutez when: manual au déclencheur de production pour obtenir une porte de validation intégrée directement dans le graphe du pipeline.

Pourquoi c'est important : les entreprises SaaS et les équipes plateforme utilisent ce modèle pour gérer des dizaines d'environnements sans dupliquer la logique de pipeline. La structure du pipeline elle-même reste simple à mesure que la matrice de déploiement évolue.

Pipeline dynamiquePipeline dynamique

4. Livraison axée sur les merge requests : pipelines de merge request, résultats fusionnés et routage par workflow

Le problème : votre pipeline s'exécute à chaque push sur chaque branche. Des tests coûteux s'exécutent sur des branches de fonctionnalité qui ne seront jamais fusionnées. Parallèlement, vous n'avez aucune garantie que ce que vous avez testé correspond réellement à ce qui arrivera sur la branche main après le merge.

GitLab propose trois fonctionnalités imbriquées qui résolvent ensemble ce problème :

  • Les pipelines de merge request ne s'exécutent que lorsqu'une merge request existe, et non à chaque push de branche. Cette approche à elle seule élimine une quantité significative de ressources gaspillées.
  • Les pipelines à résultats fusionnés vont plus loin. GitLab crée un commit de merge temporaire (votre branche plus la branche cible actuelle) et exécute le pipeline sur ce résultat. Vous testez ce qui existera réellement après le merge, et non simplement votre branche de manière isolée.
  • Les règles de workflow vous permettent de définir exactement quel type de pipeline s'exécute dans quelles conditions et de supprimer tout le reste. La protection $CI_OPEN_MERGE_REQUESTS ci-dessous empêche le déclenchement simultané de pipelines en double pour une branche et sa merge request ouverte.

Avec ces trois fonctionnalités combinées, voici à quoi ressemble un pipeline à niveaux :

      # .gitlab-ci.yml
workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
      when: never
    - if: $CI_COMMIT_BRANCH
    - if: $CI_PIPELINE_SOURCE == "schedule"

stages:
  - fast-checks
  - expensive-tests
  - deploy

lint-code:
  stage: fast-checks
  script:
    - echo "Running linter"
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == "main"

unit-tests:
  stage: fast-checks
  script:
    - echo "Running unit tests"
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == "main"

integration-tests:
  stage: expensive-tests
  script:
    - echo "Running integration tests (15 min)"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == "main"

e2e-tests:
  stage: expensive-tests
  script:
    - echo "Running E2E tests (30 min)"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == "main"

nightly-comprehensive-scan:
  stage: expensive-tests
  script:
    - echo "Running full nightly suite (2 hours)"
  rules:
    - if: $CI_PIPELINE_SOURCE == "schedule"

deploy-production:
  stage: deploy
  script:
    - echo "Deploying to production"
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
      when: manual

    

Avec cette configuration, le pipeline se comporte différemment selon le contexte. Un push vers une branche de fonctionnalité sans merge request ouverte n'exécute que l’analyse du code et les tests unitaires. Dès qu'une merge request est ouverte, les règles de workflow passent d'un pipeline de branche à un pipeline de merge request, et la suite complète d'intégration et de tests de bout en bout s'exécute sur le résultat fusionné. Le merge vers la branche main met en file d'attente un déploiement en production manuel. Une planification nocturne exécute le scan complet une seule fois, et non à chaque commit.

Pourquoi c'est important : les équipes réduisent leurs coûts CI de manière significative avec ce modèle, non pas en exécutant moins de tests, mais en exécutant les bons tests au bon moment. Les pipelines à résultats fusionnés détectent les bogues qui n'apparaissent qu'après un merge, avant même qu'ils n'atteignent la branche main.

Pipelines conditionnels (dans une branche sans merge request)Pipelines conditionnels (dans une branche sans merge request)

Pipelines conditionnels (dans une merge request)Pipelines conditionnels (dans une merge request)

Pipelines conditionnels (branche principale)Pipelines conditionnels (branche principale)

5. Pipelines gouvernés : composants CI/CD

Le problème : votre équipe plateforme a défini la bonne manière de compiler, tester et déployer. Mais chaque équipe possède son propre fichier .gitlab-ci.yml avec des variations subtiles. Les scans de sécurité sont ignorés. Les normes de déploiement subissent des dérives de configuration. Les audits deviennent trop complexes.

Les composants CI/CD de GitLab permettent aux équipes plateforme de publier des composants de pipeline versionnés et réutilisables. Les équipes applicatives les utilisent avec une seule ligne include: et des paramètres facultatifs : pas de copier-coller, pas de dérive. Les composants sont consultables via le catalogue CI/CD, ce qui permet aux équipes de trouver et d'adopter des composants approuvés sans avoir à passer par l'équipe plateforme.

Voici la définition d'un composant issu d'une bibliothèque partagée :

      # templates/deploy.yml
spec:
  inputs:
    stage:
      default: deploy
    environment:
      default: production
---
deploy-job:
  stage: $[[ inputs.stage ]]
  script:
    - echo "Deploying $APP_NAME to $[[ inputs.environment ]]"
    - echo "Deploy URL: $DEPLOY_URL"
  environment:
    name: $[[ inputs.environment ]]

    

Et voici comment une équipe applicative l'utilise :

      # Application repo: .gitlab-ci.yml
variables:
  APP_NAME: "my-awesome-app"
  DEPLOY_URL: "https://api.example.com"

include:
  - component: gitlab.com/my-org/component-library/[email protected]
  - component: gitlab.com/my-org/component-library/[email protected]
  - component: gitlab.com/my-org/component-library/[email protected]
    inputs:
      environment: staging

stages:
  - build
  - test
  - deploy

    

Trois lignes include: remplacent des centaines de lignes de fichier YAML dupliqué. L'équipe plateforme peut déployer un correctif de sécurité dans la version v1.0.7 et les équipes l'adoptent à leur propre rythme, ou l'équipe plateforme peut imposer une version minimale à tous. Dans les deux cas, une seule modification se propage partout au lieu de devoir être appliquée dépôt par dépôt.

Associez cette approche aux groupes de ressources pour empêcher les déploiements simultanés vers le même environnement, et aux environnements protégés pour appliquer des portes d'approbation, et vous obtenez une plateforme de livraison gouvernée où la conformité est la norme, et non l'exception.

Pourquoi c'est important : c'est le modèle qui permet à GitLab CI/CD d'évoluer pour être appliqué par des centaines d'équipes. Les équipes d'ingénierie de plateforme appliquent la conformité sans devenir un goulot d'étranglement. Les équipes applicatives obtiennent un chemin rapide vers un pipeline fonctionnel sans avoir à tout recommencer.

Pipeline avec composants (jobs importés)Pipeline avec composants (jobs importés)

Vue d'ensemble

Aucune de ces fonctionnalités n'existe de manière isolée. L'intérêt du modèle de pipeline de GitLab réside dans le fait que ces éléments fondamentaux se combinent entre eux :

  • Un monorepo utilise des pipelines parent-enfant, et chaque pipeline enfant utilise l'exécution du DAG.
  • Une plateforme de microservices utilise des pipelines multi-projets, et chaque projet utilise des pipelines de merge request avec résultats fusionnés.
  • Une plateforme gouvernée utilise des composants CI/CD pour standardiser les modèles ci-dessus dans toutes les équipes.

La plupart des équipes découvrent l'une de ces fonctionnalités lorsqu'elles rencontrent un point de friction spécifique. Celles qui investissent dans la compréhension du modèle complet obtiennent un système de livraison qui reflète réellement le fonctionnement de leur organisation d'ingénierie, et non un pipeline qui le freine.

Autres modèles à explorer

Les cinq modèles ci-dessus couvrent les points de friction structurels les plus courants, mais le modèle de pipeline de GitLab va plus loin. Voici quelques pistes supplémentaires à mesure que vos besoins évoluent :

  • Les versions temporaires d'application avec environnements dynamiques vous permettent de créer un aperçu en direct pour chaque branche de fonctionnalité et de le supprimer automatiquement à la fermeture de la merge request. C'est particulièrement utile pour les équipes qui travaillent sur le frontend ou les modifications d'API qui nécessitent une validation des parties prenantes avant le merge.
  • Les stratégies de mise en cache et d'artefacts sont souvent le moyen le plus rapide de réduire le temps d'exécution des pipelines une fois le travail structurel effectué. Structurer les clés de cache: autour des fichiers de verrouillage des dépendances et faire preuve de rigueur sur ce qui est transmis entre les jobs avec artefacts: peut faire une différence significative sans modifier la forme de votre pipeline.
  • Les pipelines planifiés et déclenchés par API méritent d'être connus, car tout ne doit pas s'exécuter sur un push de code. Les scans de sécurité nocturnes, les rapports de conformité et l'automatisation des releases sont mieux modélisés sous forme de pipelines planifiés ou déclenchés par API, avec $CI_PIPELINE_SOURCE qui achemine les bons jobs selon le contexte.

Lancez-vous

La livraison logicielle moderne est complexe. Les équipes gèrent des monorepos avec des dizaines de services, coordonnent leurs efforts entre plusieurs dépôts, déploient vers de nombreux environnements simultanément et cherchent à maintenir la cohérence des normes à mesure que les organisations évoluent. Le modèle de pipeline de GitLab a été conçu avec tous ces enjeux à l'esprit.

Il vaut la peine d'investir dans le modèle de pipeline de GitLab, car ses différents éléments s'articulent particulièrement bien entre eux. Les pipelines parent-enfant apportent une certaine structure aux codes sources volumineux. Les pipelines multi-projets donnent davantage de visibilité aux dépendances inter-équipes et permettent de les tester. Les pipelines dynamiques transforment la gestion des environnements en un processus aisément évolutif. La livraison axée sur les merge requests avec résultats fusionnés garantit la confiance à chaque étape du processus de revue. Et les composants CI/CD offrent aux équipes plateforme un moyen de partager les bonnes pratiques dans toute l'organisation sans devenir un goulot d'étranglement.

Chacune de ces fonctionnalités est puissante individuellement, et encore plus lorsqu'elles sont combinées. GitLab vous fournit les composants nécessaires pour concevoir un système de livraison adapté au fonctionnement réel de votre équipe, et qui évolue avec vos besoins.

Démarrez un essai gratuit de GitLab Ultimate pour exploiter la logique des pipelines dès aujourd'hui.

Donnez-nous votre avis

Cet article de blog vous a plu ? Vous avez des questions ou des retours à nous faire ? Donnez votre avis en créant un nouveau sujet sur le forum de la communauté GitLab.

Faites-nous part de vos commentaires

Commencez à développer plus rapidement dès aujourd'hui

Découvrez ce que votre équipe peut accomplir avec la plateforme d'orchestration intelligente pour le DevSecOps.