22

How do I prevent a gitlab ci pipeline being triggered when I add a git tag? I'm running this command locally (as opposed to within a gitlab-ci job)

git tag -a "xyz"

and then pushing the tag; and this triggers various pipelines. I want to exclude some of those pipelines from running.

I'm trying variations on ideas from questions such as this; that question is using only, I'm wanting to exclude, so I'm trying except. The answers there have two variants, one with refs one without.

build:  
  # ... my work here ...  
  except:
    - tags


build:  
  # ... my work here ...  
  except:
    refs:
      - tags

Neither seem to have any effect; I add a tag, the build still happens.

My understanding may be completely awry here as there seem to be three possible meanings of the word tags and when reading docs or examples I'm not always sure which meaning is applicable:

  1. Git tags applied using git tag
  2. Gitlab CI tags used to determine which runners pick a job
  3. The ref identifier of a commit used to trigger a pipeline via the REST API. This is usually a branch name, but could be a git tag.

I'm interested in controlling what happens if the first case. It does seem clear from comments so far that "except: -tags" is not relevant to my case, so is there any approach that does work?

djna
  • 54,992
  • 14
  • 74
  • 117
  • Per https://docs.gitlab.com/ee/ci/yaml/#onlyexcept-basic this refers to git tags. You can also see info on the refs strategy on that page. Note that there will be two builds for a tagged commit; one for the commit, one for the tag. – jonrsharpe Feb 22 '20 at 11:20
  • Thanks @jonrsharpe. I agree that's what the docs say is the sense of "tag". Is there any way to prevent these builds cause by git tags? – djna Feb 22 '20 at 20:58
  • Are you using `git tag -a TAG` locally and then `git push origin TAG`? Or the `git tag` command is part of your `.gitlab-ci.yml` jobs ? – Nicolas Pepinster Feb 24 '20 at 09:42
  • @Nicolas Pepinster - running locally and pushing, added that clarification – djna Feb 24 '20 at 12:06

4 Answers4

36

It looks like GitLab recommends using rules instead of except as per the documentation

only and except are not being actively developed. rules is the preferred keyword to control when to add jobs to pipelines.

So it'd be

your_job:
  stage: your_stage
  script:
    - echo "Hello"
  rules:
    - if: $CI_COMMIT_TAG
      when: never 
    - when: always
diegosasw
  • 13,734
  • 16
  • 95
  • 159
  • 1
    @diegosaw, thanks. We are still on v12 where the docs say: "Note: The rules syntax is now the preferred method of setting job policies. only and except are candidates for deprecation, and may be removed in the future." I'm glad you drew this to my attention. – djna Jun 26 '21 at 05:47
  • Note that this may lead to pipelines being executed twice if you push to a branch for which a merge request exists. Details here: https://docs.gitlab.com/ee/ci/jobs/job_control.html#avoid-duplicate-pipelines – Wolfram Rösler May 30 '23 at 15:30
31

Except tags is exactly what you should use if you want to skip build for tags.

You need to be sure to understand commit vs branches vs tags

To illustrate what happens when you push tagged commit to gitlab I did as follows:

  1. Created .gitlab-ci.yml with following content:
tests_always_run:
    script:
      - echo I should always execute
tests_except_tags:
    script:
      - echo I skip tagged triggers
    except:
      - tags
  1. Commited changes, tagged commit and pushed with --follow-tags to make sure tag is also propagated to server:
git add .gitlab-ci.yml
git commit -m 'my great yml with except tags'
git tag -a "abc" -m "Test tag"
git push --follow-tags

Ilustrated results: Tagged commit pipeline results

If you want to skip CI for selected commit then you could use git push -o ci.skip, inspired by this article

makozaki
  • 3,772
  • 4
  • 23
  • 47
6

(note : this a formatted comment more than an answer)

In order to debug the conditions that trigger your pipeline :

gitlab's doc mentions several variables which are set when running a CI job, among which :

  • CI_COMMIT_REF_NAME : The branch or tag name for which project is built
  • CI_COMMIT_BRANCH : The commit branch name. Present only when building branches.
  • CI_COMMIT_TAG : The commit tag name. Present only when building tags.

Have your build job output some of these variables (e.g : echo "triggered by ref : " $CI_COMMIT_REF_NAME) to view what triggered your job.

LeGEC
  • 46,477
  • 5
  • 57
  • 104
1

I was in the same situation, my solution was this:

Before:: BEFORE

After: AFTER

Both stages are configured in my .gitlab-ci.yml file, with different name The "Dev-UnitTests" , it only executes when someone commits to the repository, no effect on tags y the branch "test"

Dev-UnitTests:
  stage: pruebas 
  script:
    - mvn $MAVEN_CLI_OPTS test
  artifacts:
    when: always
    reports:
      junit: 
        - target/surefire-reports/*Test.xml
        - target/failsafe-reports/*Test.xml
      cobertura: target/site/jacoco/jacoco.xml
  tags:
    - shell 
  except: 
    - test 
    - tags   

The Unit Tests , only run when a merge is done on the branch test

Unit Tests:
  stage: pruebas 
  script:
    - mvn $MAVEN_CLI_OPTS test
  artifacts:
    when: always
    reports:
      junit: 
        - target/surefire-reports/*Test.xml
        - target/failsafe-reports/*Test.xml
      cobertura: target/site/jacoco/jacoco.xml
  tags:
    - shell 
  only: 
    - test

That did not run again any pipeline when creating a tag, I hope it helps you.

The key is:

...
 except:  
    - tags   
...
Erik Roky
  • 111
  • 1
  • 5