Using conditionals in GitLab CI with user intervention - gitlab

Is that possible to add conditionals that executes if or else block based on a user input in GitLab CI yml?
In the event the user input is a YES then it must trigger a template(ansible tower template) to restart specific service (tower-cli job launch --job-template)
Should I userules:if with when for such a conditional.Could someone put an insight on such a format.I am a first time user in Gitlab and have some experience in Jenkins.

The rules section (and also only and except) are evaluated when the pipeline is first created, but before the first job starts running because it controls which jobs will be in a pipeline or not, so you can't use variables/conditionals that come from another job or manual task variables.
An alternative is to use a normal bash conditional in your script section and simply exit 0; when the job shouldn't run.
...
Job:
stage: my_stage
when: manual
script:
- if [ $MY_USER_INPUT_VARIABLE == "don't run the job" ] then exit 0; fi
- ./run_job.sh
These are just simple examples, but you check the variable for whatever it is you need it to do (or use multiple conditionals if using multiple variables) and if the job shouldn't run, execute exit 0; which will stop the job from processing, but will not mark it as failed. Otherwise, we run whatever we need this job to do.

Related

How to exclude gitlab CI job from pipeline based on a value in a project file?

I need to exclude a job from pipeline in case my project version is pre-release.
How I know it's a pre-release?
I set the following in the version info file, that all project files and tools use:
version = "1.2.3-pre"
From CI script, I parse the file, extract the version value, and know whether it's a pre-release or not, and can set the result in an environment variable.
The only way I know to exclude a job from pipeline is to use rules, while, I know also from gitlab docs that:
rules are evaluated before any jobs run
before_script also is claimed to be called with the script, i.e. after applying the rules.
I can stop the job, only after it starts from the script itself, based on the version value, but what I need is to extract the job from the pipeline in the first place, so it's not displayed in the pipeline history. Any idea?
Thanks
How do you run (start) your pipeline, and is the information whether "it's a pre-release" already known at this point?
If yes, then you could add a flag like IS_PRERELEASE as a variable to the pipeline, and use that in the rules: section of your job. The drawback is that this will not work with automatic pipelines (triggered by a commit or MR); but you can use this approach with manually triggered pipelines (https://docs.gitlab.com/ee/ci/variables/#override-a-variable-when-running-a-pipeline-manually) or via the API (https://docs.gitlab.com/ee/ci/triggers/#pass-cicd-variables-in-the-api-call).

How to read labels in Gitlab CI script

I have a few use cases in my Gitlab setup I would like to be able to support:
If a certain label (let's call it “skip_build”) is set, the deployment steps should not be run when I merge an MR to a main branch. This would be useful when we have multiple MRs being merged right after another and only need the last one built.
If another label (we'll call it “skip_tests”) is set, I should be able to read it as an env var from within the script and alter the flow within the script accordingly (using normal bash syntax), e.g. to alter the package command parameters used a bit. This is useful for small changes where it might not make sense to run a lengthy test suite.
Is this possible with Gitlab, and if so, how?
I’ve tried experimenting with CI_MERGE_REQUEST_LABELS, but it doesn’t seem to be able to read that as an env var from within the script.
You have to use merge request pipelines for the CI_MERGE_REQUEST_LABELS variable (and other MR-related variables) to be present as documented in predefined variables.
You could use a rules: clause to skip jobs. Something like
build:
rules: # only run this job if the regex pattern does not match
- if: $CI_MERGE_REQUEST_LABELS !~ /skip_build/
You can also do this on any other kind of predefined (or user-defined) variable, like branch name, commit messages, MR titles, etc. Whatever works for you.
For example, a built in feature of GitLab is that if your commit message contains [ci skip] it will prevent the pipeline from running. You could implement similar functionality for your jobs and/or pipelines through rules: or workflow:rules:.

Add GitLab CI job to pipeline based on script command result

I have a GitLab CI pipeline with a 'migration' job which I want to be added only if certain files changed between current commit and master branch, but in my current project I'm forced to use GitLab CI pipelines for push event which complicates things.
Docs on rules:changes clearly states that it will glitch and will not work properly without MR (my case of push event), so that's out of question.
Docs on rules:if states that it only works with env variables. But docs on passing CI/CD variables to another job clearly states that
These variables cannot be used as CI/CD variables to configure a
pipeline, but they can be used in job scripts.
So, now I'm stuck. I can just skip running the job in question overriding the script and checking for file changes, but what I want is not adding the job in question to pipeline in first place.
While you can't add a job alone to a pipeline based on the output of a script, you can add a child pipeline dynamically based on the script output. The method of using rules: with dynamic variables won't work because rules: are evaluated at the time the pipeline is created, as you found in the docs.
However, you can achieve the same effect using dynamic child-pipelines feature. The idea is you dynamically create the YAML for the desired pipeline in a job. That YAML created by your job will be used to create a child pipeline, which your pipeline can depend on.
Sadly, to add/remove a Gitlab job based on variables created from a previous job is not possible for a given pipeline
A way to achieve this is if your break your current pipeline to an upstream and downstream
The upstream will have 2 jobs
The first one will use your script to define a variable
This job will trigger the downstream, passing this variable
Upstream
check_val:
...
script:
... Script imposes the logic with the needed checks
... If true
- echo "MY_CONDITIONAL_VAR=true" >> var.env
... If false
- echo "MY_CONDITIONAL_VAR=false" >> var.env
artifacts:
reports:
dotenv: var.env
trigger_your_original_pipeline:
...
variables:
MY_CONDITIONAL_VAR: "$MY_CONDITIONAL_VAR"
trigger:
project: "project_namespance/project"
The downstream would be your original pipeline
Downstream
...
migration:
...
rules:
- if: '$MY_CONDITIONAL_VAR == "true"'
Now the MY_CONDITIONAL_VAR will be available at the start of the pipeline, so you can impose rules to add or not the migration job

Run triggered Gitlab jobs only on specific days

I have the following issue:
I have a scheduled git pipeline which runs every work day in the morning. This pipeline is triggering other pipelines of other projects. The jobs are defined in multiple gitlab.yml files in their corresponding projects. For better understanding, here is a minimal example with only one triggered job:
main job:
trigger: child job
child job:
// Do something here
Now the thing is that this triggered child job is only allowed to run on specific days. In our case, it is that the child job is not allowed to run on Mondays.
I already had the idea to distinguish in the main job on which day the child job should be executed, give the child job a variable and check the given variable with the only or except tags. But it seems like it is not that easy to get the current work day inside the gitlab.yml. Or am I wrong there?
Is there a way to achieve this?
UPDATE
#KamilCuk made me realize that I was missing an important aspect in the question. When the child job is executed on its own, it should run without any hinderance (also on monday) if possible. When triggered by the main job, the check should apply.
The simplest is to just check it in the job.
child job:
script:
- weekday=$(LC_ALL=C date +%a)
- case "$weekday" in
Mon) echo "Not running on monday"; exit 0; ;;
esac
- rest of the job
You can trigger the job via API. https://docs.gitlab.com/ee/api/pipeline_triggers.html https://docs.gitlab.com/ee/ci/triggers/index.html
main job trigger child job:
script:
- weekday=$(LC_ALL=C date +%a)
- case "$weekday" in
Mon) echo "Not running on monday"; exit 0; ;;
esac
- curl
-H "Authorization: Bearer somethingosmething"
$CI_GITALB_URL/.../api/4/....
trigger child job

Azure DevOps - Run Build job Conditional statement and expression

I am trying to run a CI stage in Azure DevOps in a self-hosted Linux Agent. The stages look like below:
CI - Build Job:
Task 1: Python script to check a TRUE OR FALSE condition
Task 2: Bash script to execute certain commands
Now, Task 2 Should run only when the Task 1 py script execution contains only "TRUE".
I have referred a few docs which suggested to go with custom conditions from the following link:
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/conditions?view=azure-devops&tabs=classic
But not sure how to write custom condition as I am new to this.
NOTE: I want to try only in a custom mode, not in YAML
We can define a new variable or update a variable in the python script when the Task 1 py script execution contains only "TRUE", then use the variable in the condition. Sample condition eq(variables['{variable name}'], '{variable value}'), the task 2 will only run if the condition is determined to be successful, if the result is fail, the task 2 will be skipped.

Resources