3

After having to manually update my repo because I forgot to change the version number... twice, I decided it was time for some CI magic.

Here's the deal: if I make a Merge Request into main, I expect the application version number to have changed in 3 different files.

Here is my code so far:

stages:
  - test
  - deploy

workflow:
  # some rules

unit_test:
  stage: test
  script:
    # run UT

# This is the part the question is about
check_version:
  stage: test
  rules:
    - if: '$CI_PIPELINE_SOURCE' == "merge_request_event" && '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME' == '$CI_DEFAULT_BRANCH'
      changes:
        - composer.json
        - resources/index.php
        - Doxyfile

deploy:
  stage: deploy
  script:
    # deployment script
  rules:
    - if: '$CI_COMMIT_BRANCH' == '$CI_DEFAULT_BRANCH'

If I understood things correctly, what I did is "If it's a Merge Request into main, check for changes in composer.json, resources/index.php and Doxyfile".

First: is it correct?

Second: what do I do to allow pushes and Merge Requests in other branches? Is there some kind of "else" that follows the "if"?

SteeveDroz
  • 6,006
  • 6
  • 33
  • 65

1 Answers1

4

According to the documentation for the rules keyword, the way you have it is correct based on the description of what you want. If a pipeline is run for a Push event, for a different branch, or if no changes are included for those three files, the check_version job will not be added to the pipeline (you won't even see it in the pipeline diagram), and all other jobs will run based on their own rules clause, if any, or an explicit when clause.

However, others working on your project might find this way confusing, so personally I always add an explicit when:never in these cases:

...
check_version:
  stage: test
  rules:
    - if: '$CI_PIPELINE_SOURCE' == "merge_request_event" && '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME' == '$CI_DEFAULT_BRANCH'
      changes:
        - composer.json
        - resources/index.php
        - Doxyfile
    - when: never
...

This will end up with the same result as your example in your question, but in my opinion is more clear. When this is evaluated during the push/merge request/trigger/etc. event, if the if conditional passes, the job is added to the pipeline. Otherwise, it [explicitly] isn't.

Adam Marshall
  • 6,369
  • 1
  • 29
  • 45
  • 1
    Excellent, `when: never` corresponds to that `else` I was looking for. This is perfect, thanks! – SteeveDroz Aug 25 '21 at 18:08
  • 1
    One note about the `rules` keyword, multiple clauses are only ever interpreted as logical OR, no matter if it's multiple if's, a separate `when` clause like above, etc., it's interpreted as `OR`. The only way to get a logical AND is in the same conditional, like in your example. – Adam Marshall Aug 25 '21 at 19:14
  • 3
    That is such a simple explanation, thank you! `- X ⏎ Y` is AND, `- X ⏎ - Y` is OR, brilliant! – SteeveDroz Aug 26 '21 at 04:55