This plugin provides wildcard and regex filters for Pipeline Multibranch Plugin pipelines. The filter provides two behaviors beyond the default SCM filter
- It will match branches and pull requests destined for the matched branches.
- It will match branches and pull requests originating from the matched branches.
In both of the above scenarios, you can also add additional filters for matching tags independently of branches.
After installing this plugin four new options will appear in Pipeline Multibranch Plugin jobs for configuring branch filters. In additional behaviors, click on Add and you'll see the following additional filters:
Choose only one filter. The filter will match branches and tags to be built. It will also match any pull request destination branch that matches a filtered branch to also be built as a pull request by the Pipeline Multibranch Plugin job.
This plugin supports filtering both for branches, pull requests destined for matched branches, and tags. This plugin is meant to satisfy a typical tag-based development workflow. In order to build tags, tag discovery must be configured in addition to specifying matching tags.
Here's a screenshot to filter tags with a regular expression (notice Discover tags trait).
Here's a screenshot to filter tags with wildcards (notice Discover tags trait).
Matching and building a PR, is what is called a Peer Review build in generic terms of SCM. Depending on the platform you're using it goes by different names. For example, GitHub (for Git) and Mercurial (another SCM) has Pull Requests. GitLab has Merge Requests. In essence, these are all the same thing. This plugin will match branches which are destined for the target branch (usually main branch in Git) and build them as part of an automated peer review.
In multibranch pipelines, it's not straight forward to tell the difference between tags, pull requests, and regular branch builds. Create a pipeline shared library and add the following pipeline variables to it.
vars/isTagBuild.groovy
vars/isPRBuild.groovy
The source of vars/isTagBuild.groovy
:
import hudson.model.Job
import jenkins.scm.api.mixin.TagSCMHead
import org.jenkinsci.plugins.workflow.multibranch.BranchJobProperty
@NonCPS
Boolean isTagBuild(Job build_parent) {
build_parent.getProperty(BranchJobProperty).branch.head in TagSCMHead
}
Boolean call() {
isTagBuild(currentBuild.rawBuild.parent)
}
The source of vars/isPRBuild.groovy
:
import hudson.model.Job
import jenkins.scm.api.mixin.ChangeRequestSCMHead
import org.jenkinsci.plugins.workflow.multibranch.BranchJobProperty
@NonCPS
Boolean isPRBuild(Job build_parent) {
build_parent.getProperty(BranchJobProperty).branch.head in ChangeRequestSCMHead
}
Boolean call() {
isPRBuild(currentBuild.rawBuild.parent)
}
Now scripted and declarative pipelines can be written which can detect what kind of build is occuring: branch build, tag build, PR build. Here's some example usage in scripted pipeline.
if(isPRBuild()) {
// do something because it is a PR build
}
if(isTagBuild()) {
// do something because it is a tag build
}
if(!isPRBuild() && !isTagBuild()) {
// do something only on branch builds and not on PR or tag build
}
CHANGE_ID
environment variable is populated for pull requests. It is not set when the triggered build is not a peer review.
One can modify their build scripts to behave differently if a peer review is being built vs a matched branch. Here's an example in bash:
if [ -n "${CHANGE_ID}" ] ; then
# do something because it's a pull request
else
# not a pull request
fi
Additionally, it may be desired that a Jenkinsfile
not run certain stages when evaluating branches vs peer reviews (such as deploys). This can be accomplished two ways.
if(env.CHANGE_ID) {
// do something because it's a pull request
} else {
// not a pull request
}
Declarative pipelines provide a "when" condition. Therefore, similar logic can be applied. For example, deploy only when not a peer review and it is the main branch.
pipeline {
stages {
stage('Example Deploy') {
when {
allOf {
environment name: 'CHANGE_ID', value: ''
branch 'main'
}
}
steps {
// not a pull request so do something
}
}
}
}