How to send a referencedParameter to a readFileFromWorkspace through activeChoiceReactiveParam - jenkins

I'm trying to send a referencedParameter ('product') to a Groovy script (services.groovy) that is triggered by the command readFileFromWorkspace that is wrapped with an activeChoiceReactiveParam.
Expected result: Get a dropdown list with the files content.
Actual result: The job fails when processing the DSL script
ERROR: (services.groovy, line 5) No such property: product for class: dsl.jobs.argocd.services
I tried to define the products referenced parameter as an environment variable (And updated in the services.groovy script), it didn't work.
I tried to re-create the services.groovy file in the directory /tmp/ but I had issues finding the files.
products.groovy:
package dsl.jobs.argocd
return ['a','b','c']
services.groovy:
package dsl.jobs.argocd
return_value = []
if (product.equals("a")){
return_value = ['e']
}
if (product.equals("b")){
return_value = ['f']
}
if (product.equals("c")){
return_value = ['g']
}
return return_value;
Pipeline:
pipelineJob("test") {
description("test")
keepDependencies(false)
parameters {
activeChoiceParam('product') {
description('What product would you like to update?')
filterable()
choiceType('SINGLE_SELECT')
groovyScript {
script(readFileFromWorkspace('dsl/jobs/argocd/products.groovy'))
fallbackScript('return ["ERROR"]')
}
}
activeChoiceReactiveParam('service') {
description('Which services would you like to update?')
filterable()
choiceType('CHECKBOX')
groovyScript {
script(readFileFromWorkspace('dsl/jobs/argocd/services.groovy'))
fallbackScript('return ["ERROR"]')
}
referencedParameter("product")
}
}
}
Am I approaching this wrong? Is there a different way to use the same parameter in a few Groovy files?

