For reasons, you might want your Jenkins Multibranch Pipeline jobs to do a different thing depending on which branch is being built.
Fortunately, the multibranch plugin provides us with a built-in variable
BRANCH_NAME, which we can use to figure out which branch we are currently building.
In such scenarios, it’s not a bad idea to create a minimal
Jenkinsfile at the repo root that contains just enough logic to figure out which branch we are on, and then call another groovy script that contains the actual build definition:
In this script we load an external groovy file based on the current branch, and then call the function defined therein. In this particular case, the
run_build() functions don’t do anything particularly exciting, but they probably do enough to demonstrate this mechanism.
The most important line in each of these scripts is the
return this at the end; as documented, this is required for the functions to be callable from the outer script. The
checkout scm step in the root
Jenkinsfile is also required, as without it the rest of the scripts won’t be fetched from the repo. All three of these files are in the root of the repo, this is because gist doesn’t support folders. In “real life”, it’s probably a good idea to create a separate folder for these scripts, and provide the path to the
If you don’t have a Jenkins server handy, you can create a new one with
docker run -p 8080:8080 jenkinsci/jenkins:lts1 and connect to it on http://localhost:8080. After that, it’s just a question of creating a new job of type “Mutibranch Pipeline” and specifying an appropriate name.
In the “Branch Sources” section, add a source of type “Git” (not “Github”!), and provide it with the path to the source repo, in this case the gist.
It might be a lesser known fact about Github that gists are really just repos with a few extra rules that can be forked and cloned like any other Github repo. What it doesn’t say in that linked page is that you can also create branches, even if these new branches aren’t visible in the Gist UI. So, if you create a fork of https://gist.github.com/gavincampbell/480843552e43efa84c60f9bb4840d6c1, you should end up with an identical gist in your own Github account. You can then paste the url of this gist into the Jenkins job definition as shown:
The other thing to note here is the checkbox for “Scan Multibranch Pipeline Triggers”; since we aren’t configuring any push notifications from our git repo, we need to get Jenkins to scan the repo periodically to look for any new branches, or new commits in existing branches. (In my particular case, since the Jenkins instance is just an ephemeral Docker image, there’s no route to it anyway.)
When you save the job configuration, Jenkins will scan the source repo, and create the first pipeline job:
As noted above, there’s nothing in the gist UI to support creating new branches. However, if we clone the gist repo to a local folder we can create the branch and push it back to the origin. You can substitute the url to your own fork of the gist in place of mine (there’s only one branch in mine, and you don’t have permission to create more!). The downside of this approach of using a gist rather than a “proper” repo is that by default you get a long guid instead of a readable folder name.
$ mkdir j && cd j; $ git clone https://gist.github.com/gavincampbell/480843552e43efa84c60f9bb4840d6c1 Cloning into '480843552e43efa84c60f9bb4840d6c1'... remote: Counting objects: 32, done. remote: Compressing objects: 100% (32/32), done. remote: Total 32 (delta 7), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (32/32), done. Checking connectivity... done. $ cd 480843552e43efa84c60f9bb4840d6c1/ $ git status On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working tree clean $ git checkout -b fancyFeature Switched to a new branch 'fancyFeature' $ git push --set-upstream origin fancyFeature Total 0 (delta 0), reused 0 (delta 0) To https://gist.github.com/gavincampbell/480843552e43efa84c60f9bb4840d6c1 * [new branch] fancyFeature -> fancyFeature Branch fancyFeature set up to track remote branch fancyFeature from origin.
The next time the repo is scanned, the new job will be created in Jenkins:
When the branch is deleted, the job wil disappear too:
$ git push origin --delete fancyFeature To https://gist.github.com/gavincampbell/480843552e43efa84c60f9bb4840d6c1 - [deleted] fancyFeature
Looking in the “Multibranch Pipeline Log” confirms this:
[Thu May 25 22:40:36 UTC 2017] Finished branch indexing. Indexing took 1.7 sec Evaluating orphaned items in jenkins-branch-conditions Will remove fancyFeature as it is #1 in the list Finished: SUCCESS
Depending on your system configuration, this step may have one or more prerequisites! ↩︎