Syntax for defining MultiJob conditional step in Job DSL plugin - jenkins

I using Jenkins CI with Job DSL and Multijob plugins. I'm attempting to define a parametrized Multijob containing conditional step using DSL, but I fail to figure out the correct syntax. My code:
multiJob("MyJob")
{
parameters {
stringParam("PLATFORM", "Win32")
stringParam("CONFIGURATION", "Release")
}
steps
{
phase("Build") {
job("BuildJob") { sameNode() }
}
conditionalSteps {
condition {
and { stringsMatch("${PLATFORM}", "Win32", false) } { stringsMatch("${CONFIGURATION}", "Release", false) }
}
runner('Fail')
steps {
phase("Prepare installer") {
job("PrepareInstallerJob") { sameNode() }
}
}
}
}
}
Running this I get the following error:
Processing DSL script My.groovy
ERROR: (My.groovy, line 117) No such property: PLATFORM for class: javaposse.jobdsl.dsl.helpers.step.RunConditionContext
Finished: FAILURE
When line 117 is the line containing the "and" condition.
What would be the correct syntax? Why does not it resolve the PLATFORM parameter?

Groovy interpolates double quoted strings, see String interpolation. You need to use single quotes to avoid the interpolation, e.g. '${PLATFORM}'.

Related

Can Jenkins pipelines have variable stages?

From my experience with Jenkins declarative-syntax pipelines, I'm aware that you can conditionally skip a stage with a when clause. E.g.:
run_one = true
run_two = false
run_three = true
pipeline {
agent any
stages {
stage('one') {
when {
expression { run_one }
}
steps {
echo 'one'
}
}
stage('two') {
when {
expression { run_two }
}
steps {
echo 'two'
}
}
stage('three') {
when {
expression { run_three }
}
steps {
echo 'three'
}
}
}
}
...in the above code block, there are three stages, one, two, and three, each of whose execution is conditional on a boolean variable.
I.e. the paradigm is that there is a fixed superset of known stages, of which individual stages may be conditionally skipped.
Does Jenkins pipeline script support a model where there is no fixed superset of known stages, and stages can be "looked up" for conditional execution?
To phrase it as pseudocode, is something along the lines of the following possible:
my_list = list populated _somehow_, maybe reading a file, maybe Jenkins build params, etc.
pipeline {
agent any
stages {
if (stage(my_list[0]) exists) {
run(stage(my_list[0]))
}
if (stage(my_list[1]) exists) {
run(stage(my_list[1]))
}
if (stage(my_list[2]) exists) {
run(stage(my_list[2]))
}
}
}
?
I think another way to think about what I'm asking is: is there a way to dynamically build a pipeline from some dynamic assembly of stages?
For dynamic stages you could write either a fully scripted pipeline or use a declarative pipeline with a scripted section (e. g. by using the script {…} step or calling your own function). For an overview see Declarative versus Scripted Pipeline syntax and Pipeline syntax overview.
Declarative pipeline is better supported by Blue Ocean so I personally would use that as a starting point. Disadvantage might be that you need to have a fixed root stage, but I usually name that "start" or "init" so it doesn't look too awkward.
In scripted sections you can call stage as a function, so it can be used completely dynamic.
pipeline {
agent any
stages {
stage('start') {
steps {
createDynamicStages()
}
}
}
}
void createDynamicStages() {
// Stage list could be read from a file or whatever
def stageList = ['foo', 'bar']
for( stageName in stageList ) {
stage( stageName ) {
echo "Hello from stage $stageName"
}
}
}
This shows in Blue Ocean like this:

Jenkins Job DSL does not take parameters

