My GitLab pipelines execute automatically on every push, I want to manually run pipeline and not on every push.
Pipeline docs: https://docs.gitlab.com/ee/ci/yaml/#workflowrules
I tried this in
.gitlab-ci.yml
workflow:
rules:
- when: manual # Error: workflow:rules:rule when unknown value: manual
as mentioned in the documentation, I think you should specify a condition that tells Gitlab to not run the pipeline specifically on push events like so:
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
when: never # Prevent pipeline run for push event
- when: always # Run pipeline for all other cases
Well, this was all from the official documentation but I hope that this may help you :)
We can define your jobs to be only executed on Gitlab.
The web option is used for pipelines created by using Run pipeline button in the GitLab UI, from the project's CI/CD > Pipelines section.
only:
- web
Here is the solution I cam up with:
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "web"'
when: always
- when: never
This specifies that it will only run if you click the "Run Pipeline" button in the web UI. In all other cases it will not be triggered.
the when section should not be within rules
workflow:
when: manual
Related
I have a pipeline which builds and deploys my application to staging environment.
I want to create a job which can deploy my application to production environment, but it should be run manually.
In theory I see 2 options:
Create a separate .deploy-to-prod.yml pipeline with when: manual condition and run it via "play" button. As far as I understand its impossible because I cannot run an arbitrary pipeline in Gitlab, it always runs default one. Please correct me if I am wrong.
Hence only 2nd option is available for me: I need to create additional trigger job in my default .gitlab-ci.yml and add conditions: if execution is manual and some variable is set or environment = production - then run deploy to prod, otherwise a standard job should be executed.
An example of 2nd approach can look like:
manual-deploy-to-prod:
stage: deploy
trigger:
include:
- '.deploy-to-prod.yml'
strategy: depend
rules:
- if: $MANUAL_DEPLOY_VERSION != null
when: manual
..while in standard pipeline triggers I should add following lines to avoid execution along with production deployment:
rules:
- if: $MANUAL_DEPLOY_VERSION == null
Is this a good approach?
Is it correct that only 2nd option is available for me?
What is the best practice for creating a manual production deployment pipeline?
"Best" is a very subjective term, so it's difficult to tell you which one is best for your use-case. Insteaad, let me lay out a couple of options for how you could achieve what you're attempting to do:
You could update your deploy process to use deploy.yml, then use the trigger keyword in your CI file to trigger that job for different environments. You can then use the rules keyword to control when and how different jobs are triggered. This has the benefit of re-using your deployment process that you're using for your staging environment, which is nice and DRY and ensures that your deployment is repeatable across environments. This would look like this:
deploy-to-staging:
stage: deploy
trigger:
include: deploy.yml
strategy: depend
when: on_success
deploy-to-production:
stage: deploy
trigger:
include: deploy.yml
strategy: depend
when: manual
You could use the rules keyword to include your deploy-to-production job only when the job is kicked off manually from the UI. The rest of your pipeline would still execute (unless you explicitly tell it not to), but your deploy-to-prod job would only show up if you manually kicked the pipeline off. This would look like this:
deploy-to-prod:
stage: deploy
script:
- echo "I'm deploying!"
rules:
- if: $CI_PIPELINE_SOURCE == "web"
when: on_success
- when: never
You could use a separate project for your deployment pipeline. This pipeline can retrieve artifacts from your other project, but would only run its CI when you manually click on run for that project. This gives you really nice separation of concerns because you can give a separate set of permissions to that project as opposed to the code project, and it can help keep your pipeline clean if it's really complicated.
All approaches have pros and cons, simply pick the one that works best for you!
I want to send a slack notification as soon as trigger the pipeline build manually.
Steps I am following:
Go to your project’s CI/CD > Pipelines and select Run pipeline.
Choose the branch you want to run the pipeline for.
Input the variable and its value in the UI.
Click on the Run pipeline button
From the documentation I see:
How the pipeline was triggered. Can be push, web, schedule, api, external, chat, webide, merge_request_event, external_pull_request_event, parent_pipeline, trigger, or pipeline. For a description of each value, see Common if clauses for rules, which uses this variable to control when jobs run.
In this init stage I want to execute a script only when I run the pipeline using the above steps
init:
stage: init
environment: $DEPLOY_ENVIRONMENT
script:
- bundle exec fastlane slack_build_start_summary
rules:
- if: $CI_PIPELINE_SOURCE == "trigger" // also tried with "pipeline"
when: always
But I can't see this stage in the Gitlab pipeline stages.
I want to know which CI_PIPELINE_SOURCE ("trigger" or "pipeline" or something else?) I need to check when I trigger the pipeline manually from Gitlab using the above steps.
I got the answer here from the documentation
web -> For pipelines created by using Run pipeline button in the GitLab UI, from the project’s CI/CD > Pipelines section.
So I need to use:
- if: $CI_PIPELINE_SOURCE == "web"
My GitLab pipelines execute automatically on every push, I want to manually run pipeline and not on every push.
Pipeline docs: https://docs.gitlab.com/ee/ci/yaml/#workflowrules
I tried this in
.gitlab-ci.yml
workflow:
rules:
- when: manual # Error: workflow:rules:rule when unknown value: manual
as mentioned in the documentation, I think you should specify a condition that tells Gitlab to not run the pipeline specifically on push events like so:
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
when: never # Prevent pipeline run for push event
- when: always # Run pipeline for all other cases
Well, this was all from the official documentation but I hope that this may help you :)
We can define your jobs to be only executed on Gitlab.
The web option is used for pipelines created by using Run pipeline button in the GitLab UI, from the project's CI/CD > Pipelines section.
only:
- web
Here is the solution I cam up with:
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "web"'
when: always
- when: never
This specifies that it will only run if you click the "Run Pipeline" button in the web UI. In all other cases it will not be triggered.
the when section should not be within rules
workflow:
when: manual
As several other users, I'm facing issues with duplicate pipelines in GitLab CI/CD. While there is some documentation on how to prevent this scattered around in the GitLab docs,
my impression is that the indivdual docs pages and sections are rather inconsistent.
My question is, what are the differences between the following rules? Or, more specifically, are there cases in which these rules are evaluated differently?
Switch between branch pipelines and merge request pipelines suggest this to identify merge request pipelines:
if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
Additionally, Switch between branch pipelines and merge request pipelines also uses this rule in combination with $CI_COMMIT_BRANCH &&:
if: '$CI_OPEN_MERGE_REQUESTS'
Moreover, the MergeRequest-Pipelines.gitlab-ci.yml uses a third rule:
if: $CI_MERGE_REQUEST_IID
Any explanation or hints to docs pages I might have overlooked is highly appreciated.
In order to avoid duplicate pipeline creation and the requirement that you want to switch between Branch-Pipelines and Merge-Request-Pipelines I recommend using these workflow rules
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never
- if: '$CI_COMMIT_BRANCH' || '$CI_COMMIT_TAG'
There is another SO-question that asks how to prevent duplicate pipelines here
The Explanation(s):
In the following section I will try to explain your different rules and how GitLab CI will evaluate them during pipeline creation.
The merge_request_event-rule
Using this rule:
if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
will create a pipeline each time a Merge-Request is created/updated, but there will also be a pipeline created for the branch if you do not have another prevention mechanism (rule).
As the variable naming also points out, this is about the source of the pipeline trigger, other sources could be schedule, push, trigger etc.
The CI_OPEN_MERGE_REQUESTS variable:
Using a rule like:
if: '$CI_OPEN_MERGE_REQUESTS'
GitLab will create new pipelines if there is an open Merge-Request for this branch. Pipelines because there will be a Merge-Request pipeline (denoted with the detached flag) and a branch pipeline for the branch you pushed changes.
if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
This rule above will create a pipeline for your branch when, and only when there is an open MR on that branch.
if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never
When using the above combination no pipeline will be created if there are open Merge-Requests on that branch, which might also be undesirable since the CI should run tests for branches and/or Merge-Requests.
But how to be able to have pipelines for MRs and Branches, but prevent duplications in pipeline creation?
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never
- if: '$CI_COMMIT_BRANCH' || '$CI_COMMIT_TAG'
With this rule set above GitLab will create pipelines for branches and Merge-Requests (the detached ones), as well as pipelines for git-tags, but it will prevent GitLab from duplicating pipelines.
The last rule evaluates to true either when there is a commit to a branch or there is a git-tag.
Further links
Official docs on switching between MR- and Branch-Pipelines
Docs on how to avoid duplicate pipelines with rules examples
I need to run a certain job on master branch after each merge to it. Pipelines that were scheduled or run manually should not contain this job. Is there a way to do that in GitLab CI?
As a side note, I want to say that I don't want to use "merge_request_event" because it triggers an additional pipeline after every commit to a merge request and it's something that doesn't suit me.
But it will also run while triggering a pipeline on master manually and I don't need that
You can add this in you .gitlab-ci.yml file.
job_name:
script:
- your_job_part_1
- your_job_part_2
only:
- master
It will run you job_name each time master is updated, hence, each time a merge request is accepted and branch is merged into master.
You can take a look at GitLab CI/CD for more options.
You can use rules keyword:
job_name:
rules:
- if: $CI_COMMIT_BRANCH == 'master' && $CI_PIPELINE_SOURCE == 'merge_request_event'
You can also replace master string by $CI_DEFAULT_BRANCH variable if you master/main branch is the default.
See: https://docs.gitlab.com/ee/ci/yaml/index.html#rules