63

How to use if else condition inside the gitlab-CI.

I have below code:

deploy-dev:
  image: testimage
  environment: dev
  tags:
    - kubectl
  script:
   - kubectl apply -f demo1 --record=true
   - kubectl apply -f demo2 --record=true

Now I want to add a condition something like this

script:
    - (if [ "$flag" == "true" ]; then kubectl apply -f demo1 --record=true; else kubectl apply -f demo2 --record=true);

Could someone provide the correct syntax for the same? Is there any documentation for the conditions (if-else, for loop) in gitlabci?

Vikas Rathore
  • 4,486
  • 5
  • 17
  • 31

5 Answers5

130

Hereunder three syntax options for that kind of statement. From gitlab-ci documentation :

Using shell variable

deploy-dev:
image: testimage
environment: dev
tags:
 - kubectl
script:
 - if [ "$flag" == "true" ]; then MODULE="demo1"; else MODULE="demo2"; fi
 - kubectl apply -f ${MODULE} --record=true

Using shell variable with yaml multiline block

deploy-dev:
image: testimage
environment: dev
tags:
  - kubectl
script:
  - >
    if [ "$flag" == "true" ]; then
      kubectl apply -f demo1 --record=true
    else
      kubectl apply -f demo2 --record=true
    fi

Using gitlab rules

workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
      when: never
    - if: '$CI_PIPELINE_SOURCE == "push"'
      when: never
    - when: always

Using gitlab templates and variables

demo1-deploy-dev:
extends: .deploy-dev
only:
  variables: [ $flag == "true" ]
variables:
MODULE: demo1
        
demo2-deploy-dev:
extends: .deploy-dev
only:
  variables: [ $flag == "false" ]
variables:
  MODULE: demo2
        
.deploy-dev:
image: testimage
environment: dev
tags:
  - kubectl
script:
  - kubectl apply -f ${MODULE} --record=true
Xavier D
  • 1,578
  • 1
  • 6
  • 15
  • In the last example how you check the value of $flag? – Roger Coll Sep 18 '19 at 10:25
  • @RogerCollAumatell : i.e. Using `only: variables: [ $flag == "true" ]` – Xavier D Sep 26 '19 at 07:24
  • @XavierD: I'm not able to grok the last example. It looks like a variable is being set for MODULE, which is used in .deploy-dev, which is based on $flag, but what causes .deploy-dev to be run at all? (I thought the '.' prefix meant that the section was skipped (hidden)? – Cognitiaclaeves Nov 01 '19 at 17:11
  • 1
    Thanks @Cognitiaclaeves. Indeed `extends` keyword was missing from jobs definitions. You're right, the '.' prefixed job is not executed and acts as a template or let's say an abstract job here. I've fixed my example. Hope it's more clear now. – Xavier D Nov 02 '19 at 00:11
  • 1
    there is also `- |` which is similar to `- >` only that it will keep the content multiline instead of concatenating it into a single line interspersed with `;` – fabb Feb 02 '21 at 10:22
8

Note that with GitLab 13.3 (August 2020), there is an improvement to the if-else rule syntax:

CI/CD rules:if support logical expressions with parentheses

If you use the rules keyword with if clauses, it’s now even more powerful, with support for bracketed expressions evaluated by the pipeline processor.

You can use more complex and efficient AND (&&) / OR (||) expressions, making your pipelines rules more logical, powerful, and easier to manage.

See Documentation and Issue.


And, with GitLab 13.8 (January 2021)

Support variables for pipeline rules

Previously, the rules keyword was limited in scope and only determined if a job should be included or excluded from pipelines. In this release, you can now decide if certain conditions are met and subsequently override variables in jobs, providing you with more flexibility when configuring your pipelines.

https://about.gitlab.com/images/13_8/var.png -- Support variables for pipeline rules

See Documentation and Issue.


With GitLab 13.12 (May 2021):

Support variables in CI/CD pipeline 'workflow:rules'

Previously, the rules keyword was limited in scope and only determined if a job should be included or excluded from pipelines. In 13.8, we added the ability to use the variables keyword with rules to set variable values in a job based on which rule matched.

In this release we’ve extended this ability to workflow: rules, so you can set variable values for the whole pipeline if certain conditions match.
This helps you make your pipelines even more flexible.

https://about.gitlab.com/images/13_12/variable.png -- Support variables in CI/CD pipeline 'workflow:rules'

See Documentation and Issue.

VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283
3

I think you need to just add a semicolon and closing "fi" at the end. I couldn't find a link to documentation.

script:
    - (if [ "$flag" == "true" ]; then kubectl apply -f demo1 --record=true; else kubectl apply -f demo2 --record=true; fi);
3

You may consider checking rules

It allows for a list of individual rule objects to be evaluated in order, until one matches and dynamically provides attributes to the job.

Available rule clauses include:

  • if (similar to only:variables)
  • changes (same as only:changes)
  • exists

Example:

job:
  script: "echo Hello, Rules!"
  rules:
    - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
      when: always
    - if: '$VAR =~ /pattern/'
      when: manual
    - when: on_success
Arihant Godha
  • 1,982
  • 2
  • 22
  • 49
  • Using =~ pattern matching is really useful. Just be aware of the limitations of this regex pattern matching if you decide to use the pattern in a variable: https://gitlab.com/gitlab-org/gitlab/-/issues/35438 – Christian Groleau Jan 14 '21 at 19:21
1

In addition, in the case of a multiline block if you want or need to preserve line breaks you can use the pipe character:

script: |
    if [ "$flag" == "true" ]; then
      kubectl apply -f demo1 --record=true
    else
      kubectl apply -f demo2 --record=true
    fi

To go deeper, visit https://yaml-multiline.info/

Pixadelic
  • 71
  • 4