How to fix Jenkins String Interpolation with downstream job? - jenkins

I have a parent pipeline job that takes parameters and passes them to a downstream job. I've achieves this in multiple ways with no issue however I keep getting a string interpolation warning that I am trying to fix, but am unable to do so. Based on the documentation (https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#string-interpolation) in most cases using single quotes should work, however this passes the literal name rather than the value (e.g if I set my variable as SECRET_PWD and call it like '${SECRET_PWD}' it shows up as ${SECRET_PWD} on the downstream job instead of the value passed to the parameter.
Here's what I've tried to so far:
Parent Pipeline
pipeline {
agent any
parameters {
password(defaultValue: "", description: 'The admin password', name: 'SUPER_SECRET_ADMIN_PWD')
stages {
stage("Stage1") {
steps {
build job: "secret_job/${env.BRANCH}", propagate: true, wait: true, parameters: [
[$class: 'StringParameterValue', name: 'SUPER_SECRET_ADMIN_PWD', value: "${params.SUPER_SECRET_ADMIN_PWD}" ]
]
}
}
This gives the following error in when calling the downstream job.
Warning: A secret was passed to "build" using Groovy String interpolation, which is insecure.
Affected argument(s) used the following variable(s): [SUPER_SECRET_ADMIN_PWD]
See https://jenkins.io/redirect/groovy-string-interpolation for details.
The parameter 'SUPER_SECRET_ADMIN_PWD' did not have the type expected by secret_job ยป secret_branch. Converting to Password Parameter.
Note: I am aware that the StringParameterValue is the reason for the first error. I have changed this in a few different ways to solve that but i still get the interpolation issue.
The other ways I've tried are:
password(name: 'SUPER_SECRET_ADMIN_PWD', value: "${SUPER_SECRET_ADMIN_PWD}") = This works but still interpolation issue
password(name: 'SUPER_SECRET_ADMIN_PWD', value: "${SUPER_SECRET_ADMIN_PWD}") = This does NOT work as it passes ${SUPER_SECRET_ADMIN_PWD} as the value rather than the one entered into the parameter. HOWEVER the interpolation warning goes away
[$class: 'StringParameterValue', name: 'SUPER_SECRET_ADMIN_PWD', value: '${params.SUPER_SECRET_ADMIN_PWD}' = This does NOT work as it passes ${SUPER_SECRET_ADMIN_PWD} as the value rather than the one entered into the parameter. HOWEVER the interpolation warning goes away
I've also used ${env.SUPER_SECRET_ADMIN_PWD} similar to ${params.SUPER_SECRET_ADMIN_PWD}
Note that I've changed my downstream job to use single quotes and i'm doing a simple sh script something like below with no interpolation errors (I have them before though).
stages{
stage("test"){
steps{
script{
sh '''
echo ${SUPER_SECRET_ADMIN_PWD}
'''
}
}
}
How do I go about solving interpolation and still passing the password parameter down to a downstream job?

Related

Multiple Jenkins parameterized build value pass value to Jenkinsfile for declarative pipeline

Hi my Jenkins project is parameterised build. I have 3 variables. 1 choice and 2 string parameter. The choise perameter is do_you_want_to_deploy and string parameter is git_tag and git_branch. I want to know how can i pass this value to a jenkinsfile?
In freestyle project, I selecft 'Extra Variables' and then got Key and Value. So key i put deploy_location, value is ${do_you_want_to_deplo}. Key is which_tag, value is ${git_tag}. Key is which_ranch, value is ${git_branch}. I am performing for ansible. How can i add verbos -vvv as well? This for pipelin project. Below is my code
ansiblePlaybook(
vaultCredentialsId: 'VaultId',
inventory: 'host-inventory.yml',
playbook: 'myPlaybook.yml'
)
``
I also need pass same value to downstream project. How can this be done?
Hi my Jenkins project is parameterised build. I have 3 variables. 1
choice and 2 string parameter. The choise perameter is
do_you_want_to_deploy and string parameter is git_tag and git_branch.
I want to know how can i pass this value to a jenkinsfile?
In Jenkinsfile there is parameters block to define variables. As per your use case, parameters definition may look like below. Here, by choice in your explanation I was assuming you need a toggle but if you need a list of items then use choice parameter type.
pipeline {
...
parameters {
booleanParam(name: 'do_you_want_to_deploy', defaultValue: false, description: 'Description of do_you_want_to_deploy')
string(name: 'git_tag', defaultValue: '', description: 'Description of git_tag')
string(name: 'git_branch', defaultValue: '', description: 'Description of git_branch')
}
stages {
stage('Example') {
steps {
ansiblePlaybook(
...
)
}
}
}
}
In freestyle project, I selecft 'Extra Variables' and then got Key and
Value. So key i put deploy_location, value is ${do_you_want_to_deplo}.
Key is which_tag, value is ${git_tag}. Key is which_ranch, value is
${git_branch}. I am performing for ansible. How can i add verbos -vvv
as well?
Ansible plugin has an option extraVars that can be used to pass number of variables from the pipeline. There is another option named extras that takes a string and can be used to pass additional variables, switches etc.
Together, ansiblePlaybook may look like below,
ansiblePlaybook (
vaultCredentialsId: 'VaultId',
inventory: 'host-inventory.yml',
playbook: 'myPlaybook.yml',
extras: '-vvv',
extraVars: [
deploy_location: params.do_you_want_to_deploy,
which_tag: params.git_tag,
which_branch: params.git_branch
]
)
I also need pass same value to downstream project. How can this be
done?
As you can see from the example of ansiblePlaybook above, the parameters can be accessed via params object.

In Jenkins, is there a timeout for Build with Parameters?

In Jenkins, I know that input can be combined with timeout (example), but what about Build with Parameters?
My (maybe incorrect) thought is to have "default" parameters set on a declarative pipeline Jenkinsfile, so that if a human runs it, he can enter the parameters, but when it runs periodically (e.g., daily at 12pm), the prompt is not required and the "default" parameters are used.
You are correct with regard to setting default values and can do this:
options {
timeout(time: params.timeoutTime, unit: params.timeoutUnit)
}
parameters {
string(name: 'timeoutTime', defaultValue: '30', description: '')
string(name: 'timeoutUnit', defaultValue: 'MINUTES', description: '')
}
When you trigger the build manually, it will use the parameters that you provide. For timer triggered builds, it will use the default values.
It seems like what you're looking for is the parameterized scheduler plugin perhaps? See my answer Here

String interpolation and concatenation for Jenkinsfile

I am trying to setup a Jenkinsfile that gets a job to call other jobs, based on the parameters passed into itself.
Instead of having multiple when conditions, I'm thinking that it would be smarter (and manageable for future scaling) if the names of the jobs being called would ideally be concatenating a common prefix with the parameter being passed in, for example:
CICD_api-gateway
CICD_front-end
CICD_customer-service
I'm having difficulty mixing string interpolation with string concatenation to achieve this:
build job: 'CICD_"${params.SERVICE_NAME}"', wait : false
In Linux, we are able to use eval to achieve this. I'm not sure what the equivalent is in Jenkinsfile syntax.
The full code below:
pipeline {
agent any
parameters { string(name: 'SERVICE_NAME', defaultValue: '', description: 'Service being deployed.') }
stages {
stage('Build Trigger'){
steps{
echo "CICD_${params.SERVICE_NAME}"
build job: 'CICD_"${params.SERVICE_NAME}"', wait : false
}
}
}
}
Change it to be a Gstring from the beginning, no need for the single quotes:
build job: "CICD_${params.SERVICE_NAME}", wait : false

How to access all nodes from NodeParameterDefinition in jenkins pipeline?

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

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