I have this template:
def call(body) {
def pipelineParams= [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = pipelineParams
body()
pipeline {
agent any
....
stages {
stage('My stages') {
steps {
script {
pipelineParams.stagesParams.each { k, v ->
stage("$k") {
$v
}
}
}
}
}
}
post { ... }
}
}
Then I use the template in a pipeline:
@Library('pipeline-library') _
pipelineTemplateBasic {
stagesParams = [
'First stage': sh "do something...",
'Second stage': myCustomCommand("foo","bar")
]
}
In the stagesParams
I pass the instances of my command (sh
and myCustomCommand
) and they land
in the template as $v
. How can I then execute them? Some sort of InvokeMethod($v)
?
At the moment I am getting this error:
org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Required context class hudson.FilePath is missing
Perhaps you forgot to surround the code with a step that provides this, such as: node
The problem of using node
is that it doesn't work in situations like parallel
:
parallelStages = [:]
v.each { k2, v2 ->
parallelStages["$k2"] = {
// node {
stage("$k2") {
notifySlackStartStage()
$v2
checkLog()
}
// }
}
}
If you want to execute sh
step provided with a map, you need to store map values as closures, e.g.
@Library('pipeline-library') _
pipelineTemplateBasic {
stagesParams = [
'First stage': {
sh "do something..."
}
'Second stage': {
myCustomCommand("foo","bar")
}
]
}
Then in the script
part of your pipeline stage you will need to execute the closure, but also set the delegate and delegation strategy to the workflow script, e.g.
script {
pipelineParams.stagesParams.each { k, v ->
stage("$k") {
v.resolveStrategy = Closure.DELEGATE_FIRST
v.delegate = this
v.call()
}
}
}