How to access Jenkinsfile parameters values as strings in a loop

14.7k Views Asked by At

In our Jenkinsfile we have a lot of parameters (parameterized build) and in this case I want to check if each parameter is toggled and act on that. These parameters have similar names but end with a different decimal, so I would like to iterate over them to achieve this.

I have something like:

if ("${TEST_00}" == "true") { testTasksToRun.add(testsList[0]) }
if ("${TEST_01}" == "true") { testTasksToRun.add(testsList[1]) }
if ("${TEST_02}" == "true") { testTasksToRun.add(testsList[2]) }
if ("${TEST_03}" == "true") { testTasksToRun.add(testsList[3]) }
if ("${TEST_04}" == "true") { testTasksToRun.add(testsList[4]) }
if ("${TEST_05}" == "true") { testTasksToRun.add(testsList[5]) }

But I would like to have something like:

for(int i=0; i<testsList.size(); i++) {
    if ("${TEST_0${i}}" == "true") {
        testTasksToRun.add(testsList[i])
    }
}

I tried to search for solutions and experimented on the GroovyConsole but didn't manage to get anything to work. Looks like it has something to do with "binding", but I am not familiar with that.

2

There are 2 best solutions below

1
mkobit On BEST ANSWER

params is a GlobalVariable that when accessed returns an unmodifiable map. You can see the implementation here.

Because it returns a Map, you can use the same strategies to iterate over it as you would for normal Groovy maps.

params.each { key, value ->
  // do things
}
for (entry in params) {
  // entry.key or entry.value
}

Newer versions of the Groovy CPS libraries should handle most iteration cases since JENKINS-26481 has been resolved.

4
Jacob Aae Mikkelsen On

You can do this using the this keyword, and reference properties of the current scope. The below sample code works in the Groovy Console (as this is a script, the @Field annotation is necessary, for scoping)

import groovy.transform.Field

def testsList = ['a','b','c']

@Field 
def TEST_00 = "true"

@Field 
def TEST_01 = "false"

@Field 
def TEST_02 = "true"

for(int i=0; i<testsList.size(); i++) {
    if ( this."TEST_0${i}" == "true") {
        println testsList[i]
    }
}

In a Jenkins pipeline script, you can do something along the lines of:

node {
    def testsList = ['a','b','c']

    def myInput = input message: 'Give me input 1', parameters: [string(defaultValue: '', description: '', name: 'DEMO1'), string(defaultValue: '', description: '', name: 'DEMO2'), string(defaultValue: '', description: '', name: 'DEMO3')]

    for(int i=0; i<testsList.size(); i++) {
        if ( myInput."DEMO${i+1}" == "true") {
           println testsList[i]
        }
    }
}

When prompted, it will output only the values (a,b,c) where you supply the string "true" to the input