4

I am trying to build a Gitlab CI yml, that triggers a certain job:

  • when the commit is tagged in the form x.y.z
  • I trigger manually via the Gitlab webapp
  • the commit message ends with a certain regex ("-build_doc")

with the bullets being logical or statements. I tried only statements and rules alike but couldn't figure it out. Web and tag already worked like so:

script: ... only: - /^v(\d+)\.(\d+)\.(\d+)$/ #tag - web 

I also found this issue, which allows the commit message condition via only:variables, but now I struggled with the other two...

My trial with rules:

script: ... rules: - if: '$CI_PIPELINE_SOURCE == "web"' - if: '$CI_COMMIT_MESSAGE =~ /^.*-build_doc$/' - if: $CI_COMMIT_TAG 

Any advice? Thanks!!

2 Answers 2

3

Just for the sake of completeness I am posting my final solution as an alternative answer. It is still based on Adams solution, but uses multiple if statements instead.

script: ... rules: - if: '$CI_PIPELINE_SOURCE == "web"' - if: '$CI_COMMIT_MESSAGE =~ /^.*\[build_doc\].*$/s' - if: '$CI_COMMIT_REF_NAME =~ /^(\d+)\.(\d+)\.(\d+)$/' - when: always 
Sign up to request clarification or add additional context in comments.

Comments

2

You won't be able to get your desired result using the only syntax due to the way it's evaluated. The example you have above is a simple/shorthand way of using the refs keyword, so it is the same thing as

only: refs: - /^v(\d+)\.(\d+)\.(\d+)$/ #tag - web 

For this alone, the job will be added to the pipeline if any of the refs matches. When combined with the other keywords (like variables or kubernetes), the keywords are combined using AND's. So with this example, one of the refs must match, AND the variable must match. There's no way to make it an OR.

only: refs: - /^v(\d+)\.(\d+)\.(\d+)$/ #tag - web variables: - $CI_COMMIT_MESSAGE =~ /^my message/ 

You should be able to get your desired result using the newer rules syntax though. If you have multiple if statements, they are OR'ed together, not AND'ed. An example of how if's are evaluated are in the docs here: https://docs.gitlab.com/ee/ci/yaml/#rules-clauses. In a single if statement, you can combine conditions using || for OR and && for AND. You can see examples of that here: https://docs.gitlab.com/ee/ci/yaml/#rulesif

So for this use case, I'd try either

rules: - if: '$CI_PIPELINE_SOURCE == "web" || $CI_COMMIT_MESSAGE =~ /^my message/i || $CI_COMMIT_REF_NAME =~ /^v(\d+)\.(\d+)\.(\d+)$/' when: always 

You're not required to add the when clause to your if statements, and if you don't it will use the when you put on the job, or use the default on-success.

Also, all the pre-defined variables you can use are listed here: https://docs.gitlab.com/ee/ci/variables/predefined_variables.html.

4 Comments

Thanks Adam! Followup question: What is the difference between your suggested solution and mine, using rules (not considering syntax errors, but only semantic logic)? Or asked differently: what's the difference between multiple ifs and || ?
There's no difference between multiple if's and ||'s, just that the only way to get &&'s is in a single if.
Actually, there is a benefit of doing an OR inline, you can use parentheses to create a more complex conditional.
This worked for me thanks - the only problem is that when I add the comment, as well as adding the conditional job to the pipeline, it adds an entirely new "detached" pipeline with just that job. This one fails. Any idea how to stop that? Thanks

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.