Reputation: 2574
I have a Jenkinsfile which uses a shared library. I would like to make a global variable which is usable in all functions of the shared library, similar to the params
object. However I always end up with
groovy.lang.MissingPropertyException: No such property: pipelineParams for class: groovy.lang.Binding
Following this guideline, I define a Field
in the Jenkinsfile
:
import org.apache.commons.io.FileUtils
@groovy.transform.Field
def pipelineParams
library identifier: 'pipeline-helper@master', retriever: modernSCM(
[$class: 'GitSCMSource',
remote: 'https://bitbucket/scm/jenkins/pipeline-helper.git',
credentialsId: 'bitbucket.service.user'
])
defaultCiPipelineMSBuild {
nodes = 'TEST-NODES' /* label of jenkins nodes*/
email = '[email protected]' /* group mail for notifications */
msbuild = 'MSBUILD-DOTNET-4.6' /* ms build tool to use */
}
And then in the defaultCiPipelineMSBuild
I set the pipelineParams
def call(body) {
// evaluate the body block, and collect configuration into the object
pipelineParams= [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = pipelineParams
body()
pipeline {
...
Later on I call a function buildApplication
which want's to consume the variable:
def msBuildExe = tool pipelineParams.msbuild
Upvotes: 5
Views: 11536
Reputation: 2574
As suggested by @Dillip it is possible to use env
even so for non-strings. If the object stored as environment variable is a list or a map, it shall be deserialized
So I slightly changed the pipeline code to store the map as environment variable
def call(body) {
// evaluate the body block, and collect configuration into the object
pipelineParams= [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = pipelineParams
body()
env.pipelineParams = pipelineParams
pipeline {
...
The pipeline is serialized and thus when reading returns a String
{ nodes=TEST-NODES,[email protected],msbuild=MSBUILD-DOTNET-4.6 }
Thus for usage it has to be deserialized
def pipelineParams =
// Take the String value between the { and } brackets.
"${env.pipelineParams}"[1..-2]
.split(', ')
.collectEntries { entry ->
def pair = entry.split('=')
[(pair.first()): pair.last()]
}
//use map
pipelineParams.msbuild
You may add the deserialization into a function so you can use it in other places as well.
Upvotes: 0
Reputation: 289
Instead of creating a whole new pipeline parameter your self, did you try adding your variables into already available env
parameter which you can use across your shared libraries?
env.param_name = "As per your requirement"
Can also be accessible with env.param_name
or env[param_name]
across shared library
Upvotes: 6