Issue
-
I am using Pipeline Multibranch and/or GitHub Organization and/or Bitbucket Team Project - i.e. any project item that leverage Multibranch Pipelines.
-
I want to define additional behaviors to my SCM for specific branches - like I would do with the
checkout
step in a simple Pipeline job. -
I want a pipeline-as-code solution to customize SCM checkout for Multibranch Pipeline Projects.
Resolution
IMPORTANT: The following approach is a workaround and should not be used once JENKINS-37658 has been fixed
For Multibranch Pipelines, the source code can be checked out with a simple checkout scm
in the Jenkinsfile
. In some cases, a different behavior needs to be defined for specific branches. For that, there is a pipeline-as-code solution.
The checkout
step accepts the scm
variable. This variable references an Object which means that attributes of this object can be accessed via scm.$attributeName
. Therefore the checkout scm
can be customized.
In brief, for the following Multibranch configuration:
the following Jenkinsfile
:
node { checkout scm }
is equivalent to something like this:
node { checkout([ $class: 'GitSCM', branches: scm.branches, doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations, extensions: scm.extensions, userRemoteConfigs: scm.userRemoteConfigs ]) }
With one difference though: in the latter the access to scm.
attributes need to be allowlisted by an administrator in Jenkins*
Some Explanation
In the context of Pipeline Multibranch, for each branch the SCM configuration is "injected" in the variable scm
.
This variable is an object implementation of an SCM. For example with Git, the scm
references a GitSCM Object. You can see that in the source code and/or when using the Snippet Generator. By default, the snippet generator for will generate something like the following:
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[]] ])
This object contains attributes, for example branches
, extensions
, userRemoteConfigs
. Inside the Jenkinsfile
, these attributes can be accessed via scm.branches
, scm.extensions
, scm.userRemoteConfigs
. Some attributes are mandatory, some are optional or have a default value and therefore don’t need to be specified.
While the Snippet Generator gives a pretty good idea of the attributes accessible, it is sometimes required to have a look at the source code to understand how to map them to the constructor. |
Implications
When the Pipeline is read from SCM - like for Multibranch Pipelines - it is sandboxed (see Script Security Plugin). This means that any access to scm
attributes need to be approved by an Administrator in Jenkins. This can be controlled under .
Example
So we have seen that it is possible to customize our checkout scm
step. Here is a simple scenario: for all my branches, I want to checkout the code and carry on with my workflow whereas for the release/*
branches I want to Clean before Checkout - which is a Git additional Behavior:
For all branches, my Jenkinsfile
looks like this:
node { checkout scm //Build, Test, Stage, Deploy [...] }
In my feature/*
branches, I want to Clean After Checkout so I am gonna change the Jenkinsfile
. I use the Snippet Generator for and add the the Additional Behavior Clean After Checkout.
Let’s see which attribute I need to add:
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CleanCheckout']], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'git-credentials', url: 'https://github.com/user/repo.git']] ])
I need to add the [[$class: 'CleanCheckout']]
to extensions. Attributes other than branches
and userRemoteConfigs
don’t need to be specified in my case. So I modify the Jenkinsfile
and append this attribute to the scm.extensions
that are passed to the flow:
node { checkout([ $class: 'GitSCM', branches: scm.branches, extensions: scm.extensions + [[$class: 'CleanCheckout']], userRemoteConfigs: scm.userRemoteConfigs ]) //Build, Test, Stage, Deploy [...] }
The Jenkins Administrator needs to approve the following methods:
method hudson.plugins.git.GitSCM getBranches method hudson.plugins.git.GitSCM getUserRemoteConfigs method hudson.plugins.git.GitSCMBackwardCompatibility getExtensions staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods plus java.util.Collection java.lang.Object
Further Information
Since the release of the version 2.5.2 of the Git Plugin, it is now possible to specify Advanced Behaviors in the Git SCM configuration of Multibranch Project: