I have a jenkins job groovy script like below. I want the Github branch to be taken from the parameter value.
Groovy Script :
git_url = "git#github.deere.com:ABC/XYZ.git" jenkins_node = "master"
freeStyleJob('myjob') {
logRotator(numToKeep = 100)
parameters { stringParam("GIT_BRANCH", "master" , "master cert dev") }
label(jenkins_node)
scm {
git {
remote { url(git_url) }
branch($GIT_BRANCH)
extensions { }
}
}
You have to put $GIT_BRANCH variable into single quotes so it is not get parsed by job DSL script. Paste your script to this Job DSL playground app and you will get an exception:
javaposse.jobdsl.dsl.DslScriptException: (script, line 12) No such property: $GIT_BRANCH for class: javaposse.jobdsl.dsl.helpers.scm.GitContext
at javaposse.jobdsl.dsl.AbstractDslScriptLoader.runScriptEngine(AbstractDslScriptLoader.groovy:112)
at javaposse.jobdsl.dsl.AbstractDslScriptLoader$_runScripts_closure1.doCall(AbstractDslScriptLoader.groovy:59)
at javaposse.jobdsl.dsl.AbstractDslScriptLoader.runScripts(AbstractDslScriptLoader.groovy:46)
at javaposse.jobdsl.dsl.AbstractDslScriptLoader$runScripts$0.callCurrent(Unknown Source)
But if you add single quotes:
branch('$GIT_BRANCH')
then you will get your job XML file generated correctly:
<!-- 1. myjob -->
<project>
<actions></actions>
<description></description>
<keepDependencies>false</keepDependencies>
<properties>
<hudson.model.ParametersDefinitionProperty>
<parameterDefinitions>
<hudson.model.StringParameterDefinition>
<name>GIT_BRANCH</name>
<defaultValue>master</defaultValue>
<description>master cert dev</description>
</hudson.model.StringParameterDefinition>
</parameterDefinitions>
</hudson.model.ParametersDefinitionProperty>
</properties>
<canRoam>false</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers></triggers>
<concurrentBuild>false</concurrentBuild>
<builders></builders>
<publishers></publishers>
<buildWrappers></buildWrappers>
<logRotator>
<daysToKeep>100</daysToKeep>
<numToKeep>-1</numToKeep>
<artifactDaysToKeep>-1</artifactDaysToKeep>
<artifactNumToKeep>-1</artifactNumToKeep>
</logRotator>
<assignedNode>master</assignedNode>
<scm class='hudson.plugins.git.GitSCM'>
<userRemoteConfigs>
<hudson.plugins.git.UserRemoteConfig>
<url>git#github.deere.com:ABC/XYZ.git</url>
</hudson.plugins.git.UserRemoteConfig>
</userRemoteConfigs>
<branches>
<hudson.plugins.git.BranchSpec>
<name>$GIT_BRANCH</name>
</hudson.plugins.git.BranchSpec>
</branches>
<configVersion>2</configVersion>
<doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
<gitTool>Default</gitTool>
</scm>
</project>
Here is job DSL I used in the sandbox:
git_url = "git#github.deere.com:ABC/XYZ.git"
jenkins_node = "master"
freeStyleJob('myjob') {
logRotator(numToKeep = 100)
parameters {
stringParam("GIT_BRANCH", "master" , "master cert dev")
}
label(jenkins_node)
scm {
git {
remote { url(git_url) }
branch('$GIT_BRANCH')
extensions { }
}
}
}
Now when you run a job generated from this DSL it will ask you for GIT_BRANCH parameter and the value you pass will be used to set up the branch.
Related
I have a Jenkins folder "testFolder", a view "test_view" in the folder, n job pipelines in "test_view".One parameter named "exclude" in n jobs, how to update the value of parameter "exclude" in batch of the pipelines under "test_view"? Is there any plugin / API / code can do it?
I refer to this blog and execute the groovy script in the Jenkins script console
Update default values of Jenkins Job Parameters but the solution will delete all existing parameters and add the parameter back which is quite risky. If I remove this line
((Job) job).removeProperty(ParametersDefinitionProperty.class);
It can override the default value of the parameter but it will keep the old parameter in the config.xml. Is there any function that can update specific parameters, maybe something like
((Job) job).updateProperty(new ParametersDefinitionProperty(newParameters));
Groovy script
Jenkins instance = Jenkins.getInstance();
List items = instance.getAllItems();
String folderPath = "test_folder";
String viewNameInFolder = "test_view";
String parameterNameInPipelines = "exclude";
String parameterValue = "exclude.json";
String parameterDescription = "";
for (Item item: items) {
if (item instanceof com.cloudbees.hudson.plugins.folder.Folder) {
if (item.getFullName().trim().equals((folderPath).trim())) {
//locate the expected folder
Object[] viewsArray = item.getAllViews().toArray();
for(Object view: viewsArray){
if(view.getViewName().trim().equals(viewNameInFolder)){
// locate the expected view under folder
Object[] jobsArray = view.getAllItems().toArray();
for (Object job: jobsArray) { // Loop though all pipelines job
if(job instanceof org.jenkinsci.plugins.workflow.job.WorkflowJob) {
StringParameterDefinition param1 = new StringParameterDefinition(parameterNameInPipelines , parameterValue, parameterDescription);
ParameterDefinition[] newParameters = [param1];
((Job) job).addProperty(new ParametersDefinitionProperty(newParameters));
}
}
}
}
}
}
}
config.xml
<flow-definition plugin="workflow-job#2.40">
<actions/>
<description/>
<keepDependencies>false</keepDependencies>
<properties>
<hudson.plugins.jira.JiraProjectProperty plugin="jira#3.2.1">
<siteName>https://$sitename.com/</siteName>
</hudson.plugins.jira.JiraProjectProperty>
<com.sonyericsson.jenkins.plugins.bfa.model.ScannerJobProperty plugin="build-failure-analyzer#1.20.0">
<doNotScan>false</doNotScan>
</com.sonyericsson.jenkins.plugins.bfa.model.ScannerJobProperty>
<com.sonyericsson.rebuild.RebuildSettings plugin="rebuild#1.28">
<autoRebuild>false</autoRebuild>
<rebuildDisabled>false</rebuildDisabled>
</com.sonyericsson.rebuild.RebuildSettings>
<hudson.model.ParametersDefinitionProperty>
<parameterDefinitions class="java.util.Arrays$ArrayList">
<a class="hudson.model.ParameterDefinition-array">
<hudson.model.StringParameterDefinition>
<name>exclude</name>
<description/>
<defaultValue>exclude.json</defaultValue>
<trim>false</trim>
</hudson.model.StringParameterDefinition>
</a>
</parameterDefinitions>
</hudson.model.ParametersDefinitionProperty>
<hudson.model.ParametersDefinitionProperty>
<parameterDefinitions class="java.util.Arrays$ArrayList">
<a class="hudson.model.ParameterDefinition-array">
<hudson.model.StringParameterDefinition>
<name>exclude</name>
<description/>
<defaultValue>exclude2.json</defaultValue>
<trim>false</trim>
</hudson.model.StringParameterDefinition>
</a>
</parameterDefinitions>
</hudson.model.ParametersDefinitionProperty>
</properties>
<definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps#2.90">
<script>pipeline { agent any stages { stage('Hello') { steps { echo 'Hello World' } } } } </script>
<sandbox>true</sandbox>
</definition>
<triggers/>
<disabled>false</disabled>
</flow-definition>
I'm trying to use a simple FreeStyleJob SCM , and set the credentialId UUID from build parameter. The problem is, it seems the credentials is not parsing the parameter correctly.
scm {
git {
remote {
github('\${MY_REPO_HANDLE}', 'ssh')
credentials('\${MY_REPO_CREDENTIALS}')
}
branch('\${MY_BRANCH}')
}
}
My MY_REPO_CREDENTIALS is a simple String parameter
stringParam {
name("MY_REPO_CREDENTIALS")
defaultValue("teste-credential")
}
Log:
Warning: CredentialId "${MY_REPO_CREDENTIALS}" could not be found.
UPDATE
This Jenkins Job is created by another Jenkins Job using DSL external. In resume, Job 1 whenn triggered will create the Job 2 on jenkins. When I try to use "$ (without \) the job will fail because this parameter doesn't exist on Job 1 context.
job config.xml:
<scm class="hudson.plugins.git.GitSCM">
<userRemoteConfigs>
<hudson.plugins.git.UserRemoteConfig>
<url>git#github.com:${MY_REPO_HANDLE}.git</url>
<credentialsId>${MY_REPO_CREDENTIALS}</credentialsId>
</hudson.plugins.git.UserRemoteConfig>
</userRemoteConfigs>
<branches>
<hudson.plugins.git.BranchSpec>
<name>${MY_BRANCH}</name>
</hudson.plugins.git.BranchSpec>
</branches>
<configVersion>2</configVersion>
<doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
<gitTool>Default</gitTool>
<browser class="hudson.plugins.git.browser.GithubWeb">
<url>https://github.com/${MY_REPO_HANDLE}/</url>
</browser>
</scm>
The final solution was set the ssh agent before build, using wrapper:
wrappers {
sshAgent("\${MY_REPO_CREDENTIALS}")
}
keepDependencies(false)
scm {
git {
remote {
github("\${MY_REPO_HANDLE}", 'ssh')
}
branch("\${MY_BRANCH}")
}
}
You can switch to using " instead of ' so you can use the autofill feature:
scm {
git {
remote {
github("${MY_REPO_HANDLE}", 'ssh')
credentials("${MY_REPO_CREDENTIALS}")
}
branch("${MY_BRANCH}")
}
}
my dsl job script in brief
job('test') {
steps {
shell('echo VERSION=$VERSION > version.txt\n' +
'echo VERSION_SUFFIX=$VERSION_SUFFIX >> version.txt\n' +
'echo GROUP_ID=$GROUP_ID >> version.txt')
// EnvInject Plugin
environmentVariables {
propertiesFile('version.txt')
}
}
publishers {
postBuildScripts {
steps {
shell('echo ${VERSION}')
}
onlyIfBuildSucceeds(false)
onlyIfBuildFails(false)
}
downstreamParameterized {
trigger('next-job') {
parameters {
predefinedProp('relVersion', '${VERSION}')
}
}
}
}
}
I need $VERSION number to pass to the downstream job a parameter.
I tried, ${env.VERSION} and also tried many options, but i couldn't catch the VERSION . any help is appreciated, thanks in advance.
You can use the option Prepare an environment for the run which is executed before SCM.
Option Prepare an environment for the run is not belongs pre-build/ build /post build, but job properties.
There is no job DSL API supports to configure this option. But we can use configure block.
job('next-job') {
configure { project ->
project / 'properties' << 'EnvInjectJobProperty' {
info {
loadFilesFromMaster false
propertiesContent 'Branch=${relVersion}'
}
keepBuildVariables true
keepJenkinsSystemVariables true
overrideBuildParameters false
on true
}
} // end of configure block
scm {
git {
remote {
url("ssh://git#bitbucket.rl.git")
}
branches('${branch}')
}
} // end of scm
steps {}
publishers {}
}
Above job DSL can generate following xml as the content of seed job's config.xml
<project>
<actions></actions>
<description></description>
<keepDependencies>false</keepDependencies>
<properties>
<EnvInjectJobProperty>
<info>
<loadFilesFromMaster>false</loadFilesFromMaster>
<propertiesContent>Branch=${relVersion}</propertiesContent>
</info>
<keepBuildVariables>true</keepBuildVariables>
<keepJenkinsSystemVariables>true</keepJenkinsSystemVariables>
<overrideBuildParameters>false</overrideBuildParameters>
<on>true</on>
</EnvInjectJobProperty>
</properties>
<canRoam>true</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers></triggers>
<concurrentBuild>false</concurrentBuild>
<builders></builders>
<publishers></publishers>
<buildWrappers></buildWrappers>
<scm class='hudson.plugins.git.GitSCM'>
<userRemoteConfigs>
<hudson.plugins.git.UserRemoteConfig>
<url>ssh://git#bitbucket.rl.git</url>
</hudson.plugins.git.UserRemoteConfig>
</userRemoteConfigs>
<branches>
<hudson.plugins.git.BranchSpec>
<name>${branch}</name>
</hudson.plugins.git.BranchSpec>
</branches>
<configVersion>2</configVersion>
<doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
<gitTool>Default</gitTool>
</scm>
</project>
You can try jod DSL on http://job-dsl.herokuapp.com/ to check generated xml from it as expect or not.
The Jenkins Job DSL plugin (version 1.42) allows defining MultiJobs:
multiJob('MyMultiJob'){
steps{
phase('First')
phaseJob('JobA'){
#job configuration
}
}
}
}
Is it possible to define a job and add it to a MultiJob in separate steps like in the following example?
jobA = job('JobA')
multiJob('MyMultiJob'){
steps{
phase('First')
jobA
}
}
}
Being forced to define many different jobs inside the MultiJob definition seems complicated and adds a lot of complexity. Are there workarounds? Is it possible to move the definition of a phase job to a function outside the MultiJob definition?
You can do this
def j= {
parameters {
propertiesFile('my1.properties')
}
}
multiJob('example') {
steps {
phase('First') {
phaseJob('JobZ', j)
}
phase('Second') {
phaseJob('JobA', j)
phaseJob('JobB')
phaseJob('JobC')
}
}
}
Which you can use 'j'. The closure syntax outside the parameters is syntactic sugar and the method call assumes the closure is in fact the last parameter
Output from the job dsl playground
<com.tikal.jenkins.plugins.multijob.MultiJobProject plugin='jenkins-multijob-plugin#1.8'>
<actions></actions>
<description></description>
<keepDependencies>false</keepDependencies>
<properties></properties>
<scm class='hudson.scm.NullSCM'></scm>
<canRoam>true</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers class='vector'></triggers>
<concurrentBuild>false</concurrentBuild>
<builders>
<com.tikal.jenkins.plugins.multijob.MultiJobBuilder>
<phaseName>Second</phaseName>
<continuationCondition>SUCCESSFUL</continuationCondition>
<phaseJobs>
<com.tikal.jenkins.plugins.multijob.PhaseJobsConfig>
<jobName>JobZ</jobName>
<currParams>true</currParams>
<exposedSCM>true</exposedSCM>
<disableJob>false</disableJob>
<killPhaseOnJobResultCondition>FAILURE</killPhaseOnJobResultCondition>
<configs>
<hudson.plugins.parameterizedtrigger.FileBuildParameters>
<propertiesFile>my1.properties</propertiesFile>
<failTriggerOnMissing>false</failTriggerOnMissing>
</hudson.plugins.parameterizedtrigger.FileBuildParameters>
</configs>
</com.tikal.jenkins.plugins.multijob.PhaseJobsConfig>
</phaseJobs>
</com.tikal.jenkins.plugins.multijob.MultiJobBuilder>
<com.tikal.jenkins.plugins.multijob.MultiJobBuilder>
<phaseName>Third</phaseName>
<continuationCondition>SUCCESSFUL</continuationCondition>
<phaseJobs>
<com.tikal.jenkins.plugins.multijob.PhaseJobsConfig>
<jobName>JobA</jobName>
<currParams>true</currParams>
<exposedSCM>true</exposedSCM>
<disableJob>false</disableJob>
<killPhaseOnJobResultCondition>FAILURE</killPhaseOnJobResultCondition>
<configs>
<hudson.plugins.parameterizedtrigger.FileBuildParameters>
<propertiesFile>my1.properties</propertiesFile>
<failTriggerOnMissing>false</failTriggerOnMissing>
</hudson.plugins.parameterizedtrigger.FileBuildParameters>
</configs>
</com.tikal.jenkins.plugins.multijob.PhaseJobsConfig>
<com.tikal.jenkins.plugins.multijob.PhaseJobsConfig>
<jobName>JobB</jobName>
<currParams>true</currParams>
<exposedSCM>true</exposedSCM>
<disableJob>false</disableJob>
<killPhaseOnJobResultCondition>FAILURE</killPhaseOnJobResultCondition>
<configs class='java.util.Collections$EmptyList'></configs>
</com.tikal.jenkins.plugins.multijob.PhaseJobsConfig>
<com.tikal.jenkins.plugins.multijob.PhaseJobsConfig>
<jobName>JobC</jobName>
<currParams>true</currParams>
<exposedSCM>true</exposedSCM>
<disableJob>false</disableJob>
<killPhaseOnJobResultCondition>FAILURE</killPhaseOnJobResultCondition>
<configs class='java.util.Collections$EmptyList'></configs>
</com.tikal.jenkins.plugins.multijob.PhaseJobsConfig>
</phaseJobs>
</com.tikal.jenkins.plugins.multijob.MultiJobBuilder>
</builders>
<publishers></publishers>
<buildWrappers></buildWrappers>
</com.tikal.jenkins.plugins.multijob.MultiJobProject>
I am using the Job DSL to define a job that requires multiple maven steps to be run. This is an example:
def mavenInst = 'maven-3x'
job('test') {
steps{
maven {
mavenInstallation(mavenInst)
goals('fuu')
}
maven {
mavenInstallation(mavenInst)
goals('bar')
}
// more steps of the same form.
maven {
mavenInstallation(mavenInst)
goals('fuu bar')
}
}
}
So, much of code is repeated quite often.
Is it possible to extract the respective parts of the job description and call them from within the Job DSL? I imagine something like this:
def mavenInst = 'maven-3x'
job('test') {
steps{
myCustomStep('fuu')
myCustomStep('bar')
// more steps of the same form.
myCustomStep('fuu bar')
}
}
This would result in significantly less code and would be easier to change in the future.
I have read that the steps need some sort of context but I can not figure out how to do it. I tried to extract the block into a configure closure as this:
def fuubar = { it ->
mavenInstallation(mavenInst)
goals('fuu bar')
}
But when I call the element with configure fuubar, nothing is shown in the resulting job configure.xml.
Any help would be appreciated.
I would think you can do this
job('test') {
steps {
maven {
mavenInstallation('maven-3x')
goals('fuu')
goals('bar')
goals('fuu bar')
}
}
}
based on the excellent help
and also in the dsl playground
which gives you this
<!-- 1. test -->
<project>
<actions></actions>
<description></description>
<keepDependencies>false</keepDependencies>
<properties></properties>
<scm class='hudson.scm.NullSCM'></scm>
<canRoam>true</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers class='vector'></triggers>
<concurrentBuild>false</concurrentBuild>
<builders>
<hudson.tasks.Maven>
<targets>fuu bar fuu bar</targets>
<mavenName>maven-3x</mavenName>
<jvmOptions></jvmOptions>
<usePrivateRepository>false</usePrivateRepository>
</hudson.tasks.Maven>
</builders>
<publishers></publishers>
<buildWrappers></buildWrappers>
</project>
EDIT
Rereading your question it seems this is an example.
The above could also be written
def goal_names = ['fuu', 'bar', 'fuu bar']
job('test') {
steps {
maven {
mavenInstallation('maven-3x')
goal_names.each { goal ->
goals(goal)
}
}
}
}
EDIT 2 to use separate steps
def goal_names = ['fuu', 'bar', 'fuu bar']
job('test') {
steps {
goal_names.each { goal ->
maven {
mavenInstallation('maven-3x')
goals(goal)
}
}
}
}
XML
<!-- 1. test -->
<project>
<actions></actions>
<description></description>
<keepDependencies>false</keepDependencies>
<properties></properties>
<scm class='hudson.scm.NullSCM'></scm>
<canRoam>true</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers class='vector'></triggers>
<concurrentBuild>false</concurrentBuild>
<builders>
<hudson.tasks.Maven>
<targets>fuu</targets>
<mavenName>maven-3x</mavenName>
<jvmOptions></jvmOptions>
<usePrivateRepository>false</usePrivateRepository>
</hudson.tasks.Maven>
<hudson.tasks.Maven>
<targets>bar</targets>
<mavenName>maven-3x</mavenName>
<jvmOptions></jvmOptions>
<usePrivateRepository>false</usePrivateRepository>
</hudson.tasks.Maven>
<hudson.tasks.Maven>
<targets>fuu bar</targets>
<mavenName>maven-3x</mavenName>
<jvmOptions></jvmOptions>
<usePrivateRepository>false</usePrivateRepository>
</hudson.tasks.Maven>
</builders>
<publishers></publishers>
<buildWrappers></buildWrappers>
</project>
I managed to tackle that since I got similar issue and I wanted to have reusable methods with customization. I am not sure whether it is possible to encapsulate multiples steps in a method but you can encapsulate closure like this:
Closure runInLatestInstallation(String moduleName, String mavenGoals) {
return {
rootPOM("${moduleName}/pom.xml")
goals(mavenGoals)
mavenInstallation('Latest')
}
}
and you can call it like this:
maven runInLatestInstallation(moduleName, 'versions:update-parent')