How to use Groovy variable into Extended Choice Jenkins Plugin? - jenkins

I'd like to use a Groovy variable as a value for Extended Choice plugin. Seems trivial, but doesn't work - fails with "groovy.lang.MissingPropertyException: No such property: $COMPONENTS_LIST for class: groovy.lang.Binding".
Any ideas?
environment {
COMPONENTS_LIST= "one two three"
}
parameters {
extendedChoice (description: 'Components', multiSelectDelimiter: ' ',
name: 'Components_To_Deploy', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_MULTI_SELECT',
value: $COMPONENTS_LIST, visibleItemCount: 3)
}

It is a syntax error, you are trying to set the named parameter value to the content of the variable $COMPONENTS_LIST; which doesn't exist. Also there's a problem with the scope of the variable; which needs to be available in both closures. So try defining a variable outside the scope of both closure with the value you need and then use the variables inside the closures, as in the following example:
def componentsList = "one two three"
environment {
COMPONENTS_LIST = componentsList
}
parameters {
extendedChoice (description: 'Components', multiSelectDelimiter: ' ',
name: 'Components_To_Deploy', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_MULTI_SELECT',
value: componentsList, visibleItemCount: 3)
}

I think that this is a syntax issue. You have to use double quote to refer to you variable :
def COMPONENTS_LIST= "one two three"
parameters {
extendedChoice (description: 'Components', multiSelectDelimiter: ' ',
name: 'Components_To_Deploy', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_MULTI_SELECT',
value: "${COMPONENTS_LIST}", visibleItemCount: 3)
}

Related

Jenkinsfile print parameters nicely

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
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.
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
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}"
}

Formatter not called despite passing the same binding path

I can't wrap my head around this. What am I overlooking?
Here is a minimal sample: https://plnkr.co/edit/VjqGeG9JpHblyLBb?preview
<tnt:InfoLabel
text="{
path: 'LastName',
formatter: '.formatter.typeText'
}"
colorScheme="{
path: 'LastName',
formatter: '.formatter.typeColor'
}" />
// formatter.js
sap.ui.define([], function () {
"use strict";
return {
typeText: function(sLastName) {
// Called with 'sLastName' value
},
typeColor: function(sLastName) {
// Not called
}
};
});
I'm using UI5 1.79 with sap.ui.model.odata.v4.ODataModel.
Add targetType: 'any' to the property binding info that has the issue. E.g.:
<tnt:InfoLabel
text="{
path: 'LastName',
formatter: '.getMyText'
}"
colorScheme="{
path: 'LastName',
formatter: '.getMyColorScheme',
targetType: 'any'
}"
/>
With sap.ui.model.odata.v4.ODataModel, data types in property bindings are automatically determined according to the EDM type of the entity property. I.e. in the case above: even without having a certain type explicitly assigned to the text property, the v4.ODataPropertyBinding automatically picks the String type (because LastName has Type="Edm.String" in $metadata) and assigns it to the type:
<tnt:InfoLabel
text="{
path: 'LastName',
formatter: '.getMyText',
type: 'sap.ui.model.odata.type.String' &lt-- automatically added by v4.ODataPropertyBinding
}"
This was fine for the text property since it actually awaits a string value, but doing the same for other properties, such as colorScheme which awaits an int value, results in a FormatException.*
In order to prevent the automatic Type Determination, the targetType: 'any' has to be added.
* With commit:4611772, which is available as of 1.80, we can see the corresponding error message in the console:
FormatException in property 'colorScheme' of 'Element sap.tnt.InfoLabel#...': <LastName value> is not a valid int value. Hint: single properties referenced in composite bindings and within binding expressions are automatically converted into the type of the bound control property, unless a different 'targetType' is specified. targetType:'any' may avoid the conversion and lead to the expected behavior.

How can I pass MatrixCombinationsParameterValue with simple filter in groovy pipeline

