Blog Ingénierie GitLab CI/CD : comment créer facilement un pipeline pour un monorepo
Mise à jour : May 27, 2025
Lecture : 6 min

GitLab CI/CD : comment créer facilement un pipeline pour un monorepo

Découvrez comment configurer un pipeline CI/CD dans GitLab pour un dépôt monorepo et simplifier l'hébergement de plusieurs applications dans un seul dépôt.

pipeline  2 - cover

Les monorepos permettent d’héberger le code de plusieurs applications au sein d'un seul dépôt. Dans GitLab, cela consiste à organiser le code source de chaque application dans des répertoires distincts au sein d'un même projet. Bien que cette approche facilite le contrôle de version pour l'ensemble du code, tirer parti des capacités avancées des pipelines CI/CD de GitLab pouvait s'avérer complexe... jusqu'à l'arrivée d'une nouvelle fonctionnalité dans GitLab 16.4 !

Le cas idéal : des pipelines CI/CD indépendants pour un monorepo

Lorsque plusieurs applications coexistent dans un même dépôt, il est logique de vouloir disposer de pipelines CI/CD distincts pour chacune d'elles. Par exemple, si l'un de vos projets regroupe une application .NET et une application Spring, chacune d'elle nécessitera des jobs de compilation et de test différents. L'idéal serait donc de pouvoir découpler ces pipelines pour qu'ils s'exécutent uniquement lorsque des modifications sont apportées au code source de l'application concernée.

Techniquement, cela revient à configurer un fichier de pipeline .gitlab-ci.yml au niveau du projet, qui inclut des fichiers YAML spécifiques basés sur les modifications détectées dans certains répertoires. Le fichier de pipeline .gitlab-ci.yml agit comme un plan de contrôle qui déclenche le pipeline approprié en fonction des modifications apportées au code.

Ancienne approche : le contournement

Avant l'introduction de nouvelles fonctionnalités dans GitLab 16.4, il n'était pas possible d'inclure directement un fichier YAML en fonction des modifications apportées à un répertoire ou un fichier spécifique. Une solution de contournement était toutefois disponible.

Prenons un exemple concret : un monorepo avec deux répertoires, java et python, contenant respectivement le code source d'une application Java et d'une application Python. Chaque répertoire disposait d'un fichier YAML propre à l'application pour gérer sa compilation. Le fichier de pipeline principal du projet incluait simplement les deux fichiers YAML des applications, mais une logique de gestion des modifications devait être directement intégrée dans ces fichiers.

.gitlab-ci.yml :

stages:
  - build
  - test
  - deploy

top-level-job:
  stage: build
  script:
    - echo "Hello world..."

include:
  - local: '/java/j.gitlab-ci.yml'
  - local: '/python/py.gitlab-ci.yml'

Pour chaque application, il était nécessaire de créer un job masqué (par exemple, .java-common ou .python-common), qui ne s'exécutait qu'en présence de modifications apportées au répertoire correspondant. Les jobs masqués ne s'exécutaient pas par défaut. Ils servaient à centraliser la logique de déclenchement et à la réutiliser dans d'autres jobs. Cependant, cela impliquait d'étendre le job masqué dans chaque pipeline afin de respecter les règles de détection des modifications, qui déclenchaient alors le job d'exécution du pipeline.

'j.gitlab-ci.yml':

''' stages:

  • build
  • test
  • deploy

.java-common: rules: - changes: - ../java/*'

java-build-job: extends: .java-common stage: build script: - echo "Building Java"

java-test-job: extends: .java-common stage: test script: - echo "Testing Java"

'''

'py.gitlab-ci.yml':

''' stages:

  • build
  • test
  • deploy

.python-common: rules: - changes: - "../python/*"

python-build-job: extends: .python-common stage: build script: - echo "Building Python"

python-test-job: extends: .python-common stage: test script: - echo "Testing Python"

'''

Cette méthode fonctionnait, mais présentait des inconvénients majeurs. En effet, chaque pipeline devait étendre le job masqué pour chaque autre job dans le fichier YAML afin de respecter les règles de déclenchement. Elle avait pour conséquence la création de code redondant et l'augmentation du risque d'erreur humaine. De plus, les jobs étendus n'acceptaient pas de clés en double. Vous ne pouviez donc pas définir votre propre logique de règles (rules), car cela entraînait des conflits de clés et leurs valeurs n'étaient pas fusionnées.

Malgré tout, avec cette méthode, le pipeline est opérationnel, incluant les jobs j.gitlab-ci.yml dès que le répertoire java/ est mis à jour, et les jobs py.gitlab-ci.yml dès que le répertoire python/ est mis à jour.

Nouvelle approche : l'inclusion conditionnelle des fichiers de pipeline

Votre avis nous intéresse

Cet article de blog vous a plu ou vous avez des questions ou des commentaires ? Partagez vos réflexions en créant un nouveau sujet dans le forum de la communauté GitLab. Partager votre expérience

Lancez-vous dès maintenant

Découvrez comment la plateforme DevSecOps unifiée de GitLab peut aider votre équipe.

Commencer un essai gratuit

Découvrez le forfait qui convient le mieux à votre équipe

En savoir plus sur la tarification

Découvrez ce que GitLab peut offrir à votre équipe

Échanger avec un expert