How to run jobs when MR labels was changed? - gitlab-ci

I want to run job when specific label is added to MR.
I tried this code:
stages:
- test_stage
test_job:
stage: test_stage
rules:
- if: $CI_MERGE_REQUEST_LABELS =~ "stage"
script:
- echo "It works!"
But after adding label "stage" to MR there is no reaction.

Related

Gitlab CI conditionally override a template variable based on which files were changes in a MR

I have template that looks like this:
/templates/.copy-echo.yml:
workflow:
rules:
- if: '$CI_COMMIT_REF_NAME == "master"'
variables:
FILE_PATH: /test_conf_1.txt
DESTINATION_HOST: somehost
stages:
- copy
- echo
copy step 1/2:
rules:
- changes:
- ${FILE_PATH}
stage: copy
script: |
echo "Add copy here!"
copy step 2/2:
rules:
- changes:
- ${FILE_PATH}
stage: echo
script: |
printenv
echo ${DESTINATION_HOST}
Now in my .gitlab-ci.yml:
include: '/templates/copy-echo.yml'
variables:
FILE_PATH: /test_conf_1.txt
DESTINATION_HOST: somehost2
Now what I want is conditionally assign a value to DESTINATION_HOST variable depending on which file got changed in merged request.
For e.g. if the merge request had updates to file test_conf_2.txt then the value for DESTINATION_HOST should be somehost2 and if the merge request had updates to file test_conf_3.txt then the value for DESTINATION_HOST should be somehost3.
Is it possible to achieve this?
You can use rules:variables: https://docs.gitlab.com/ee/ci/yaml/#rulesvariables
Example:
my job:
script: printenv
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
changes:
- test_conf_2.txt
variables:
DESTINATION_HOST: "somehost2"
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
changes:
- test_conf_3.txt
variables:
DESTINATION_HOST: "somehost3"
But it doesn't work if you launch pipeline manually:
You should use rules: changes only with branch pipelines or merge
request pipelines. You can use rules: changes with other pipeline
types, but rules: changes always evaluates to true when there is no
Git push event. Tag pipelines, scheduled pipelines, manual pipelines,
and so on do not have a Git push event associated with them. A rules:
changes job is always added to those pipelines if there is no if that
limits the job to branch or merge request pipelines.

Why jobs running with set "only" keyword?

I tried to spice my gitlab gitflow with gitlab-cicd. My goal is to create a job which is running while a merge request and check if the source branch for this merge request is either a hotfix/* or release/* branch. A simple bash script is in charge for this:
#!/bin/bash
if [[ "$1" =~ ^hotfix/* ]]; then
echo "Begin Hotfix Merge"
exit 0
else
echo "ERROR: Directory does not exist."
exit 1
fi
where $1 is the predefined variable CI_MERGE_REQUEST_SOURCE_BRANCH_NAME as argument of the script.
My .gitlab-ci.yaml looks the following:
image: ubuntu:latest
stages:
- test
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
test1:
tags:
- docker
- linux
stage: test
script:
- echo "Do a test here"
- echo "For example run a test suite"
- echo $PWD
- ls -la .gitlab/
job1:
tags:
- docker
- linux
script:
- echo "This job runs in merge request pipelines"
- echo $PWD
- ls -la .gitlab/workflow-scripts/
- echo "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"
- bash ./.gitlab/workflow-scripts/check_sourcebranch.sh "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"
only:
- merge_requests
- master
I am not shure if the workflow:rules distrubs anything. If I now start a merge request the pipeline runs without any issues inside the merge request, but if I aprove the request and the pipeline gets triggered again, both jobs are running.
Any Idea, why job1 is triggered, even with the only rule?
EDIT: I removed the part with the unexpected error. This Error was a residual of a classic copy&pasta and was actually expected in this scenario.
Fixed job for testing branch name on MR:
stages:
- tests
image: ubuntu:latest
test-mr-branch-name:
stage: tests
only:
- merge_requests
tags:
- docker
- linux
script:
- |
if [[ ! "${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}" =~ ^(hotfix|release)\/.+$ ]]; then
echo "ERROR: Wrong Merge!"
exit 1
fi
p.s. Operator between values of only tag is or. Read me.
p.s. You may set multiline bash script in Gitlab CI.

GITLAB CI/CD: How to know if a pipeline is a tag pipeline, an MR pipeline or a scheduled pipeline?

There's a part of the script which I want to run only if it's a tag pipeline. How do I represent that as a condition?
You can use rules or the only keyword to run only on tags or merge requests.
rules:
job1:
script:
- echo "This job runs in merge request pipelines"
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
only:
job1:
script:
- echo "This job runs in merge request pipelines"
only:
- merge_requests
To run only on tags you can use:
job1:
script:
- echo "This job runs only on tags"
only:
- tags
Docs: https://docs.gitlab.com/ee/ci/yaml/#onlyrefs--exceptrefs

Gitlab CI Pipeline job

Below is a Gitlab CI pipeline code
- image_build
- test1
- test2
image_build:
stage: image_build
tags:
- ddc
script:
- echo "image build"
rules:
- changes:
- Dockerfile
test1:
stage: test1
tags:
- ddc
script:
- echo "Test1 stage"
rules:
- when: on_success
test2:
stage: test2
tags:
- ddc
script:
- echo "Test2 stage"
rules:
- when: on_failure
I need the stages test1, test2 to execute if no changes has been done to Dockerfile. And also the same stages test1, test2 should not execute when there are changes to Dockerfile.
The second scenario works fine but the first one doesnt. Please help me get this pipeline up and running.
If you are using GitLab CI version 11.4 or above you can use only: changes or rules: changes parameters. Base on official docs:
Using the changes keyword with only or except makes it possible to define if a job should be created based on files modified by a Git push event.
So your test1 and test2 stages might look like this:
⋮
test1:
stage: test1
tags:
- ddc
script:
- echo "Test1 stage"
rules:
- when: on_success
except:
changes:
- Dockerfile
test2:
stage: test2
tags:
- ddc
script:
- echo "Test2 stage"
rules:
- when: on_failure
except:
changes:
- Dockerfile
⋮

How to create Gitlab CI rules that are evaluated as AND instead of OR

The following gitlab ci job will run if the variable $CI_COMMIT_TAG is set OR if the ./versions.txt file has changed.
some-job:
script:
- echo "Do some fancy stuff.";
rules:
- if: $CI_COMMIT_TAG
when: always
- changes:
- ./versions.txt
However, what I need is for this job to run when $CI_COMMIT_TAG is set AND ./versions.txt is changed. I don't want the job to run if only one of these evaluates to true. This was the behaviour in only/changes feature, but the only (and except)-feature is less powerful and deprecated.
Is what I want currently possible with gitlab ci?
From Docs:
In the following example:
We run the job manually if Dockerfile or any file in docker/scripts/ has changed AND $VAR == "string value". Otherwise, the job will not be included in the pipeline.
docker build:
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- if: '$VAR == "string value"'
changes: # Will include the job and set to when:manual if any of the follow paths match a modified file.
- Dockerfile
- docker/scripts/*
when: manual
Your code will look something like this.
some-job:
script:
- echo "Do some fancy stuff.";
rules:
- if: $CI_COMMIT_TAG
changes:
- versions.txt
when: manual