How to run a gitlab-ci.yml job only on a tagged branch?

GitlabGitlab CiGitlab Ci-Runner

Gitlab Problem Overview


How do I run a .gitlab-ci.yml job only on a tagged Master branch?

job:
  script:
  - echo "Do something"
  only:
  - master
  - tags

The above code will run if either condition exists: a Master branch or a tagged commit.

My goal is to have this run for a production deploy, but it would require that it be on the Master branch and that it be tagged (with a version). Otherwise, I'll have another job that will push to staging if its missing a tag.

Gitlab Solutions


Solution 1 - Gitlab

This behavior will be introduced in version 12.

Open issue was recently update:

> Jason Lenny @jlenny changed title from {-Update .gitlab-ci.yml to > support conjunction logic for build conditions-} to Conjunction logic > for build conditions MVC · 2 days ago > > Jason Lenny @jlenny changed milestone to 12.0 · 2 days ago

(fingers crossed)

A solution is to use the except keyword to exclude all the branches, in conjunction with only to run on tags, in this way you run your pipeline only on tag in master branch:

  only:
    - tags
  except:
    - branches

I'm using version 11.3.4

Solution 2 - Gitlab

Thanks to others like Matt Alioto who posted about the open issue (which is labeled Product Vision 2019 so hopefully they knock it out this year).

Specific to Carlson Cole's question, this would work:

job_for_master_no_tags:
  stage: deploy
  script:
  - echo "Release to Staging"
  only:
  - master

job_for_master_tags_only:
  stage: deploy
  script:
  - echo "Release to Production"
  only:
  - tags
  except:
  - /^(?!master).+@/    # Ruby RegEx for anything not starting with 'master'
  • To see how this RegEx works check out https://rubular.com/r/1en2eblDzRP5Ha
  • I tested this on GitLab version 11.7.0 and it works
    • Note: If you try to use - /^(?!master).+/ (without the @) it doesn't work - learned that the hard way 

Solution 3 - Gitlab

I made it work and this is my working code snippet, all others were not working for me

only:
 - tags  # please mention the 's' compared to Sergio Tomasello's solution
except:
 - branches

I use 11.4.3

Solution 4 - Gitlab

This behavior is not yet supported by gitlab-ci, although there is an open issue to add it.

In the meantime I've also heard anecdotal reports that

only:
  - master
only:
  - tags

will get the job done (as well as anecdotal reports that it won't).

Solution 5 - Gitlab

I had the same problem. I wanted to trigger a deploy to our staging-environment on a push or merge, and only when applying a tag deploy it our production-environment.

We need 2 variables for this: $CI_COMMIT_BRANCH and $CI_COMMIT_TAG. With these variables we could deduct if the pipeline was triggered by a commit or a tag. Unfortunately the first variable is only set when committing on a branch, while the second variable only is set on applying a Tag. So this was no solution...

So I went for the next-best setup by only do a production-release when a tag is set by specified conventions and by a manual trigger. This is my .gitlab-ci.yml file:

stages:
  - deploy:staging
  - deploy:prod

deploy-to-staging:
  stage: deploy:staging
  rules:
    - if: $CI_COMMIT_BRANCH == 'master'
  script:
    - echo "Deploying to Staging..."

deploy-to-production:
  stage: deploy:prod
  rules:
    - if: $CI_COMMIT_TAG =~ /^v(?:\d+.){2}(?:\d+)$/
      when: manual
  script:
    - echo "Deploying to Production..."

If you really want to automate this, you have to do a little scripting to find out if the applied tag actually belongs to a commit that is on the master-branch. Check this comment on the GitLab issuetracker for more information: https://gitlab.com/gitlab-org/gitlab-foss/-/issues/31305#note_28580169

Solution 6 - Gitlab

There is no proper build in solution in gitlab so far for this problem. To keep track of the development of a proper solution and to keep a working workaround updated I created: https://stackoverflow.com/questions/62756669/

Solution 7 - Gitlab

My solutions was

job:
  script:
  - echo "Do something"
  only: 
    refs:
      - master
      - tags
    variables:
      - $CI_COMMIT_BRANCH == "master"

Solution 8 - Gitlab

I have faced the same issue, this is how I tried to solve it

my_job:
  stage: build
  services:
    - name: docker:dind
  image: docker:latest
  script:
    - ...
  rules:
    - if: $CI_COMMIT_BRANCH == 'master' && $CI_COMMIT_TAG == null
  cache: {}

this job runs only when there is a commit on the master branch (excluding any other commit on personal/feature branch). In the very same way I trigger builds on tags:

  script:
    - ...
    
  rules:
    - if: $CI_COMMIT_BRANCH == 'master' && $CI_COMMIT_TAG != null

Solution 9 - Gitlab

Years later, still trying to launch a job on tags on master branch...

The issue at Gitlab has been closed : https://gitlab.com/gitlab-org/gitlab-foss/-/issues/27818

It's not possible to spot a tag on master branch as Git does not work this way. Branches and tags are separate references, each pointing to a commit. So, a tag has no relation with a branch.

My solution is to check the tag name to detect that it represents a PRODUCTION release :

deploy-prod:
  stage: deploy-manual
  only:
    variables:
      - $CI_COMMIT_TAG =~ /^v\d+.\d+.\d+-?.*$/
  when: manual

The regexp matches semver tag names like :

  • v1.2.0
  • v2.0.0-beta.1
  • ...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCarson ColeView Question on Stackoverflow
Solution 1 - GitlabSergio TomaselloView Answer on Stackoverflow
Solution 2 - GitlabEric D. JohnsonView Answer on Stackoverflow
Solution 3 - Gitlabhannes achView Answer on Stackoverflow
Solution 4 - GitlabMatt AliotoView Answer on Stackoverflow
Solution 5 - GitlabMilkmannetjeView Answer on Stackoverflow
Solution 6 - GitlabKoundView Answer on Stackoverflow
Solution 7 - GitlabJulio RamosView Answer on Stackoverflow
Solution 8 - GitlabMauro DorniView Answer on Stackoverflow
Solution 9 - GitlabFranckView Answer on Stackoverflow