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.


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]
  }
}

Pipeline supports two syntaxes, Declarative (introduced in Pipeline 2.5) and Scripted Pipeline.Both of which support building continuous delivery pipelines. Both may be used to define a Pipeline in either the web UI or with a Jenkinsfile, though it’s generally considered a best practice to create a Jenkinsfile and check the file into the source control repository.


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.

Loops in Jenkinsfiles. GitHub Gist: instantly share code, notes, and snippets.


Since May 30, 2017 you can iterate over Maps without workarounds. You need to upgrade Pipeline: Groovy plugin to >= 2.33 Related issue: https://issues.jenkins-ci.org/browse/JENKINS-27421

Plugin changelog: https://plugins.jenkins.io/workflow-cps

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

for(element in mymap) {
    sh "make build KEY=${element.key} VALUE=${element.value}"
}

Say we have a Map: let m = new Map();, using m.values() returns a map iterator. But I can't use forEach() or map() on that iterator and implementing a while loop on that iterator seems like an anti-pattern since ES6 offer functions like map() .


There are have another simple way for parse json object to groovy object - Parsing and producing JSON

import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText('{ "myList": [4, 8, 15, 16, 23, 42] }')
println(object.myList)

I have the following Jenkinsfile script block. When the job is executed the end-user ticks several checkboxes (Extended Choice Parameters) and the selected values go to ReposToUpdate and npmDepende


Iterating over the map using std::for_each and lambda function. We can also use an stl algorithm std::for_each to iterate over the map. It will iterate on each of the map entry and call the callback provided by us. In below example we will use a lambda function as callback. Lambda function will receive each of the map entry in a pair.


There are several ways to iterate over map. Here is comparison of their performances for a common data set stored in map by storing a million key value pairs in map and will iterate over map. 1) Using entrySet() in for each loop. for (Map.Entry<String,Integer> entry : testMap.entrySet()) { entry.getKey(); entry.getValue(); } 50 milliseconds


First of all, it is the only way to iterate over a map in older versions of Java. The other important feature is that it is the only method that allows you to remove entries from the map during iteration by calling iterator.remove (). If you try to do this during For-Each iteration you will get "unpredictable results" according to Javadoc.