How to access Jenkinsfile parameters values as strings in a loop

10,946

Solution 1

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.

Solution 2

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

Share:
10,946

Related videos on Youtube

SamGamgee
Author by

SamGamgee

Updated on June 04, 2022

Comments

  • SamGamgee
    SamGamgee almost 2 years

    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.

  • SamGamgee
    SamGamgee about 6 years
    Thank you Jacob, I will give it a try soon! Sadly I think it will not work because the parameters are injected by a Jenkins plugin, so I guess it's not using that @Field annotation...
  • Jacob Aae Mikkelsen
    Jacob Aae Mikkelsen about 6 years
    The @Field annotation I don't think you need in Jenkins, it takes care of that for you. I used it just to get it to run as a Script in the Groovy Console. Admittedly, I have not tested this in Jenkins.
  • Jacob Aae Mikkelsen
    Jacob Aae Mikkelsen about 6 years
    I've added a Jenkins script demoing something similar to what you are trying to
  • SamGamgee
    SamGamgee about 6 years
    I think I couldn't save the parameters like that because they are added with properties([parameters([string(name: 'BRANCH', defaultValue: 'master')])]), but as mkobit posted on his answer all of the params are accessible in params[]! :)
  • SamGamgee
    SamGamgee about 6 years
    Thank you mkobit! Using params["TEST_0${i}"] worked like a charm :)