Jusqu'à peu de temps, j'utilisais essentiellement un seul repo gitlab (monorepo) pour gérer la plupart de mes projets. Mais voilà, certains projets ont tellement grossi que la gestion du ci est devenu trop complexe. Cela ralentit énormément la productivité et ce malgré l'utilisation des include.
Gitlab dans la version 12.7, et complèté avec la 12.9, a apporté le concept de pipelines parent-child (parent-enfants) qui permet de décomposer des pipelines.
Ecrire un pipeline parent-enfant dans un seul repo
On peut utiliser ce concept dans un projet mono-repo. L'écriture des pipelines enfants est identique à celui qu'on utilise classiquement. Par contre, pour celui du parent, il faudra utiliser la clé trigger pour lancer son déclenchement.
# .gitlab-ci.yml
stages:
- builds
build1:
stage: builds
trigger:
include: build1.yml
strategy: depend
build2:
stage: builds
trigger:
include: build2.yml
strategy: depend
Par défaut le pipeline parent se termine tout de suite en status success
avant
même que les enfants ne se soient exécutés. Pour l'obliger à attendre la fin de
l'exécution des enfants et de lier son status avec ceux-ci, il faut indiquer
strategy: depend
Un des pipeline enfant (l'autre est identique, c'est pour l'exemple) :
# build1.yml
image: alpine:3.11
build:
stage: build
script:
- touch hello.md
artifacts:
paths:
- hello.md
Ce qui donne :
Ecrire des pipelines multi-repos
Il est possible de lancer des pipelines sur d'autres projets. Il suffit juste
d'indiquer le nom du projet avec la clé project: stephane.r/test2
Ce qui donne dans notre exemple :
# .gitlab-ci.yml
stages:
- builds
build1:
stage: builds
trigger:
include: build1.yml
strategy: depend
build2:
stage: builds
trigger:
include: build2.yml
strategy: depend
build3:
stage: builds
trigger:
project: stephane.r/test2
strategy: depend
Dans le projet test2 il suffit de créer un fichier .gitlab-ci.yml
.
Passer des variables à un enfant
Pour passer des variables aux enfants, il suffit d'utiliser la clé variables
.
build3:
variables:
ENVI: staging
stage: builds
trigger:
project: stephane.r/test2
strategy: depend
Dans le ci du projet test2 j'ai modifié le script pour qu'il utilise la variable :
# .gitlab-ci.yml
image: alpine:3.11
build:
tags:
- php
stage: build
script:
- echo $ENVI > hello.md
artifacts:
paths:
- hello.md
Dans le fichier hello.md je retrouve bien le contenu de ma variable ENVI.
Passer des artefacts aux enfants
On peut aussi passer des artefacts, pour cela il suffit d'ajouter needs
dans le trigger.
Par exemple pour passer des variables du projet test à test2 en utilisant build.env :
# test/.gitlab-ci.yml
stages:
- version
- deploy
version:
tags:
- javascript
stage: version
script:
- echo "VERSION=$CI_COMMIT_TAG" >> build.env
- echo "$CI_COMMIT_TAG"
artifacts:
reports:
dotenv: build.env
deploy:
needs:
- build
variables:
VERSION: $VERSION
stage: deploy
trigger:
project: stephane.r/test2
strategy: depend
only:
- tags
# test2/.gitlab-ci.yml
# build1.yml
image: alpine:3.11
build:
tags:
- javascript
stage: build
script:
- echo "$VERSION"
En sortie de script, je récupère bien le tag de test.
...
$ echo "$VERSION"
v0.1
Cleaning up file based variables
00:01
Job succeeded
Cas d'usages
Vous pouvez par exemple lié des repos de librairies de vos applications au déploiement de votre application.
Vous pouvez également pour une API rest, une fois l'application déployée, lancez le build de la documentation générée à partir de la définition du swagger.
Voilà pour aujourd'hui, bientôt d'autres sujets sur gitlab comme les rules et les environments.