Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define and iterate over map in Jenkinsfile

My knowledge of groovy doesn't go very far beyond what little I know about Jenkinsfiles. I'm trying to figure out if it's possible to have a map defined in a Jenkinsfile that can then be applied in a "for loop" fashion.

I have these variables:

mymap = {
    "k1": "v1"
    "k2": "v2"
    "k3": "v3" 
}

I have a stage in my Jenkinsfile that looks like this:

stage('Build Image') {
    withCredentials([[<the credentials>]) {
    sh "make build KEY={k1,k2,k3} VALUE='{v1,v2,v3}'"
}

Is there a way to make a Build Image stage for each of the pairings in mymap? I haven't had any luck with what I've tried.

like image 363
numb3rs1x Avatar asked Mar 13 '17 18:03

numb3rs1x


People also ask

How do you declare a variable in Jenkinsfile?

Environment variables can be defined using NAME = VALUE syntax. To access the variable value you can use these three methods $env.NAME , $NAME or ${NAME} There are no differences between these methods.

What does checkout SCM do in Jenkinsfile?

The checkout step will checkout code from source control; scm is a special variable which instructs the checkout step to clone the specific revision which triggered this Pipeline run.

In which language Jenkinsfile is written?

The Jenkinsfile is written using the Groovy Domain-Specific Language and can be generated using a text editor or the Jenkins instance configuration tab. The Declarative Pipelines is a relatively new feature that supports the concept of code pipeline. It enables the reading and writing of the pipeline code.


2 Answers

There are some similar user-submitted examples in the Jenkins documentation.

Something like this should work:

def data = [
  "k1": "v1",
  "k2": "v2",
  "k3": "v3",
]

// Create a compile job for each item in `data`
work = [:]
for (kv in mapToList(data)) {
  work[kv[0]] = createCompileJob(kv[0], kv[1])
}

// Execute each compile job in parallel
parallel work


def createCompileJob(k, v) {
  return {
    stage("Build image ${k}") { 
      // Allocate a node and workspace
      node {
        // withCredentials, etc.
        echo "sh make build KEY=${k} VALUE='${v}'"
      }
    }
  }
}

// Required due to JENKINS-27421
@NonCPS
List<List<?>> mapToList(Map map) {
  return map.collect { it ->
    [it.key, it.value]
  }
}
like image 147
Christopher Orr Avatar answered Sep 16 '22 17:09

Christopher Orr


You can iterate over a map like this:

def map = [Io: 1, Europa: 2, Ganymed: 3]
for (element in map) {
    echo "${element.key} ${element.value}"
}

I don't know if a dynamic count of stages is useful. Maybe you could use parallel nodes, but I don't know if that's possible.

like image 43
Christopher Avatar answered Sep 20 '22 17:09

Christopher