I have in my Jenkinsfile:
def foo = ["1", "2", "3"]
def parallelStagesFromMap = foo.collectEntries {
["Build ${it}" : generateStage(it)]
}
def generateStage(bar) {
return {
stage("Build ${bar}") {
echo "Building for ${bar}"
}
}
}
I can then use them with parallel parallel parallelStagesFromMap
but now I'm trying to call one in particular, for example:
generateStage("a")
and it is just skipped... Am I missing anything?
You can also mix and match node { stage {..}} and stage { node {..}} within your pipeline codes. By design (in Jenkins, as well as in the concept of continuous delivery), stages do not execute in parallel. Only the steps within a single stage are executed in parallel.
Jenkins Pipeline allows you to compose multiple steps in an easy way that can help you model any sort of automation process. Think of a "step" like a single command which performs a single action. When a step succeeds it moves onto the next step. When a step fails to execute correctly the Pipeline will fail.
As discussed in the Defining a Pipeline in SCM, a Jenkinsfile is a text file that contains the definition of a Jenkins Pipeline and is checked into source control. Consider the following Pipeline which implements a basic three-stage continuous delivery pipeline.
To create a function in the Jenkins pipeline with groovy, refer to the below code snippet. Initially, we have defined a function named Greet and which takes a parameter as the name. In the next step, we create a Jenkins scripted pipeline that should start with a node block.
Our project uses a jenkins-shared-library which has generic pipeline stages. We are looking at adding a stage that will inspect the code coverage and fail the pipeline if the coverage targets aren’t met.
The Jenkins scripted pipeline that will return value can be defined as Using the def method an addition function is defined that will take two numbers and return the addition of it. Next, we need to use the node and stage block to define the scripted pipeline.
You are missing closure invocation. Your generateStage(name)
method returns a closure, and this closure is not invoked implicitly. (It works with parallel stages, because parallel
method expects a map where each entry value is a closure, so it iterates over all map entries and invokes collected closures).
Here is what your example should look like to add a non-parallel stage to the pipeline using generateStage(name)
method:
def foo = ["1", "2", "3"]
def parallelStagesFromMap = foo.collectEntries {
["Build ${it}" : generateStage(it)]
}
def generateStage(bar) {
return {
stage("Build ${bar}") {
echo "Building for ${bar}"
}
}
}
node {
parallel parallelStagesFromMap
generateStage("skipped") // no invocation, stage is skipped
generateStage("nonparallel").call()
}
And here is what the Blue Ocean UI looks like after running this exemplary pipeline:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With