Rules et workflow¶
Tous les jobs n'ont pas à tourner à chaque commit. Il y a deux niveaux pour contrôler ça:
rules:dans un job: ce job tourne ou pasworkflow:au niveau global: la pipeline entière est créée ou pas
rules¶
job:
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
script:
- echo "tourne si la condition est vraie"
Trois choses à savoir:
- les règles sont évaluées dans l'ordre, la première dont le
ifest vrai décide - si aucune règle ne match, le job ne tourne pas (comme
when: never) - une règle sans
ifmatch toujours, donc elle sert de "sinon"
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: on_success # IF
- when: manual # ELSE
when¶
| Valeur | Effet |
|---|---|
on_success |
tourne si les jobs d'avant ont réussi (défaut) |
on_failure |
tourne si au moins un job d'avant a échoué |
always |
tourne quoi qu'il arrive |
manual |
il faut cliquer sur ▶️ dans l'interface gitlab |
delayed |
tourne tout seul après un délai (start_in: 30 minutes) |
never |
ne tourne pas |
Conditions courantes¶
# sur la branche par défaut
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
# uniquement quand on pousse un tag
- if: '$CI_COMMIT_TAG != null'
# uniquement dans une merge request vers main
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main"'
&& = ET, || = OU. Plusieurs - if: à la suite sont combinés avec un OU.
Le dernier when: never¶
Pattern que j'utilise partout: les règles voulues d'abord, et un when: never à la fin pour être explicite sur le "sinon, ne pas tourner":
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: on_success
- when: never
Après c'est pas obligatoire hein. Ça revient à faire ça:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
Le job qui tourne jamais¶
stages:
- learn
learn-job:
stage: learn
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: never
script:
- echo "Ca tourne en boucle"
Sur main, la règle dit never. Sur toute autre branche, aucune règle ne match, donc le job est exclu aussi. Il ne tourne donc jamais, et comme c'est le seul job, la pipeline ne peut même pas être créée.
Pour que ça tourne partout sauf sur main, il faut rajouter une règle "sinon":
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: never
- when: on_success
workflow¶
workflow:rules décide si la pipeline est créée. Même syntaxe que rules, mais écrit une seule fois, en haut du fichier.
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
- if: '$CI_COMMIT_BRANCH == "main"'
Éviter les pipelines en double¶
Quand on push sur une branche qui a une merge request ouverte, gitlab peut lancer deux pipelines: une pour le push, une pour la MR. Pour n'en garder qu'une:
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: always
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"'
when: never
- if: '$CI_COMMIT_BRANCH'
when: always
Lecture:
- pipeline de MR: ok
- push sur une branche qui a une MR ouverte: non (la pipeline de la MR suffit)
- tout push sur une branche: ok
Même problème avec les tags: un commit tagué puis push peut lancer une pipeline pour le push et une pour le tag (git tag ne crée le tag qu'en local, il faut ensuite git push origin --tags). Pour ignorer les tags:
workflow:
rules:
- if: '$CI_COMMIT_TAG'
when: never
- if: '$CI_PIPELINE_SOURCE == "push"'
Exemple du cours¶
stages:
- build
- test
- deploy
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
- commit poussé sur la branche principale: la pipeline est déclenchée
- commit poussé sur une branche qui a une MR ouverte: pas de pipeline séparée (celle de la MR tourne)
Jobs spécifiques aux tags¶
Un job qui ne tourne que lors d'un push de tag (utile pour une release):
release:
stage: deploy
rules:
# $CI_COMMIT_TAG est uniquement set si on est sur un tag push
- if: '$CI_COMMIT_TAG != null'
when: on_success
- when: never
script: |
echo "Current tag is: $CI_COMMIT_TAG"
Et un job qui ne tourne que dans une merge request:
check-mr:
stage: test
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: on_success
- when: never
script: |
echo "Bonjour depuis la merge request"