How to access all nodes from NodeParameterDefinition in jenkins pipeline? - jenkins

I'm writing a Jenkinsfile that use the NodeLabel Parameter Plugin for jenkins. Here I use the NodeParameterDefinition to give the user the ability to select nodes where the build should happen. I have enabled allowMultiSelectionForConcurrentBuilds, but I only still get a string with only one node name when accessing the parameter value in the Jenkinsfile. The parameter value type is also a string, how can I get all the nodes the user selected for the parameter?
paramter definition:
[
$class: 'NodeParameterDefinition',
allowedSlaves: ['ALL (no restriction)'],
defaultSlaves: ['master'],
description: 'What nodes to run the build on.',
name: 'BUILD_NODE',
nodeEligibility: [$class: 'AllNodeEligibility'],
triggerIfResult: 'allowMultiSelectionForConcurrentBuilds'
]
So if I select multiple nodes when executing, I still only get one node name when accessing this parameter value.
echo "Will build on $BUILD_NODE";
Is multi node selection was enabled not possible with pipeline scripts?
How I access the parameter value:
echo "Will build on $BUILD_NODE";
node("$BUILD_NODE")
{
...
}

NodeLabel Parameter Plugin doesn't work smoothly with Pipeline and Blue Ocean, just as it is not updated frequently (see the revision history). Jenkins Plugins must follow requirements in order to be compatible with Pipeline.
Unfortunately the issue is still unresolved (unknown when it will be resolved):
https://issues.jenkins-ci.org/browse/JENKINS-43720
The problem is that I can not use env.NODE_PARAM or NODE_PARAM to get
multiple selection of nodes, as those are only a string representation
of a single node.
You can vote for this jira-task JENKINS-43720 (click "Vote for this issue"), or participate in the plugin development.
So far I found my clumsy way to imitate the plugin behavior by using another parameter option choice (but this works in Blue Ocean!):
properties([
parameters([
choice(choices: ["none", "node_1", "node_2"], description: "", name: "NODE_1"),
choice(choices: ["none", "node_1", "node_2"], description: "", name: "NODE_2")
])
])
// here you can write your behaviour
// e.g. validation of params, e.g. if 'none' is selected, then use the default node_X
node(env.NODE_1) { }
node(env.NODE_2) { }
or you can use the option string:
properties([
parameters([
string(defaultValue: "node_1, node_2", description: "", name: "NODE", trim: false)
])
])
// parse here the param env.NODE

Related

How to define a Label parameter in a parameterized build using scripted pipeline approach

I'm trying to solve the same problem as this SO question: How to trigger a jenkins build on specific node using pipeline plugin?
The only difference in my case is that the job I'm triggering is another scripted pipeline job. So the second step in the proposed solution does not apply in my case:
Install Node and Label parameter plugin
In test_job's configuration, select 'This build is parameterized' and add a Label parameter and set the parameter name to 'node'
In pipeline script, use code (code omitted)
My question is how to define the :
org.jvnet.jenkins.plugins.nodelabelparameter.LabelParameterDefinition
parameter inside my scripted pipeline parameterized job (not through the GUI).
What I have tried:
properties([[$class : 'RebuildSettings',
autoRebuild : false,
rebuildDisabled: false],
parameters([org.jvnet.jenkins.plugins.nodelabelparameter.LabelParameterDefinition(name: 'node')])])
The easiest way to generate the code you need for your parameterized scripted pipeline is to:
Go to Pipeline Snippet Generator
Select "properties: Set job properties"
Check "This project is parameterized"
Click "Add parameter" and select "Label"
Click "Generate pipeline script"
This gives you:
properties([
[$class: 'RebuildSettings', autoRebuild: false, rebuildDisabled: false],
parameters([
[$class: 'LabelParameterDefinition',
allNodesMatchingLabel: false,
defaultValue: '',
description: '',
name: 'node',
nodeEligibility: [$class: 'AllNodeEligibility'], t
riggerIfResult: 'allCases']
]
)
])
But in my case this wasn't even necessary. All you need is a regular string parameter with a custom name, lets say "node" and then do:
node(params.node){}
If your use case is to have generic pipeline to be executed in particular Agent Node, then you can use 'Agent-Server-parameter' plugin with which you can add agent-name parameter as agent of your choice from drop down, into parameterized pipeline (or call it as 'Master' pipeline) and can use agent-name parameter under your pipeline script(e.g. calling sample.groovy inside Master parameterized-pipeline).
And for another parameters, (may be string, boolean, choice) you defined within pipeline(without GUI).
See the below example of sample.groovy which I am calling from Master job.
#!groovy
/* This Groovy implementation is pipeline for a Sample project */
pipeline {
agent { label params['agent-name'] } //agent can be configured for stage as well.
options {
timeout(time: 1, unit: 'HOURS', activity: true) // abort if nothing happens
timestamps() // prepend timestamps on the console output
}//option
parameters {
booleanParam(
name: 'BOO_PARAM1', defaultValue: false,
description: 'Enable Parameter 1')
booleanParam(
name: 'BOO_PARAM2', defaultValue: false,
description: 'Enable Parameter 2')
stringParam('MY_PATH', 'C:\SampleProject')
choiceParam('RUN_JOBON_NODE', ['YES', 'NO'])
}//parameters
environment {
/* Environment Variable definition and its use */
BOO_PARAM1 = "${params.BOO_PARAM1}"
}//environment
stages {
/* agent is single for complete pipeline but can be changed for stage */
stage('Hello') {
when {
expression { return params.BOO_PARAM1}
}
print"Hello Stage on %agent-name%"
} // Stage
}//stages
}//pipeline
Note: post build stage is excluded.
'agent-server-parameter' plugin gives you leverage to have generic pipeline (common stages) to be executed on different Nodes.