Well, seems the code above is perfect, the only problem was the location of the services.groovy script.
I took the file out of the DSL directory (Since I don't want it to be parsed as a DSL file), referenced it to the correct location, and it works perfect.
Updated pipeline:
pipelineJob("test") {
description("test")
keepDependencies(false)
parameters {
activeChoiceParam('product') {
description('What product would you like to update?')
filterable()
choiceType('SINGLE_SELECT')
groovyScript {
script(readFileFromWorkspace('dsl/jobs/argocd/products.groovy'))
fallbackScript('return ["ERROR"]')
}
}
activeChoiceReactiveParam('service') {
description('Which services would you like to update?')
filterable()
choiceType('CHECKBOX')
groovyScript {
script(readFileFromWorkspace('services.groovy'))
fallbackScript('return ["ERROR"]')
}
referencedParameter("product")
}
}
}

Related

Pass variable to JobDsl seed job (Jenkins) in scriptText?

I am working on a project and i have to configure a jenkins using JCasC (config as code plugin).
I have to create a job BUT i can't pass variables in the script.
My code:
freeStyleJob("SEED") {
parameters {
stringParam("MY_PARAMETER", "defaultValue", "A parameter")
}
steps {
jobDsl {
scriptText('''
job("seedJOB") {
displayName('${MY_PARAMETER}') // don't work
description("${MY_PARAMETER}") // don't work
//description("$MY_PARAMETER") // don't work
//description('$MY_PARAMETER') // don't work
// i tried to use triple full quotes instead of triple single quote but it's not working...
... here the job...
'''.stripIndent())
}
}
EDIT: BEST SOLUTION HERE:
i'm writing groovy code in """ quotes so if I want to evaluate variable : I don't have to put ${} just write your variable name:
With the solution:
freeStyleJob("SEED") {
parameters {
stringParam("MY_PARAMETER", "defaultValue", "A parameter")
}
steps {
jobDsl {
scriptText('''
job("seedJOB") {
displayName('MY_PARAMETER) // solution
... here the job...
'''.stripIndent())
}
}
easy!
May you could write it to a file ? You'll get something like that in your step:
steps {
shell('echo $DISPLAY_NAME > display_name.txt')
jobDsl {
scriptText('''
job("seedjob") {
String jobname = readFileFromWorkspace('display_name.txt').trim()
displayName(jobname)
}
'''.stripIndent())
}
}
You could also use a .properties file to do it more properly.

Value returned from a script does not assigned to a variable declared in jenkins declarative pipeline stage

I am working on adding a jenkins Declarative pipeline for automation testing. In the test run stage i want to extract the failed tests from the log. i am using a groovy function for extracting the test result. this function is not a part of the jenkins pipeline. It is another script file. The function works fine and it build a string containing the failure details. Inside a pipeline stage i am calling this function and assinging the returned string to another variable. But when i echo the variable value it prints empty string.
pipeline {
agent {
kubernetes {
yamlFile 'kubernetesPod.yml'
}
}
environment{
failure_msg = ""
}
stages {
stage('Run Test') {
steps {
container('ansible') {
script {
def notify = load('src/TestResult.groovy')
def result = notify.extractTestResult("${WORKSPACE}/testreport.xml")
sh "${result}"
if (result != "") {
failure_msg = failure_msg + result
}
}
}
}
}
post {
always {
script {
sh 'echo Failure message.............${failure_msg}'
}
}
}
}
here 'sh 'echo ${result}'' print empty string. But 'extractTestResult()' returns a non-empty string.
Also i am not able to use the environment variable 'failure_msg' in post section it return an error 'groovy.lang.MissingPropertyException: No such property: failure_msg for class: groovy.lang.Binding'
can anyone please help me with this ?
EDIT:
Even after i fixed the string interpolation, i was getting the same
error. That was because jenkins does not allow using 'sh' inside
docker container. there is an open bug ticket in jenkins issue
board
I would suggest to use a global variable for holding the error message. My guess is that the variable is not existing in your scope.
def FAILURE_MSG // Global Variable
pipeline {
...
stages {
stage(...
steps {
container('ansible') {
script {
...
if (result != "") {
FAILURE_MSG = FAILURE_MSG + result
}
}
}
}
}
post {
always {
script {
sh "${FAILURE_MSG}" // Hint: Use correct String Interpolation
}
}
}
}
(Similar SO question can be found here)

How to return a value from Jenkins function to the build stage?

I want to return the value from groovy function back to my jenkins build stage so that the value can be used as a condition in other stages. I am not able to figure out how to implement this. I have tried something like below but that didn't work.
I have Jenkinsfile something like this:
pipeline
{
agent any
stages
{
stage('Sum')
{
steps
{
output=sum()
echo output
}
}
stage('Check')
{
when
{
expression
{
output==5
}
}
steps
{
echo output
}
}
}
}
def sum()
{
def a=2
def b=3
def c=a+b
return c
}
The above approach doesn't work. Can someone provide correct implementation.
You are missing a script-step. It is necessary if you want to execute plain groovy in your Jenkinsfile. Furthermore output has to be set as global variable if you want to access it later.
def output // set as global variable
pipeline{
...
stage('Sum')
{
steps
{
script
{
output = sum()
echo "The sum is ${output}"
}
}
}
...

How can I use foreach with conditionalSteps in Jenkins Job DSL

I'm trying to use the conditionalSteps add in with Jenkins Job DSL to conditionally trigger a build step. I want this step to trigger if any file in a given set exists. I am able to get this work by explcitly calling out multiple fileExists and an or. However I would like to dynamically create this using a foreach.
Here's what I have been playing with on http://job-dsl.herokuapp.com/
def files = ["file1", "file2", "file3"]
job('SomeJob') {
steps {
conditionalSteps {
condition {
/* This works fine:
or {
fileExists("file1.jenkinsTrigger", BaseDir.WORKSPACE)
}{
fileExists("file2.jenkinsTrigger", BaseDir.WORKSPACE)
}{
fileExists("file3.jenkinsTrigger", BaseDir.WORKSPACE)
}
*/
//But I want to create the Or clause from the array above
or {
files.each {
fileExists("${it}.jenkinsTrigger", BaseDir.WORKSPACE)
}
}
}
runner('Unstable')
steps {
gradle 'test'
}
}
}
}
The above gets
javaposse.jobdsl.dsl.DslScriptException: (script, line 17) No condition specified
and I have tried all manner of combinations to get this work without avail... any tips would be much appreciated
The or DSL method expects an array of closures. So you need to convert the collection of file names to an array of closure.
Example:
def files = ["file1", "file2", "file3"]
job('example') {
steps {
conditionalSteps {
condition {
or(
(Closure[]) files.collect { fileName ->
return {
fileExists("${fileName}.jenkinsTrigger", BaseDir.WORKSPACE)
}
}
)
}
runner('Unstable')
steps {
gradle 'test'
}
}
}
}

JobDSL - No signature of method java.lang.String

I have the following code to build as a job-dsl with "Active Choice Plugin":
freeStyleJob('job') {
description('description')
// Label which specifies on which nodes this job can be run.
label('master')
logRotator {
numToKeep(10)
}
//This Build is parametrized
parameters {
activeChoiceReactiveParam('branch') {
description('Select the branch you are going to use')
choiceType('SINGLE_SELECT')
script('["integration", "master"]')
fallbackScript('"Error. No branch to select."')
filterable(true)
}
}
}
I when executing it I get the following error:
How can this error be solved?
The syntax is actually a bit different:
job('example-1') {
parameters {
activeChoiceReactiveParam('CHOICE-1') {
description('Allows user choose from multiple choices')
filterable()
choiceType('SINGLE_SELECT')
groovyScript {
script('["choice1", "choice2"]')
fallbackScript('"fallback choice"')
}
referencedParameter('BOOLEAN-PARAM-1')
referencedParameter('BOOLEAN-PARAM-2')
}
}
}
Use the API viewer to lookup the syntax:
https://jenkinsci.github.io/job-dsl-plugin/#path/job-parameters-activeChoiceReactiveParam

Resources