Ali
Ali

Reputation: 1869

Gitlab CI conditional statement does not work as expected: Both AND and OR conditions

I would like to have the following condition for a job in Gitlab CI (Gitlab cloud).

First, I thought the following statement should work:

only:
      - master
      - production
only:
      - tags
only:
      - /^v[0-9](?:\.[0-9]){2,3}/

But it turns out no matter how you arrange only it always considers the different statements as OR. So I came with the following statement to see if I can address it properly:

only:
      - tags
      - /^v[0-9](?:\.[0-9]){2,3}/
except:
      - /^(?!master)/
      - /^(?!production)/

That didn't work either. Then I thought I should be able to use rules which is very recently added to Gitlab CI:

rules:  
      - if: '($CI_MERGE_REQUEST_TARGET_BRANCH == "master" || $CI_MERGE_REQUEST_TARGET_BRANCH == "production") && $CI_COMMIT_TAG =~ /^v[0-9](?:\.[0-9]){2,3}/'
        when: always

However, turns out the syntax is incorrect and using parentheses is not allowed. Then I came to the following statement:

rules: 
      - if: '$CI_MERGE_REQUEST_TARGET_BRANCH == "master" && $CI_COMMIT_TAG =~ /^v[0-9](?:\.[0-9]){2,3}/'
        when: always
      - if: '$CI_MERGE_REQUEST_TARGET_BRANCH == "production" && $CI_COMMIT_TAG =~ /^v[0-9](?:\.[0-9]){2,3}/'
        when: always

But the above statement did not work either. I would appreciate if someone can help me to understand how the requested conditions can be met in Gitlab CI.

Upvotes: 1

Views: 2677

Answers (2)

makozaki
makozaki

Reputation: 4366

I performed some tests on gilab.com project with version GitLab Enterprise Edition 12.3.0-pre. Gitlab docs says:

With only, individual keys are logically joined by an AND:

(any of refs) AND (any of variables) AND (any of changes) AND (if kubernetes is active)

So I created pipeline as follows to test it:

build0-refs:
  script:
    - env | sort
  only:
    refs:
      - master
      - production
build1-variables:
  script:
    - env | sort
  only:
    variables:
      - $CI_COMMIT_TAG =~ /^v[0-9](?:\.[0-9]){1,2}$/
build2-refs-and-variables:
  script:
    - env | sort
  only:
    refs:
      - master
      - production
    variables:
      - $CI_COMMIT_TAG =~ /^v[0-9](?:\.[0-9]){1,2}$/

I tried different cases on different branches with and without tags and checked which builds are triggered.

For tagged commit 2 pipelines are triggered. One with CI_COMMIT_REF_NAME=master and missing CI_COMMIT_TAG, another with CI_COMMIT_REF_NAME and CI_COMMIT_TAG with the same tag value.

build2-refs-and-variables has never been triggered. Looks like condition for ref name and commit tag exclude each other. You should probably change your flow.

Upvotes: 2

CordlessWool
CordlessWool

Reputation: 1530

I see two problems:

  1. Your regex do not match to vx.x, I build a new one fitting this case I build a new one fitting this case

  2. In your if statement you try to match the tag with master or production, but I think tags are not fitting to a branch. So you have to validate tag or master or production

Upvotes: 0

Related Questions