I have a Jenkins seed DSL job:
job("cronjob/${ACTION}_${ENVRIONMENT}_environment_CRONJOB") {
scm {
git('https://git_user#github.com/abc-Data/devops.git','*/develop')
}
triggers {
scm("${SCHEDULE}")
}
steps {
ansiblePlaybook("ansible/scripts/ansible-${ACTION}.yml") {
inventoryPath("/etc/ansible/hosts")
credentialsId("usercred")
extraVars {
extraVar('environment_name',"${ENVRIONMENT}",false)
}
}
}
}
ACTION, ENVIRONMENT and SCHDULE are parameters.
ACTION can have values of create or remove, and I have two ansible playbooks ansible-create.yml and ansible-remove.yml.
When I run the sseed job, I got the following error:
ERROR: (unknown source) No signature of method: javaposse.jobdsl.dsl.helpers.step.StepContext.ansiblePlaybook() is applicable for argument types: (org.codehaus.groovy.runtime.GStringImpl, script$_run_closure1$_closure4$_closure5) values: [ansible/scripts/ansible-create.yml, ...]
Finished: FAILURE
The ansiblePlaybook("ansible/scripts/ansible-${ACTION}.yml") does not work with the variable ACTION.
If I hard code the the script name in ansiblePlaybook, the seed job will create a new job.
The other two variables work fine in the DSL script.
What did I miss here?
Thanks!
As #daggett suggested above, I changed the code as below:
job("cronjob/${ACTION}_${ENVRIONMENT}_environment_CRONJOB") {
scm {
git('https://git_user#github.com/abc-Data/devops.git','*/develop')
}
triggers {
scm("${SCHEDULE}")
}
steps {
ansiblePlaybook("ansible/scripts/ansible-${ACTION}.yml" as String) {
inventoryPath("/etc/ansible/hosts")
credentialsId("usercred")
extraVars {
extraVar('environment_name',"${ENVRIONMENT}",false)
}
}
}
}
It works as expect and create a new job with the use entered variable values. Thanks to you again #daggett!

Jenkins publishers postBuildScripts doesn't work

I have a groovy script to setup a scheduled job in Jenkins.
I want to execute some shell scripts on failed build.
If I had the scripts manually after the job creation after the job is updated by groovy script, they run.
But the groovy script does not add it:
job('TestingAnalysis') {
triggers {
cron('H 8 28 * *')
}
steps {
shell('some jiberish to create error')
}
publishers {
postBuildScripts {
steps {
shell('echo "fff"')
shell('echo "FFDFDF"')
}
onlyIfBuildSucceeds(false)
onlyIfBuildFails(true)
}
retryBuild {
rerunIfUnstable()
retryLimit(3)
fixedDelay(600)
}
}
}
Every thing works fine except:
postBuildScripts {
steps {
shell('echo "fff"')
shell('echo "FFDFDF"')
}
onlyIfBuildSucceeds(false)
onlyIfBuildFails(true)
}
This is my result:
I tried postBuildSteps and also got error.
I tried also with error:
postBuildScripts {
steps {
sh' echo "ggg" '
}
onlyIfBuildSucceeds(false)
onlyIfBuildFails(true)
}
Take a look at JENKINS-66189 seems like there is an issue with version 3.0 of the PostBuildScript in which the old syntax (that you are using) is no longer supported. In order to use the new version it in a Job Dsl script you will need to use Dynamic DSL syntax.
Use the following link in your own Jenkins instance to see the correct usage:
YOUR_JENKINS_URL/plugin/job-dsl/api-viewer/index.html#path/freeStyleJob-publishers-postBuildScript.
it will help you build the correct command. In your case it will be:
job('TestingAnalysis') {
triggers {
cron('H 8 28 * *')
}
steps {
shell('some jiberish to create error')
}
publishers {
postBuildScript {
buildSteps {
postBuildStep {
stopOnFailure(false) // Mandatory setting
results(['FAILURE']) // Replaces onlyIfBuildFails(true)
buildSteps {
shell {
command('echo "fff"')
}
shell {
command('echo "FFDFDF"')
}
}
}
}
markBuildUnstable(false) // Mandatory setting
}
}
}
Notice that instead of using functions like onlyIfBuildSucceeds and onlyIfBuildFails you now just pass a list of relevant build results to the results function. (SUCCESS,UNSTABLE,FAILURE,NOT_BUILT,ABORTED)

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.

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