Reputation: 3785
It would be nice for our Jenkins CI server to automatically detect, deploy and build tags as they are created in our Github repository.
Is this possible?
Upvotes: 46
Views: 30760
Reputation: 10559
In the world of modern (?) multi-branch pipelines, building tags works as follows.
Upvotes: 1
Reputation: 29821
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.
Upvotes: 18
Reputation: 11723
With the following configuration, you can make a job build all tags:
+refs/tags/*:refs/remotes/origin/tags/*
*/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.
Upvotes: 36
Reputation: 5305
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'.
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.
Upvotes: 3
Reputation: 1486
You can use the option "Git Publisher" which comes as part of the Git Plugin to create a tag after a successful build/deploy.
Upvotes: -3