Looping over parameters added by Jenkins extended choice parameters - jenkins

I've added an extendedChoice param on my .groovy file as below
extendedChoice(name: 'Subscription', defaultValue: 'demo_standard', description: 'Check mark on subscription/Part number', multiSelectDelimiter: ',', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_CHECKBOX', value: 'demo_standard,demo_advanced,trial_standard,trial_advanced,standard,advanced', visibleItemCount: 6),
for calling this param I have below line.
sh "./create.js ${params.Username} ${params.Subscription} "
From the above line what I want to do is. If I select 2 | 3 | 4 | till 6 checks for subscriptions in params then above sh line should run those multiple times.
Example:
If I select "demo_advanced,trial_standard" then it should call sh command twice with both subscriptions.
sh "./create.js ${params.Username} ${params.Subscription} -->(demo_advanced will replace)"
sh "./create.js ${params.Username} ${params.Subscription} -->(trial_standard will replace)"
How can I write this on my .groovy file??

Here is a full sample of how you can do this in your Pipeline.
properties([
parameters([
extendedChoice(name: 'Subscription', defaultValue: 'demo_standard', description: 'Check mark on subscription/Part number', multiSelectDelimiter: ',', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_CHECKBOX', value: 'demo_standard,demo_advanced,trial_standard,trial_advanced,standard,advanced', visibleItemCount: 6)
])
])
pipeline {
agent any
stages {
stage ("Example") {
steps {
script{
script {
echo "${params.Subscription}"
for(def sub : params.Subscription.split(',')) {
sh "./create.js ${params.Username} ${sub}"
}
}
}
}
}
}
}

Related

How to display the selected parameter in Jenkins?

There is a job groove pipeline that asks for parameters from the user interactively. After entering, I cannot display the selected parameters.
Here is my code:
node {
stage('Input Stage') {
Tag = sh(script: "echo 123'\n'456'\n'789'\n'111", returnStdout: true).trim()
input(
id: 'userInput', message: 'Choice values: ',
parameters: [
[$class: 'ChoiceParameterDefinition', name:'Tags', choices: "${Tag}"],
[$class: 'StringParameterDefinition', defaultValue: 'default', name:'Namespace'],
]
)
}
stage('Second Stage') {
println("${ChoiceParameterDefinition(Tags)}") //does not work
println("${ChoiceParameterDefinition(Namespace)}") //does not work
}
}
How to display the selected parameter correctly?
You would need to write the input step in a script. This should work.
node {
stage('Input Stage') {
Tag = sh(script: "echo 123'\n'456'\n'789'\n'111", returnStdout: true).trim()
script {
def userInputs =
input(
id: 'userInput', message: 'Choice values: ',
parameters: [
[$class: 'ChoiceParameterDefinition', name:'Tags', choices: "${Tag}"],
[$class: 'StringParameterDefinition', defaultValue: 'default', name:'Namespace'],
]
)
env.TAGS = userInputs['Tags']
env.NAMESPACE = userInputs['Namespace']
}
}
stage('Second Stage') {
echo "${env.TAGS}"
echo "${env.NAMESPACE}"
}
}
References:
Jenkins Declarative Pipeline: How to read choice from input step?
Read interactive input in Jenkins pipeline to a variable

Use Jenkins WORKSPACE environment variable in Jenkins declarative pipeline parameter

Is there a way to use Jenkins WORKSPACE environment variable in Jenkins declarative pipeline parameters?
Below attempt failed.
pipeline {
parameters {
extendedChoice description: 'Template in project',
multiSelectDelimiter: ',', name: 'TEMPLATE',
propertyFile: env.WORKSPACE + '/templates.properties',
quoteValue: false, saveJSONParameterToFile: false, type: 'PT_MULTI_LEVEL_SINGLE_SELECT',
value: 'Project,Template', visibleItemCount: 6
...
}
stages {
...
}
propertyFile: '${WORKSPACE}/templates.properties' didn't work either.
The environment variable can be accessed in various place in Jenkinsfile like:
def workspace
node {
workspace = env.WORKSPACE
}
pipeline {
agent any;
parameters {
string(name: 'JENKINS_WORKSPACE', defaultValue: workspace, description: 'Jenkins WORKSPACE')
}
stages {
stage('access env variable') {
steps {
// in groovy
echo "${env.WORKSPACE}"
//in shell
sh 'echo $WORKSPACE'
// in groovy script
script {
print env.WORKSPACE
}
}
}
}
}
The only way that worked is putting absolute path to Jenkins master workspace where properties file is located.
pipeline {
parameters {
extendedChoice description: 'Template in project',
multiSelectDelimiter: ',', name: 'TEMPLATE',
propertyFile: 'absolute_path_to_master_workspace/templates.properties',
quoteValue: false, saveJSONParameterToFile: false, type: 'PT_MULTI_LEVEL_SINGLE_SELECT',
value: 'Project,Template', visibleItemCount: 6
...
}
stages {
...
}
It seems that environment variables are not available during pipeline parameters definition before the pipeline actually triggered.

Active choice parameter with declarative Jenkins pipeline

I'm trying to use active choice parameter with declarative Jenkins Pipeline script.
This is my simple script:
environments = 'lab\nstage\npro'
properties([
parameters([
[$class: 'ChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
description: 'Select a choice',
filterLength: 1,
filterable: true,
name: 'choice1',
randomName: 'choice-parameter-7601235200970',
script: [$class: 'GroovyScript',
fallbackScript: [classpath: [], sandbox: false, script: 'return ["ERROR"]'],
script: [classpath: [], sandbox: false,
script: """
if params.ENVIRONMENT == 'lab'
return['aaa','bbb']
else
return ['ccc', 'ddd']
"""
]]]
])
])
pipeline {
agent any
tools {
maven 'Maven 3.6'
}
options {
disableConcurrentBuilds()
timestamps()
timeout(time: 30, unit: 'MINUTES')
ansiColor('xterm')
}
parameters {
choice(name: 'ENVIRONMENT', choices: "${environments}")
}
stages {
stage("Run Tests") {
steps {
sh "echo SUCCESS on ${params.ENVIRONMENT}"
}
}
}
}
But actually the second parameter is empty
Is it possible to use together scripted active choice parameter and declarative parameter?
UPD
Is there any way to pass list variable into script? For example
List<String> someList = ['ttt', 'yyyy']
...
script: [
classpath: [],
sandbox: true,
script: """
if (ENVIRONMENT == 'lab') {
return someList
}
else {
return['ccc', 'ddd']
}
""".stripIndent()
]
You need to use Active Choices Reactive Parameter which enable current job parameter to reference another job parameter value
environments = 'lab\nstage\npro'
properties([
parameters([
[$class: 'CascadeChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
description: 'Select a choice',
filterLength: 1,
filterable: true,
name: 'choice1',
referencedParameters: 'ENVIRONMENT',
script: [$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: true,
script: 'return ["ERROR"]'
],
script: [
classpath: [],
sandbox: true,
script: """
if (ENVIRONMENT == 'lab') {
return['aaa','bbb']
}
else {
return['ccc', 'ddd']
}
""".stripIndent()
]
]
]
])
])
pipeline {
agent any
options {
disableConcurrentBuilds()
timestamps()
timeout(time: 30, unit: 'MINUTES')
ansiColor('xterm')
}
parameters {
choice(name: 'ENVIRONMENT', choices: "${environments}")
}
stages {
stage("Run Tests") {
steps {
sh "echo SUCCESS on ${params.ENVIRONMENT}"
}
}
}
}
As of Jenkins 2.249.2 without any plugin and using a declarative pipeline,
the following pattern prompt the user with a dynamic dropdown menu (for him to choose a branch):
(the surrounding withCredentials bloc is optional, required only if your script and jenkins configuratoin do use credentials)
node {
withCredentials([[$class: 'UsernamePasswordMultiBinding',
credentialsId: 'user-credential-in-gitlab',
usernameVariable: 'GIT_USERNAME',
passwordVariable: 'GITLAB_ACCESS_TOKEN']]) {
BRANCH_NAMES = sh (script: 'git ls-remote -h https://${GIT_USERNAME}:${GITLAB_ACCESS_TOKEN}#dns.name/gitlab/PROJS/PROJ.git | sed \'s/\\(.*\\)\\/\\(.*\\)/\\2/\' ', returnStdout:true).trim()
}
}
pipeline {
agent any
parameters {
choice(
name: 'BranchName',
choices: "${BRANCH_NAMES}",
description: 'to refresh the list, go to configure, disable "this build has parameters", launch build (without parameters)to reload the list and stop it, then launch it again (with parameters)'
)
}
stages {
stage("Run Tests") {
steps {
sh "echo SUCCESS on ${BranchName}"
}
}
}
}
The drawback is that one should refresh the jenkins configration and use a blank run for the list be refreshed using the script ...
Solution (not from me): This limitation can be made less anoying using an aditional parameters used to specifically refresh the values:
parameters {
booleanParam(name: 'REFRESH_BRANCHES', defaultValue: false, description: 'refresh BRANCH_NAMES branch list and launch no step')
}
then wihtin stage:
stage('a stage') {
when {
expression {
return ! params.REFRESH_BRANCHES.toBoolean()
}
}
...
}

Jenkins pipeline input script with one prompt only

Don't need 2 prompt in Jenkins pipeline with input script. In snippet, there is highlighted 1 and 2 where pipeline prompt 2 times for user input.
If execute this pipeline, prompt 1 will provide user to "Input requested" only, so no option to "Abort". Prompt 2 is okay as it ask to input the value and also "Abort" option.
Prompt 1 is almost useless, can we skip promt this and directly reach to prompt 2?
pipeline {
agent any
parameters {
string(defaultValue: '', description: 'Enter the Numerator', name: 'Num')
string(defaultValue: '', description: 'Enter the Denominator', name: 'Den')
}
stages {
stage("foo") {
steps {
script {
if ( "$Den".toInteger() == 0) {
echo "Denominator can't be '0', please re-enter it."
env.Den = input message: 'User input required', ok: 'Re-enter', // 1-> It will ask whether to input or not
parameters: [string(defaultValue: "", description: 'Enter the Denominator', name: 'Den')] // 2-> It will ask to input the value
}
}
sh'''#!/bin/bash +x
echo "Numerator: $Num\nDenominator: $Den"
echo "Output: $((Num/Den))"
'''
}
}
}
}
Yes, you can simplify the input by using $class: 'TextParameterDefinition'.
e.g.
pipeline {
agent any
parameters {
string(defaultValue: '', description: 'Enter the Numerator', name: 'Num')
string(defaultValue: '', description: 'Enter the Denominator', name: 'Den')
}
stages {
stage("foo") {
steps {
script {
if ( "$Den".toInteger() == 0) {
env.Den = input(
id: 'userInput', message: 'Wrong denominator, give it another try?', parameters: [
[$class: 'TextParameterDefinition', defaultValue: '', description: 'Den', name: 'den']
]
)
}
}
sh'''#!/bin/bash +x
echo "Numerator: $Num\nDenominator: $Den"
echo "Output: $((Num/Den))"
'''
}
}
}
}
If you want to go the extra mile and ask for both values:
def userInput = input(
id: 'userInput', message: 'Let\'s re-enter everything?', parameters: [
[$class: 'TextParameterDefinition', defaultValue: '', description: 'Denominator', name: 'den'],
[$class: 'TextParameterDefinition', defaultValue: '', description: 'Numerator', name: 'num']
]
)
print userInput
env.Den = userInput.den
env.Num = userInput.num

How to get user input data in shell (Jenkinsfile)

I am trying to take user input through Jenkinsfile but I can't use that in the shell. Here is the code:
def userInput = timeout(time:60, unit:'SECONDS') {input(
id: 'userInput', message: 'URL Required', parameters: [
[$class: 'TextParameterDefinition', defaultValue: '', description: 'URL', name: 'url'],
])
}
node{
echo "Env jsfsjaffwef:"+userInput) //this works
echo "${userInput}" //but this does not
sh '''
python test.py ${userInput}
'''
}
Be careful about string interpolation: Variables will be replaced inside double quotes ("..", or the multi-line variant """), but not inside single quotes ('..', resp. '''..'''). So the sh step shouldn't have it replaced, the echo above should have it correctly.
def userInput = timeout(time:60, unit:'SECONDS') {input(
id: 'userInput', message: 'URL Required', parameters: [
[$class: 'TextParameterDefinition', defaultValue: '', description: 'URL', name: 'url'],
])
}
node {
echo "Env jsfsjaffwef:"+userInput) //this works
echo "${userInput}" // this should have also worked before
sh """
python test.py ${userInput}
"""
}
So make sure that you exactly apply the right quotes and don't just replace them compared to what people suggest here.
The following works for me on Jenkins 2.62:
def userInput = input(
id: 'userInput', message: 'URL Required', parameters: [
[$class: 'TextParameterDefinition', defaultValue: '', description: 'URL', name: 'url'],
])
node('master') {
sh "echo userInput is: ${userInput}"
}

Resources