Is it possible for Jenkins to automatically detect and build newly created tags in a git repo?

With the following configuration, you can make a job build all tags:

  1. Make the job fetch tags as if they were branches: Click on the Advanced button below the repository URL and enter the Refspec +refs/tags/*:refs/remotes/origin/tags/*
  2. Have it build all tag "branches" with the Branch Specifier */tags/*
  3. Enable SCM polling, so that the job detects new tags.

This approach has one drawback: The job will build all tags and not just newly added tags. So after you have created the job, it will be triggered once for every existing tag. So you probably want to have the job do nothing at first, then wait until all existing tags have been processed, and only then configure the build steps you want to be done for every new tag.

Since tags don't change in git, the job will then only be triggered once for every new tag.


To overcome the drawback of @oberlies' answer that all tags will be built I'm using a special trigger build instead. The trigger build uses the same git repository and branch as the main build and the following (post) build steps.

Build -> Execute shell:

# Get the most recent release tag.
PATTERN="release-tag-[0-9][0-9]-[0-9][0-9][0-9][0-9]"
TAG=$(git log --tags=$PATTERN --no-walk --pretty="format:%d" | grep -m 1 -o $PATTERN)

# Due to a Jenkins limitation (https://issues.jenkins-ci.org/browse/JENKINS-8952)
# when passing environment variables we have to write the tag to a file and
# inject it later again.
mv release.properties release-old.properties || true
echo "TAG = $TAG" > release.properties

# Fail the build if the most recent release tag did not change.
! diff release.properties release-old.properties

Build -> Inject environment variables:

Properties File Path: release.properties

Post-build Actions -> : Trigger parameterized build on other projects

Projects to build: <your main project>
Trigger when build is: Stable
Parameters: TAG=$TAG

Finally, in your main build, tick "This build is parameterized" with the following string parameter

Name: TAG
Default Value: <your release branch>

And in the "Source Code management" section use "$TAG" in the "Branches to build" field.


You can install a post-receive hook, which checks if a tag was commited, and creates a build in jenkins.

The hook can look something like this [*]:

#!/usr/bin/env python

import sys
from subprocess import Popen, PIPE, check_call

def call_git(command, args):
    return Popen(['git', command] + args, stdout=PIPE).communicate()[0]
JENKINS = 'http://localhost:8002/jenkins'
TOKEN = 'asdf8saffwedssdf'
jobname = 'project-tag'

def handle_ref(old, new, ref):
     print 'handle_ref(%s, %s, %s)' % (old, new, ref)
     if not ref.startswith('refs/tags/'):
          return
     url = '%s/job/%s/buildWithParameters?token=%s&branch=%s' % (
        JENKINS, jobname, TOKEN, new)
     print "queueing jenkins job " + jobname + " for " + new
     check_call(["wget", "-O/dev/null", "--quiet", url])
if __name__ == '__main__':
    for line in sys.stdin:
        handle_ref(*line.split())

[*] note: this is just a quick conversion from a slightly different script, so it's quite probable that there are some small bugs here. This is mostly to show the idea.

On the jenkins side, you need to configure a parametrized job. The only parameter is 'branch'.

  1. Check 'this build is parametrized' and add the parameter
  2. In 'source code management -> branches to build' put '$branch'

This gives a fairly secure and robust way to build. To test, run a build through the web interface, it'll ask for the value of the parameter.

Tags:

Git

Jenkins