This post covers a specific workflow used by my team; in particular, we don’t do pull requests, and we use tags to denote releases, which are automatically deployed. We tag our releases manually, so we aren’t configuring Jenkins to tag every build, but rather to watch for new tags to be pushed, and execute builds for them.
Our requirements are something like this:
- Generate a build for every branch, and execute it on creation
- Execute a build every time changes are pushed to its branch
- Generate a build whenever a tag is pushed, and execute it
If your workflow is different, you can configure things differently (i.e., to build pull requests), without affecting the way tags are built.
The steps outlined here will work for a GitHub organization; there are equivalents for BitBucket, but I haven’t used them yet.
Plugins and Configuration
We need a couple of plugins in order to discover and build git tags:
Note that the GitHub Branch Source Plugin must be at least version 2.3.0 for tag discovery to work.
Once the plugins are installed, navigate to your top-level GitHub Organization job, go to
Configure, and you can add
Tag Discovery from the dropdown under
Similarly, you can add build strategies for both branches and tags:
The next time you scan your GitHub Organization, you should see jobs generated for each existing tag:
When you push a new tag, its job will be generated and executed automatically.
Controlling which Tags are Built
If you’re using tags for deployment, you need to put some thought into setting up your build strategy; for example, if you add a Jenkinsfile to a repository that already has a number of tags, they will all get discovered, and jobs will be generated for them. If you aren’t careful with your build strategy, all of those jobs will be run as well!
We’ve set our system up to only build tags that are less than a day old–so far this has worked well.
Executing Stages Provisionally
We typically want to run our build and test scripts on every branch, but only deploy artifacts from tags. You can do this by wrapping the stage in a conditional (for scripted pipelines), or using a
when block (for declarative pipelines):
We have seen issues getting the
TAG_NAME environment variable to work, similar to this issue. As a workaround, we capture the tag using a shell command.