How to make my pipeline respect the workflow rules? They simply seem to be ignored

Introduction

In my corporate-managed gitlab instance (community edition) version 12.5.8, I want to perform automatic tagging in the CI pipeline. To test the approach I am thinking of, I set up a minimal pipeline configuration.
The pipeline shall do nothing but add a tag to the commit.
With the workflow rules, I want to prevent the pipeline to run again for that newly created tag.

What I expect to happen

The pipeline is run once after a push and no subsequent pipeline is created for the newly added tag because of the workflow rules I added.

What am I experiencing

The pipeline tags the commit successfully. Immediately after finishing, a new pipeline appears for that tag, although this should not happen at all considering the workflow rules.

My pipeline config

workflow:
  rules:
    - if: '$CI_COMMIT_TAG'
      when: never
    - when: always  

stages:
  - tag

tag_automatically:
  stage: tag
  tags:
    - shell
  variables:
    GIT_AUTHOR_NAME: "Gitlab-ci"
    GIT_AUTHOR_EMAIL: "gitlab-noreply@<company>.com"
    GITLAB_TOKEN: <mytoken>
    TAG: v1.0.0.${CI_PIPELINE_IID}-ci
  script:
  - set -x
  - echo $CI_COMMIT_TAG
  - git config --global user.email ${GIT_AUTHOR_EMAIL}
  - git config --global user.name ${GIT_AUTHOR_NAME}
  - git remote set-url origin "https://gitlab-ci-token:$GITLAB_TOKEN@$CI_SERVER_HOST/$CI_PROJECT_PATH.git"
  - git tag ${TAG} ${CI_COMMIT_SHA}
  - git push --push-option=ci.skip origin ${TAG}
  when: manual

Output of the pipeline on push

Running with gitlab-runner 13.3.1 (738bbe5a)
  on project-group-shell 7a178224
Preparing the "shell" executor
Using Shell executor...
Preparing environment
Running on <domain>
Getting source from Git repository
Fetching changes with git depth set to 50...
Bestehendes Git-Repository in /home/gitlab-runner/builds/7a178224/0/<group>/ci-tagging-test/.git/ neuinitialisiert
Checking out 07f2468a as master...
Skipping Git submodules setup
Executing "step_script" stage of the job script
$ set -x
++ echo '$ echo $CI_COMMIT_TAG'
$ echo $CI_COMMIT_TAG
++ echo

++ echo '$ git config --global user.email ${GIT_AUTHOR_EMAIL}'
$ git config --global user.email ${GIT_AUTHOR_EMAIL}
++ git config --global user.email gitlab-noreply@<company>.com
++ echo '$ git config --global user.name ${GIT_AUTHOR_NAME}'
$ git config --global user.name ${GIT_AUTHOR_NAME}
++ git config --global user.name Gitlab-ci
++ echo '$ git remote set-url origin "https://gitlab-ci-token:$GITLAB_TOKEN@$CI_SERVER_HOST/$CI_PROJECT_PATH.git"'
$ git remote set-url origin "https://gitlab-ci-token:$GITLAB_TOKEN@$CI_SERVER_HOST/$CI_PROJECT_PATH.git"
++ git remote set-url origin https://gitlab-ci-token:<my token>@<server>/<group>/ci-tagging-test.git
++ echo '$ git tag ${TAG} ${CI_COMMIT_SHA}'
$ git tag ${TAG} ${CI_COMMIT_SHA}
++ git tag v1.0.0.356-ci 07f2468a1e5162e5123837d2c84a37e444b0aa3a
++ echo '$ git push --push-option=ci.skip origin ${TAG}'
$ git push --push-option=ci.skip origin ${TAG}
++ git push --push-option=ci.skip origin v1.0.0.356-ci
To <server>/<group>/ci-tagging-test.git
 * [new tag]         v1.0.0.356-ci -> v1.0.0.356-ci
Job succeeded

