I have some rules for example:
.run_for_apple:
- if: '$APPLE == "apple"'
.run_for_orange:
- if: '$ORANGE == "orange"'
I wonder if in my job as below:
job_one:
....
rules:
- !reference [.run_for_apple]
- !reference [.run_for_orange]
Does GitLab ci consider the rule as an and condition or an or condition?
I could not find an explicit explanation. Please let me know if anyone knows anything!
I have seen sometimes the job run when the first rule is true while other rules are false.
Related
I have pipeline that makes some changes and commits another change which triggers another pipeline and I dont want that automatic update to trigger pipeline.
I had an idea that I will specify commit message and that ignore it, but for some reason I cannot get it working.
Can you help me with that?
variables:
COMMIT_MESSAGE: "MyCommitMessage"
workflow:
rules:
- if: $CI_COMMIT_MESSAGE != $COMMIT_MESSAGE
...
You have to add the never keyword and use a regex like this :
variables:
COMMIT_MESSAGE: "MyCommitMessage"
workflow:
rules:
- if: $CI_COMMIT_MESSAGE =~ /^.*COMMIT_MESSAGE/
when: never
- when: always
The if will be evaluate to true and the pipeline will never run.
I am finding it difficult to restrict a stage to only run on MR and be manual
I have the following rules
rules:
- when: manual
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH'
when: never
but this stage is still running under branches, i do not want it to run on any branch, only on MR
it is literally driving me crazy. Code shows what should happen but it just does not follow it
So what am I missing?
From the documentation:
The job is added to the pipeline:
If an if, changes, or exists rule matches and also has when: on_success (default), when: delayed, or when: always.
If a rule
is reached that is only when: on_success, when: delayed, or when: always.
The job is not added to the pipeline:
If no rules match.
If a rule matches and has when: never.
So in order to achieve your requirements (which are add manual job only on MR, otherwise, do not add the job) the right order should be:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: manual
- when: never
This translate to: "When the first if matches -> add job manually, in all other cases -> don't add the job".
We use an on-prem GitLab server. One of the rules for launching our MR pipeline is its state. It should not be Draft or WIP, as I stated below.
rules:
- if: $CI_MERGE_REQUEST_TITLE =~ /^WIP/ || $CI_MERGE_REQUEST_TITLE =~ /^Draft/
when: never
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_PIPELINE_SOURCE == "web"'
But in this form, it does not start in all cases with the error: “No stages/jobs for this pipeline”. Our developers want the MR pipeline to start when you click on the “Run pipeline” button in the “pipelines” section of the current MR. I did not find any indicator for clicking on this button, neither in the webhook nor anywhere else. I tried to use only when: manual, if: '$CI_PIPELINE_SOURCE == "web" and many other rules, but still no luck. Is there a way to make an exception to run the pipeline in this case, but keep it for the rest?
you have to be aware the rules are evaluated in order, and as soon as one applies the evaluation is stopped.
Rules are evaluated when the pipeline is created, and evaluated in order until the first match. When a match is found, the job is either included or excluded from the pipeline, depending on the configuration.
https://docs.gitlab.com/ee/ci/yaml/#rules
this means, if you put - if: '$CI_PIPELINE_SOURCE == "web"' as the first rule, it will be evaluated first. this means if somebody triggers it via web, it does not matter if it is a draft or not.
I have a job template .deploy_to_staging:template with some rule that is extended by another job deploy_to_staging_triggered that adds up another rule:
.deploy_to_staging:template:
<<: *job_deploy_definition
stage: deploy
rules:
- if: '$JOB_TRIGGERED == "DEFAULT"'
deploy_to_staging:triggered:
extends: .deploy_to_staging:template
rules:
- if: '$ENV_TRIGGERED == "STAGING"'
When this is executed, it seems that Gitlab performs a merge that internally creates a job that looks like this one:
deploy_to_staging:mergedJob (following merge)
<<: *job_deploy_definition
stage: deploy
rules:
- if: '$CI_COMMIT_TAG && $JOB_TRIGGERED == "DEFAULT"'
- if: '$ENV_TRIGGERED == "STAGING"'
Gitlab evaluates rules in order until first match according to their docs. So the above if rules acts like OR operators that is logically equivalent to this single IF statement:
- if : '$JOB_TRIGGERED == "DEFAULT" || $ENV_TRIGGERED == "STAGING"'
However I would like all conditions to be verified in order for the job to be executed, i.e having an AND operator instead:
- if : '$JOB_TRIGGERED == "DEFAULT" && $ENV_TRIGGERED == "STAGING"'
How can this be achieved?
Unfortunately, as of Gitlab version 13.9 this isn't possible. The closest they've come to using the rules keyword with templates is allowing conditions to decide if an include is actually included or not using rules (https://gitlab.com/gitlab-org/gitlab/-/issues/216673).
If you're a paying customer, talking to Support (or your sales contact? not sure) will help. Generally Gitlab relies on the community to build wanted features since it is Open Source, but when enough paying customers want a feature, they'll work on it directly.
I would like to run one or multiple jobs within a scheduled context and therefore used the specific rule to declare it like this.
Problem is that the pipeline will neither be triggered by my schedule configuration nor when i manually trigger it via the scheduling pipeline UI. I just don't see any triggered scheduled pipeline at all.
Gitlab Version: 12.9.2
gitlab-ci.yml (partially):
workflow:
rules:
- if: $CI_COMMIT_TAG
- if: $CI_COMMIT_BRANCH
non-scheduled-job:
...
rules:
- if: '$CI_PIPELINE_SOURCE != "schedule"'
scheduled-job:
...
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: always
- if: '$CI_PIPELINE_SOURCE != "schedule"'
when: never
I know that the second rule for the scheduling-job is not needed but even without this the pipeline is not properly running.
Unfortunately, as for Workflows logic, Gitlab is very twiggy.
If you use Workflow section and Rules conditions for your jobs, you have to obviously declare 'Scheduled' type of pipeline in the Workflow section to enable it in your configuration:
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
...
Or you may enable all types of pipelines in your configuration just adding at the end of workflow:rules
workflow:
rules:
...
- when: always
In other way, use may use except/only notation for scheduled jobs and it will work, but only if your workflow conditions met:
only:
- schedules
This approach may appear merging conflicts if you use include option.
Because merging lets you extend and override dictionary mappings, but you cannot add or modify items to an included array. Thus you have to obviously declare all previously added workflow:rules array items in the last included YAML or use anchors.
See issue for details.
You can use only.
E.g.
scheduled-job:
only:
- schedules
https://docs.gitlab.com/ee/ci/pipelines/schedules.html
But, when reusing the snippet in other jobs,
do not use rules togetther with only / except.