Reputation: 147
I want to build some Packages using several Docker-Images in a Jenkins-Pipeline . The Pipeline below works .. but I want to implement the Stage(s) is a more "Loop"-ish way ....
pipeline {
agent { label 'docker' }
stages {
stage ('Running on ubuntu:20.04') {
agent {
docker {
reuseNode true
label 'docker'
image 'ubuntu:20.04'
}
}
steps {
sh 'uname -a && bash --version'
}
}
stage ('Running on ubuntu:22.04') {
agent {
docker {
reuseNode true
label 'docker'
image 'ubuntu:22.04'
}
}
steps {
sh 'uname -a && bash --version'
}
}
}
}
An Ideas how to implement that ? ..
Initially I tried using something like this
pipeline {
agent { label 'docker' }
stages {
stage ('Loop-Stage') {
steps {
script {
// Loop trough List (*works*)
for (item in ['ubuntu:20.04', 'ubuntu:22.04']) {
// Create new stage (*works*)
stage ('Running on ${item}') {
// Set agent (*fails*)
agent {
docker {
reuseNode true
label 'docker'
image "${item}"
}
}
steps {
sh 'uname -a && bash --version'
}
}
}
}
}
}
}
}
But this does now work. The Error seems to indicate a mixture between scripted&declarative Syntax .. you get the following error:
java.lang.NoSuchMethodError: No such DSL method 'agent' found among steps [ArtifactoryGradleBuild, MavenDescriptorStep, addInteractivePromotion, ansiColor, archive, artifactoryBuildTrigger, artifactoryDistributeBuild, artifactoryDownload, artifactoryEditProps, artifactoryGoPublish, ar
How can I apply a the corresponding "agent" to the dynamically generated Stage ?
Upvotes: 3
Views: 230
Reputation: 14604
When you go into a script block you can no longer use some of the declarative syntaxes like agent
. That's why you are getting the error java.lang.NoSuchMethodError: No such DSL method 'agent'
. Jenkins is confused about whether you are trying to use Declarative Pipeline syntax or just scripted syntax with groovy.
You can do something like this. This will create a list of stages and then execute them in parallel.
def stageList
def getStages(image) {
return {
stage("Running on Ubunt:${image}") {
docker.image("ubuntu:${image}").inside {
sh 'uname -a'
}
}
}
}
pipeline {
agent any
stages {
stage ("Generate Stages") {
steps {
script {
def imageList = ["20.04", "22.04"]
stageList = imageList.collectEntries {
["${it}" : getStages(it)]}
}
}
}
stage("Run Stages") {
steps {
script {
parallel stageList
}
}
}
}
}
If you want sequential execution, you can modify your pipeline as shown below.
pipeline {
agent { label 'docker' }
stages {
stage ('Loop-Stage') {
steps {
script {
// Loop trough List (*works*)
for (item in ['ubuntu:20.04', 'ubuntu:22.04']) {
// Create new stage (*works*)
stage ('Running on ${item}') {
docker.image("${item}").inside {
sh 'uname -a'
sh 'uname -a && bash --version'
}
}
}
}
}
}
}
}
Upvotes: 3