Skip to content

Rules et workflow (cas avancés)

Suite de rules et workflow: les opérateurs, les regex, les pipelines manuelles ou planifiées, et des workflow plus complets.

Les opérateurs

Opérateur Sens Exemple
== / != égal / différent $CI_COMMIT_BRANCH == "main"
=~ / !~ correspond / ne correspond pas à une regex $CI_COMMIT_BRANCH =~ /^feature-/
&& ET $A == "x" && $B == "y"
|| OU $A == "x" || $A == "y"
( ) groupement ($A == "x" || $A == "y") && $B
$VAR seul vrai si la variable est définie et non vide $CI_COMMIT_TAG
== null / != null variable absente / présente $CI_COMMIT_TAG != null

&& est prioritaire sur ||. Dès qu'on mélange les deux, on met des parenthèses.

Les regex

Une regex se met entre / /, avec =~:

rules:
  - if: '$CI_COMMIT_BRANCH =~ /^feature-/'         # commence par feature-
  - if: '$CI_COMMIT_BRANCH =~ /^(bugfix|hotfix)-/' # bugfix- OU hotfix-
  - if: '$CI_COMMIT_BRANCH !~ /^release-/'         # ne commence PAS par release-
  - if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/'     # un tag de la forme v1.2.3

^ = début, $ = fin, | = ou, \d+ = un ou plusieurs chiffres.

Pipelines lancées à la main ou planifiées

Selon l'origine, $CI_PIPELINE_SOURCE change:

Valeur Origine
push un push (branche ou tag)
merge_request_event une merge request
web bouton Run pipeline dans l'interface (Build > Pipelines)
schedule une pipeline planifiée
api un appel à l'API
trigger un trigger token
pipeline / parent_pipeline déclenchée par une autre pipeline

La liste complète est dans la page "CI/CD variables" de la doc locale.

# uniquement quand on clique sur "Run pipeline"
job-manuel:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "web"'
  script:
    - echo "lancé à la main"

# uniquement pour les pipelines planifiées
job-nuit:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
  script:
    - echo "lancé par le planning"

La planification se règle dans l'interface, pas dans le yaml: Build > Pipeline schedules, avec une expression cron, par exemple 0 12 * * * (tous les jours à midi).

Workflow en whitelist ou en blacklist

Deux façons de raisonner pour décider quelles pipelines existent.

whitelist: on liste ce qui est autorisé, when: never à la fin pour tout le reste.

workflow:
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
    - if: '$CI_COMMIT_BRANCH =~ /^feature-/'
    - when: never

Pipeline pour main et les branches feature-..., rien d'autre.

blacklist: on bloque ce qu'on ne veut pas, when: always à la fin pour tout le reste.

workflow:
  rules:
    - if: '$CI_COMMIT_BRANCH =~ /^(bugfix|hotfix)-/'
      when: never
    - when: always

Pipeline pour tout sauf bugfix-... et hotfix-....

Exemple combiné: workflow + rules de jobs

workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push" && ($CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH =~ /^release-/)'
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

deploy:
  script:
    - ./deploy.sh
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      when: manual
    - if: '$CI_COMMIT_BRANCH =~ /^release-/'
      when: on_success

test:
  script:
    - ./test.sh
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

Lecture:

  • workflow: une pipeline existe pour un push sur main ou release-*, pour une pipeline planifiée, et pour une MR
  • deploy: manuel sur main, automatique (si les jobs d'avant ont réussi) sur release-*, absent ailleurs
  • test: seulement dans une MR

Le workflow est le premier filtre (la pipeline existe-t-elle ?), les rules des jobs sont le second (ce job est-il dans cette pipeline ?).

Deux when à ne pas confondre

  • when: never dans une règle de job: ce job est exclu
  • when: never dans une règle de workflow: la pipeline entière n'est pas créée

Et si le workflow exclut tout, ou si aucun job ne reste, GitLab ne peut pas créer la pipeline (c'est le piège du job qui ne tourne jamais).