I have a job with matrix project, I added ElasticAxis name:label
I also added a matrix combinations parameter name: labelFilter
I want to run the job from groovy pipeline with filter label == "PA16"
This call is not working for me:
[$class: 'MatrixCombinationsParameterValue', name: 'labelFilter', value: 'label=="PA16"']
The question is: What is the correct syntax to call the matrix combinations parameter?
I have few branches, each branch should run with specific label, the pipeline gets the branch name and run a job in jenkins with the name of the label. Lets say I want to run the job with the label "PA16" so I add this code to groovy pipeline file:
build job: 'test_matrix',
parameters: [
string(name: 'RndBranch', value: RndBranch),
string(name: 'BuildNumber', value: PAVersion),
string(name: 'Auto_Build_Path', value: autoFolder),
string(name: 'Installer_folder', value: Installer_folder),
string(name: 'RabbitMQ_Server', value: rabbitMQServer),
string(name: 'QueName', value: qName),
[$class: 'MatrixCombinationsParameterValue', name: 'labelFilter', filter: 'label=="PA16"']
]
For Jenkins pipeline please use matrix instead. For example:
stage ('TestMatrix') {
matrix {
axes {
axis {
name 'labelFilter'
values 'PA16', 'PA17', 'PA18'
}
axis {
name 'otherFilter'
values 'Filter1', 'Filter2', 'Filter3'
}
}
stages {
stage ('Doing what you want') {
steps { echo "Doing what I want"}
}
}
}
}
You can read more at following document about matrix or here

How to build Jenkins pipeline input parameters dynamically with Groovy?

In a Jenkins pipeline, it is possible to request input data using
def returnValue = input message: 'Need some input',
parameters: [string(defaultValue: 'adefval', description: 'a', name: 'aaa'),
string(defaultValue: 'bdefval', description: 'b', name: 'bbb')]
To build such a list dynamically, I tried something like
def list = ["foo","bar"]
def inputRequest = list.collect { string(defaultValue: "def", description: 'description', name: it) }
def returnValue = input message: 'Need some input', parameters: [inputRequest]
This does not work:
java.lang.ClassCastException: class org.jenkinsci.plugins.workflow.support.steps.input.InputStep.setParameters() expects class hudson.model.ParameterDefinition but received class java.util.ArrayList
Probably, Groovy can figure out dynamically in the first case which object is required, but in the second case it does not work anymore, as collect returns an ArrayList?
How to create such a list correctly?
edit: maybe this question not very useful for itself, but may still serve as a code sample...
Ok it was quite a simple fix, as the collect already returns an ArrayList, it should not be wrapped into another list when setting the parameters...
def returnValue = input message: 'Need some input', parameters: inputRequest
I struggled with this for a while, but it's not as complicated as I thought.
At its simplest, you can define an empty array and fill it with parameter types.
I'm honestly not clear on what the object type is, but it works.
ArrayList pa = []
if(<some conditional>) {
pa += choice (name: 'source_feed', choices: ['Development', 'Production'])
pa += string (name: 'deployVersion', defaultValue: 'Latest', description: 'version')
pa += extendedChoice (name: 'environments', value: 'one,two,three', description: 'envs', type: 'PT_CHECKBOX')
pa += booleanParam (name: 'dryRunMode', defaultValue: false, description: 'dry')
pa += booleanParam (name: 'skipPreChecks', defaultValue: false, description: 'skip')
}
else if (<some other conditional>) {
pa += string (name: 'CommandServiceVersion', defaultValue: '', description: 'commandservice')
}
def result = input message: "Enter Parameters",
ok: 'ok go!',
parameters: pa
echo result.toString()
As long as you can pass the Array[] around, it works. I ended up creating the array[] outside the pipeline, as a global, so it can be passed around throughout the run; as opposed to an env var, which can only be a string.
You can use the the following code. It will generate the choices A,B,C for you. This can be found by using the Pipeline syntax option in Jenkins. I use it because it saves time and less typos.
def createInputParameters(){
properties([[$class: 'RebuildSettings', autoRebuild: false, rebuildDisabled:
false],parameters([choice(choices: ['A', 'B', 'C'], description: '', name:
'Test')]),
[$class: 'ThrottleJobProperty', categories: [],
limitOneJobWithMatchingParams: false,
maxConcurrentPerNode: 0, maxConcurrentTotal: 0,
paramsToUseForLimit: '',
throttleEnabled: false,
throttleOption: 'project']])
}

How do i pass named parameters (not all string values) to another job in Jenkins Pipeline?

I want to pass a bunch of parameters that are named, some of which are also Maps of named parameters into another job. The below does not work:
node
{
stage ('Deploying')
{
build job: 'job-runner',
serverSetup: [test: 'test'],
jobs: [
myJob: "true"
],
runType: [test: "test"]
}
}
I want the called job to be able to do all of the following:
parameters.serverSetup.test
if ( parameters.jobs.MyJob == true )
parameters.runtype.test
How would I do that?
With the build job function, you can pass parameters. Ex : build job: 'job-runner', parameters: [[$class: 'StringParameterValue', name: 'string1', value: param1], [$class: 'BooleanParameterValue', name: 'myJob', value: params.myJob]]

Resources