The output when executing the newly generated pipeline for the tag (to see whether CI_COMMIT_TAG has been really set

unning with gitlab-runner 13.3.1 (738bbe5a)
  on hmi-group-shell 7a178224
Preparing the "shell" executor
Using Shell executor...
Preparing environment
Running on <domain>...
Getting source from Git repository
Fetching changes with git depth set to 50...
Bestehendes Git-Repository in /home/gitlab-runner/builds/7a178224/0/<group>/ci-tagging-test/.git/ neuinitialisiert
Checking out 07f2468a as v1.0.0.356-ci...
Skipping Git submodules setup
Executing "step_script" stage of the job script
$ set -x
++ echo '$ echo $CI_COMMIT_TAG'
$ echo $CI_COMMIT_TAG
++ echo v1.0.0.356-ci
v1.0.0.356-ci
++ echo '$ git config --global user.email ${GIT_AUTHOR_EMAIL}'
$ git config --global user.email ${GIT_AUTHOR_EMAIL}
++ git config --global user.email gitlab-noreply@<domain>.com
++ echo '$ git config --global user.name ${GIT_AUTHOR_NAME}'
$ git config --global user.name ${GIT_AUTHOR_NAME}
++ git config --global user.name Gitlab-ci
++ echo '$ git remote set-url origin "https://gitlab-ci-token:$GITLAB_TOKEN@$CI_SERVER_HOST/$CI_PROJECT_PATH.git"'
$ git remote set-url origin "https://gitlab-ci-token:$GITLAB_TOKEN@$CI_SERVER_HOST/$CI_PROJECT_PATH.git"
++ git remote set-url origin https://gitlab-ci-token:<mytoken>@<server>/<group>/ci-tagging-test.git
++ echo '$ git tag ${TAG} ${CI_COMMIT_SHA}'
$ git tag ${TAG} ${CI_COMMIT_SHA}
++ git tag v1.0.0.357-ci 07f2468a1e5162e5123837d2c84a37e444b0aa3a
++ echo '$ git push --push-option=ci.skip origin ${TAG}'
$ git push --push-option=ci.skip origin ${TAG}
++ git push --push-option=ci.skip origin v1.0.0.357-ci
To <server>/<group>/ci-tagging-test.git
 * [new tag]         v1.0.0.357-ci -> v1.0.0.357-ci
Job succeeded

My runner version

Version:      13.3.1
Git revision: 738bbe5a
Git branch:   13-3-stable
GO version:   go1.13.8
Built:        2020-08-25T12:29:06+0000
OS/Arch:      linux/amd64

What I already tried

  • Reducing the pipeline to the here shown minimal content.
  • Trying without -o ci.skip option -> no difference

What now

Does anyone can give me a hint what I am doing wrong in this minimal example?
Basically when I have the rule for CI_COMMIT_TAG set to when: never and also pass the push option ci.skip I cannot imagine, why the subsequent pipeline is created anyway.

All help is highly appreciated

Thanks in advance

Have you solved this issue?

After having a quick glance, could you try changing your rules from:

to

I could not yet test your suggestion. The day I opened this thread, I put my minimal example also to a private repo on gitlab.com, where the rules work as expected. My guess is, that the rule I am trying to use is basically correct, but the older gitlab version my company is using, does not understand it correctly.

My current workaround is to add except: refs: - tags to each individual job in the pipeline, which workd for now. As soon as I get to it, I will test your solution as well to see whether it works better.

I am observing the same behaviour in my pipeline configuration (GitLab Community Edition 13.12.0). According technical documentation GitLab 13.12 - workflow the following code snippet should work (without single quotes).

workflow:
  rules:
    - if: $CI_COMMIT_TAG
      when: never
    - when: always  

Unfortunately, the pipeline is still created when adding new tag.

@dinko4 your proposal doesn’t work either.

@rprodan @darkmattercoder Was there any resolution here?

I have (what I thought) was a fairly straightforward rule: the only time a pipeline should be created is when there is a merge to the main branch, no pushes, nothing else (the idea is that a feature branch is merged into main via gitlab, pipeline is triggered, end)

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != 'main'
      when: never
    - when: always

I read that as ‘if it’s a push: never run; if it’s a merge request, and the target branch is not main: never run; otherwise run’ - but as soon as I push to a feature branch, 2 pipelines are started and immediately fail.

I tried flipping the logic as well:

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == 'main'
      when: always
    - when: never

And it still kicks off 2 pipelines that immedately fail. Does :rules work at all?’

Interestingly, the CI.yaml linter shows valid syntax when not running with a simulated pipeline, but incorrect syntax when running with the simulated pipeline [ ? ]