How to conditionally hide parameter?

I am trying to create a jenkins pipeline job with parameters. I want the parameters to show up conditionally. The condition depends on a selection of a previous parameter.
I have tried the Active choices plug-in. It allows me to choose a value of a parameter conditionally. I want the whole parameter to appear in the UI conditionally.
Is it possible with jenkins pipeline files?
I do not believe this is possible. In the case of declarative/scripted pipelines, parameters are 'post-processed' meaning essentially the ones you see are what was evaluated in the previous 'run/build'. Which is why it takes a build before 'Build with Parameters' becomes available.
As an alternative, (if you're using scripted/declarative pipelines) you could use an Input step and make it trigger conditionally.
if ( x == true ) {
def userInput = input(
id: 'userInput', message: 'Let\'s promote?', parameters: [
[$class: 'TextParameterDefinition', defaultValue: 'uat', description: 'Environment', name: 'env'],
[$class: 'TextParameterDefinition', defaultValue: 'uat1', description: 'Target', name: 'target']
])
}
Example pulled from:
https://support.cloudbees.com/hc/en-us/articles/204986450-Pipeline-How-to-manage-user-inputs

Dynamic parameter on Jenkins Pipeline depending on branch

I have something like this on my jenkins pipeline
properties([
parameters([
booleanParam(description: 'Merge master to this branch', name: 'merge_master', defaultValue: false),
someOtherParameters
])
])
Obviously the first parameter that doesn't make sense if the pipeline is running on master branch. So, how can I have this parameter only if the pipeline is not running on master branch?
If you haven't found a way yet, you could just add the elements to the parameters list conditionally like this
def list = []
if (env.BRANCH_NAME != 'master') {
list.add(booleanParam(description: 'Merge master to this branch', name: 'merge_master', defaultValue: false))
}
//example list.add(otherParams)
//finally
properties([parameters(list)])
More on adding to lists in groovy can be found here.
I was able to use hakamari's example as long as I only had items that had classes that could be found like string and boolean. Since I'm also using (CascadeChoiceParameter), and others, I got the same array error, and I had to convert all to the $class: 'org.biouno.unochoice.CascadeChoiceParameter' syntax to get it to work properly. I'm not sure why, but it sure was frustrating to figure that out.
newParameters.add([
$class: 'hudson.model.ChoiceParameterDefinition',
name: 'AWSenvironment',
choices: ['Development', 'Provision'],
description: 'where to deploy, most of the time will be Development'
])
newParameters.add([
$class: 'hudson.plugins.validating_string_parameter.ValidatingStringParameterDefinition',
name: 'HostName',
defaultValue: 'AutoBuild',
description: 'What hostname would you like?<br/><i>Your last name will be prefixed to this name</i>',
regex: /^[a-zA-Z0-9.:-]+$/,
failedValidationMessage: "Regular alphanumerics, periods, colons, and hyphens only!",
])

Parameterized Jenkins Pipeline: Choices not showing up

I am trying to setup my pipeline as a Parameterized Pipeline using Single_select choice parameters.
My pipeline header looks as follows:
properties(
[
parameters([
[
$class: 'ChoiceParameter',
choiceType: 'PT_SINGLE_SELECT',
description: 'Select your testcase',
filterable: false,
name: 'testCases',
choices: ['HappyFlow', 'NewYork_HappyFlow']
]
]
),
pipelineTriggers([])
]
)
What happens when I am running my pipeline is the following:
Jenkins leaves the dropdown empty instead of giving me the options I specified in my pipeline properties
How would I get the dropdown to be filled with the parameters from my pipeline properties?
This worked for me:
parameters([choice(choices:['HappyFlow', 'NewYork_HappyFlow'], description: 'Select your testcase', name: 'testCases')
])
It sounds like you might be affected by JENKINS-26143: Workflow Snippet Generator - Incorrect format for Input with Choice Parameter. I think a fix is out for it in Jenkins 2.112 based on the comments on the issue, but for now, you can change choices from:
choices: ['HappyFlow', 'NewYork_HappyFlow']
to
choices: 'HappyFlow\nNewYork_HappyFlow'

How to pass boolean parameter value in pipeline to downstream jobs?

I'm using Jenkins v2.1 with the integrated delivery pipeline feature (https://jenkins.io/solutions/pipeline/) to orchestrate two existing builds (build and deploy).
In my parameterized build I have 3 user parameters setup, which also needs to be selectable in the pipeline.
The pipeline script is as follows:
node: {
stage 'build'
build job: 'build', parameters: [[$class: 'StringParameterValue', name: 'target', value: target], [$class: 'ListSubversionTagsParameterValue', name: 'release', tag: release], [$class: 'BooleanParameterValue', name: 'update_composer', value: update_composer]]
stage 'deploy'
build job: 'deploy', parameters: [[$class: 'StringParameterValue', name: 'target', value: target]]
}
This works correctly except for the BooleanParameterValue. When I build the pipeline the following error is thrown:
java.lang.ClassCastException: hudson.model.BooleanParameterValue.value expects boolean but received class java.lang.String
How can I resolve this typecasting error?
Or even better, is there a less cumbersome way in which I can just pass ALL the pipeline parameters to the downstream job.
In addition to Jesse Glick answer, if you want to pass string parameter then use:
build job: 'your-job-name',
parameters: [
string(name: 'passed_build_number_param', value: String.valueOf(BUILD_NUMBER)),
string(name: 'complex_param', value: 'prefix-' + String.valueOf(BUILD_NUMBER))
]
Assuming
value: update_composer
was the issue, try
value: Boolean.valueOf(update_composer)
is there a less cumbersome way in which I can just pass ALL the pipeline parameters to the downstream job
Not that I know of, at least not without using Jenkins API calls and disabling the Groovy sandbox.
like Jesse Jesse Glick and abguy said you can enumerate string into Boolean type:
Boolean.valueOf(string_variable)
or the opposite Boolean into string:
String.valueOf(boolean_variable)
in my case I had to to downstream Boolean parameter to another job.
So for this you will need the use the class BooleanParameterValue :
build job: 'downstream_job_name', parameters:
[
[$class: 'BooleanParameterValue', name: 'parameter_name', value: false],
], wait: true
build job: 'downstream_job_name', parameters: [
booleanParam(name: 'parameter_name', value: false)
]
(cf. https://www.jenkins.io/doc/pipeline/steps/pipeline-build-step/#-build-%20build%20a%20job)
Jenkins "boolean" parameters are really just a shortcut for the "choice parameter" type with the choices hardcoded to the strings "true" and "false", and with a checkbox to set the string variable. But in the end, it is just that: a string variable, with nothing to do with a true boolean. That's why you need to convert the string to a boolean if you don't want to do a string comparison like:
if (myBoolean == "true")
Not sure if this answers this question. But I was looking for something else. Highly recommend see this 2 minute video. If you wanted to get into more details then see docs - Handling Parameters and this link
And then if you have something like blue ocean, the choices would look something like this:
As discussed in the video, Jenkins is blue because it's using Blue Ocean Plugin
You define and access your variables like this:
pipeline {
agent any
parameters {
string(defaultValue: "TEST", description: 'What environment?', name: 'userFlag')
choice(choices: ['TESTING', 'STAGING', 'PRODUCTION'], description: 'Select field for target environment', name: 'DEPLOY_ENV')
}
stages {
stage("foo") {
steps {
echo "flag: ${params.userFlag}"
echo "flag: ${params.DEPLOY_ENV}"
}
}
}
}
Automated builds will pick up the default params. But if you do it manually then you get the option to choose.
And then assign values like this:
Things are much easier nowadays: the builtin Snippet Generator supports the 'build' step (I don't know since when though).

Resources