GitLab CI - Check if branch is within list of branches - gitlab

I want to be able to set a list of branches on the GitLab CICD variables on the UI and have the pipeline check that list to see if it should run a specific job.
I am trying to turn this rule:
rules:
- if: $CI_COMMIT_BRANCH == "poc5"
- if: $CI_COMMIT_BRANCH == "poc5-s1"
- if: $CI_COMMIT_BRANCH == "poc5-s2"
- if: $CI_COMMIT_BRANCH == "poc5-s3"
Into this:
rules:
- if: $CI_COMMIT_BRANCH in $DEFAULT_BRANCHES
Where $DEFAULT_BRANCHES is a variable defined in the projects CICD variables as follows:
DEFAULT_BRANCHES:
poc5
poc5-s1
poc5-s2
poc5-s3
or
poc5 poc5-s1 poc5-s2 poc5-s3
The best I could come up with was the following, which results in an invalid syntax for GitLab CI rules:
rules:
- if: echo $DEFAULT_BRANCHES | tr ' ' '\n' | grep -q -E "^${CI_COMMIT_BRANCH}$"
I am essentially trying to not have the list of branches hard coded into the pipeline yml file.
Is there a way to achieve what I am trying to do?

A solution is:
# .gitlab-ci.yml
if: "$CI_COMMIT_BRANCH == 'poc5' || $CI_COMMIT_BRANCH == 'poc5-s1' || $CI_COMMIT_BRANCH == 'poc5-s2' || $CI_COMMIT_BRANCH == 'poc5-s3'"
when: on_success
But a shorter version with regex is:
# .gitlab-ci
if: $CI_COMMIT_BRANCH =~ /^poc5(-s[1-3])?$/
when: on_success

Related

Gitlab CI/CD workflow rule variables only allow one if condition

I am currently trying to structure my .gitlab-ci.yml file like following:
There is one pipeline called "a" which should run only from the develop branch
There is one pipeline called "b" which should run only from the develop branch but only when triggered from the web
In order to avoid putting these rules in the jobs directly (in reality there are about 30 jobs) I want to reuse those rules globally. I could not find a better way other than using workflow:rules.
workflow:
rules:
- if $CI_COMMIT_BRANCH == "develop"
variables:
RUN_A: "true"
- if $CI_COMMIT_BRANCH == "develop" && $CI_PIPELINE_SOURCE == "web"
variables:
RUN_B: "true"
job-a:
rules:
- if: $RUN_A == "true"
script:
- exit 0
job-b:
rules:
- if: $RUN_B == "true"
script:
- exit 0
The problem is, that if there is a web trigger on develop, it will not set "RUN_B" to true. It will just have "RUN_A" with true. I added another job to print out the variables just to make sure:
test:
image: alpine
script:
- echo $RUN_A
- echo $RUN_B
This will only print true for RUN_A but nothing for RUN_B. I could not find anything in Gitlabs documentation that states it will only use the first matching rule. Anyhow, is there a better way to handle this? What am I missing?
Because GitLab ci Rules evaluated in order until the first match.
in your first rule if $CI_COMMIT_BRANCH == "develop" is match, the pipeline is create, in this times variable RUN_A: "true" is set, but variable RUN_B is undefined.
In your case, you can modify your .gitlab-ci.yml. variable setting and rules order.
workflow:
rules:
- if: $CI_COMMIT_BRANCH == "develop" && $CI_PIPELINE_SOURCE == "web"
variables:
RUN_B: "true"
RUN_A: "true"
- if: $CI_COMMIT_BRANCH == "develop"
variables:
RUN_A: "true"
default:
image: alpine
job-a:
rules:
- if: $RUN_A == "true"
script:
- exit 0
job-b:
rules:
- if: $RUN_B == "true"
script:
- exit 0
test:
script:
- echo $RUN_A
- echo $RUN_B

How to convert only/except gitlab logic to rules?

