2

We have a Jenkinsfile with parameters declared as follows:

def params = [string(name: 'ENVIRONMENT', value: environment),
              string(name: 'VERSION',     value: version),
              string(name: 'REGION',      value: region)]

I'd like to echo these, for example

DEPLOYING: ENVIRONMENT=STAGING, VERSION=1.3.0, REGION=EU

However calling echo "$params" prints:

[@string(name=ENVIRONMENT,value=STAGING), @string(name=VERSION,value=1.3.0), @string(name=REGION,value=EU)]

I tried iterating the array - e.g. :

params.each { echo it } throws UnsupportedOperationException: no known implementation of class java.lang.String is using symbol ‘string’

params.each { echo it.name } throws RejectedAccessException: No such field found: field org.jenkinsci.plugins.structs.describable.UninstantiatedDescribable name

How can I print the params array nicely?

EDIT - from Matt Schuchard's response:

def params = [string(name: 'ENVIRONMENT', value: "STAGING"),
              string(name: 'VERSION',     value: "1.3.0"),
              string(name: 'REGION',      value: "EU")]
print "$params"

params.each() { param, value ->
    print "Parameter: ${param}, Value: ${value}"
}

returns (i.e. Value is all null):

[@string(name=ENVIRONMENT,value=STAGING), @string(name=VERSION,value=1.3.0), @string(name=REGION,value=EU)]
Parameter: @string(name=ENVIRONMENT,value=STAGING), Value: null
Parameter: @string(name=VERSION,value=1.3.0), Value: null
Parameter: @string(name=REGION,value=EU), Value: null
user1016765
  • 2,935
  • 2
  • 32
  • 48

3 Answers3

4

You can use a Groovy map iterator lambda method (such as each) to iterate over the params map. An example follows:

params.each() { param, value ->
  print "Parameter: ${param}, Value: ${value}"
}

If you decide to use this directly inside a pipeline block, then this will need to be placed inside a script block when using declarative DSL.

Matthew Schuchard
  • 25,172
  • 3
  • 47
  • 67
  • I have edited the question to include this code - Value is 'null' in all cases – user1016765 Mar 24 '21 at 20:29
  • @user1016765 So it sounds like the `params` object does not have a `map` operator method defined in its class even though it is basically a `map` type when accessed. That is a bug I was honestly not expecting. Sorry about that. – Matthew Schuchard Mar 25 '21 at 10:58
  • No worries - the code extracting the values from the @string(...) works so all good. – user1016765 Mar 25 '21 at 14:40
0

There must be a better way but the following works

Iterating the params array:

 1. Cast each parameter to a regular String
 2. Extracted the value between @string( VALUE )
 3. Split the key/value pairs first by comma ','
 4. Then split each side of the above by equals '='
 5. Concatenate the second argument
def pretty(params) {
    def s = ""
    params.each { param ->
        def a = ("${param}" =~ /^@string\((.+)\)$/)[ 0 ][ 1 ]
        def b = a.split(",")
        s = s + b[0].split("=")[1] + "=" + b[1].split("=")[1] + "\n"
    }
    return s
}

Returns:

ENVIRONMENT=STAGING
VERSION=1.3.0
REGION=EU
user1016765
  • 2,935
  • 2
  • 32
  • 48
0

is params goal is to parameterized the build?
if this is the case, you can use parameters directive

The parameters directive provides a list of parameters that a user should provide when triggering the Pipeline.
The values for these user-specified parameters are made available to Pipeline steps via the params object.

declerative pipeline:

Declarative Pipeline supports parameters out-of-the-box, allowing the Pipeline to accept user-specified parameters at runtime via the parameters directive.

parameters {
        string(name: 'ENVIRONMENT', defaultValue: 'STAGING', description: 'Environment to test. e.g: production/develop'),
        string(name: 'VERSION', defaultValue: '1.3.0', description: 'Version to run'),
        string(name: 'REGION', defaultValue: 'EU', description: 'Region')
    }

scripted pipeline:

Configuring parameters with Scripted Pipeline is done with the properties step, which can be found in the Snippet Generator

properties([
    parameters([
        string(name: 'ENVIRONMENT', defaultValue: 'STAGING', description: 'Environment to test. e.g: production/develop'),
        string(name: 'VERSION', defaultValue: '1.3.0', description: 'Version to run'),
        string(name: 'REGION', defaultValue: 'EU', description: 'Region')
    ])
])

now, those parameters are accessible as members of the params variable
so, then you can simply use:

params.each() { param, value ->
    print "Parameter: ${param}, Value: ${value}"
}
Tam Nguyen
  • 88
  • 1
  • 8