I currently have the below:
jobA:
only:
refs:
- merge_requests
- main
except:
refs:
- pipelines
The jobA above is triggered from an upstream pipeline using the trigger: keyword
How to represent the logic above with rules?
Is the above logically equivalent to the below?
rules:
- if: '$CI_PIPELINE_SOURCE == "pipelines"'
when: never
- if: ('$CI_PIPELINE_SOURCE == "merge_request_event"' || $CI_COMMIT_BRANCH == "mainline"')
when: on_success

Is that possible to hide the stage in gitlab ci workflow?

I'd like to make the stage uninterruptible that runs the uninterruptible_job invisible (for master and release/v branches). Is there any function in gitlab ci to make that work ?
stages:
- uninterruptible
- pre_check
- build
- assign_test
- host_test
- deploy
workflow:
rules:
- if: '$CI_COMMIT_REF_NAME != "master" && $CI_COMMIT_BRANCH !~ /^release\/v/ && $CI_COMMIT_TAG !~ /^v\d+\.\d+(\.\d+)?($|-)/ && $CI_PIPELINE_SOURCE == "push"'
when: never
- if: $CI_OPEN_MERGE_REQUESTS != null
variables:
PIPELINE_COMMIT_SHA: $CI_MERGE_REQUEST_SOURCE_BRANCH_SHA
- if: $CI_OPEN_MERGE_REQUESTS == null
variables:
PIPELINE_COMMIT_SHA: $CI_COMMIT_SHA
- when: always
before_script:
- echo "Before script is started here"
default:
interruptible: true
retry:
max: 2
when:
- always
uninterruptible_job:
stage: uninterruptible
interruptible: false
resource_group: production
script:
- echo "$CI_COMMIT_BRANCH is uninterruptible"
tags:
- assign_test
rules:
- if: '$CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_BRANCH =~ /^release\/v/'
when: always
include:
- '.gitlab/ci/pre_check.yml'
- '.gitlab/ci/build.yml'
- '.gitlab/ci/assign_test.yml'
- '.gitlab/ci/host_test.yml'
- '.gitlab/ci/deploy.yml'
No. There is no feature of GitLab to hide jobs visibly in the UI.
You can delete job traces and artifacts or delete entire pipelines (like after they finish running), but there is no way to just hide stages or jobs in GitLab's pipeline visualization UI.

Can we use "only" instead of "rules" in gitlab?

In my gitlab ci/cd script , we are using rules
workflow:
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "developer" || $CI_COMMIT_BRANCH == "stage"|| ($CI_COMMIT_BRANCH =~ (/^([A-Z]([0-9][-_])?)?SPRINT(([-_][A-Z][0-9])?)+/i))
when: always
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH != "developer" || $CI_COMMIT_BRANCH != "stage"|| ($CI_COMMIT_BRANCH !~ (/^([A-Z]([0-9][-_])?)?SPRINT(([-_][A-Z][0-9])?)+/i))
when: never
for specific job , we are using only
only:
- developer
- stage
FINE. but I want the scenerio like
only:
- developer
- stage
- (/^([A-Z]([0-9][-_])?)?SPRINT(([-_][A-Z][0-9])?)+/i))
the sprint which I used is not working . If I use "rules" , its working , but I want "only" to be used in my script . Please help me to sort it out this.
An only: directove does support regular expressions that match against branch names.
But the syntax is like /^feature-.*/, so check if the outer () are in the way.
Plus, there seems to be an imbalance in the 5 ( vs. 6 ).
So either:
(/^([A-Z]([0-9][-_])?)?SPRINT(([-_][A-Z][0-9])?)+/i)
Or
/^([A-Z]([0-9][-_])?)?SPRINT(([-_][A-Z][0-9])?)+/i

for this condition , the pipeline didn't trigger ? why?

[rules:
if: '$CI_COMMIT_BRANCH =~ /^SPRINT[-][0-9]+/i'
when: always
if: '$CI_COMMIT_BRANCH !~ /^SPRINT[-][0-9]+/i'
when: never ]
If I add like this , its triggers, for the pipeline only for (sprint) name related branches but I want the rules like
[ rules:
if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && '$CI_COMMIT_BRANCH =~ /^SPRINT[-][0-9]+/i'
when: always
if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && '$CI_COMMIT_BRANCH !~ /^SPRINT[-][0-9]+/i'
when: never]
-If I gave like this, its doesn't trigger for sprint related branches. I want to run the pipeline for (sprint)named branches and also default branch and also specific named branches like dev , stage which I'm using in a single command line
.
.
.
.
.
.
If I split the command also, I doesn't works
for eg:
[rules:
if: '$CI_COMMIT_BRANCH =~ /^SPRINT[-_][0-9]+/i'
when: always
if: '$CI_COMMIT_BRANCH !~ /^SPRINT[-_][0-9]+/i'
when: never
if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == 'dev'
when: always
if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH != 'dev'
when: never]- It doesn't trigger in dev branch
. can you please anyone help me to sort it out
Cyril I
Rules are evaluated one by one and evaluation stops on the first expression that evaluates to true. Your first two regex rules (=~ then !~ for the same regex pattern) will prevent any further rules from being evaluated because one of those two expressions will always evaluate true.

Resources