Jenkins add Git Behaviors using groovy scripts - jenkins

I'm creating my Jenkins instance using groovy scripts because I'm automating the Jenkins creation process. I create this script:
/* Adds a multibranch pipeline job to Jenkins */
import hudson.model.*
import hudson.util.PersistedList
import jenkins.*
import jenkins.branch.*
import jenkins.model.*
import jenkins.model.Jenkins
import jenkins.plugins.git.*
import com.cloudbees.hudson.plugins.folder.computed.PeriodicFolderTrigger
import org.jenkinsci.plugins.workflow.multibranch.*
// Create job
def env = System.getenv()
Jenkins jenkins = Jenkins.instance
String jobName = "Job"
String jobScript = "Jenkinsfile"
def job = jenkins.getItem(jobName)
// Create the folder if it doesn't exist
if (job == null) {
job = jenkins.createProject(WorkflowMultiBranchProject.class, jobName)
}
job.getProjectFactory().setScriptPath(jobScript)
// Add git repo
String id = null
String remote = env.CODE_COMMIT_URL
String includes = "*"
String excludes = ""
boolean ignoreOnPushNotifications = false
GitSCMSource gitSCMSource = new GitSCMSource(id, remote, null, includes, excludes, ignoreOnPushNotifications)
BranchSource branchSource = new BranchSource(gitSCMSource)
// Remove and replace?
PersistedList sources = job.getSourcesList()
sources.clear()
sources.add(branchSource)
job.addTrigger(new PeriodicFolderTrigger("1m"))
and paste it at $JENKINS_HOME/ref/init.groovy.d/. When I start Jenkins, by job was already created. Besides that, I need to add some Git Behaviors to my job and I'd like to know if is there a way to add Git Behaviors using groovy script?
My Git after created:
Git behaviors I'd like to add at initialization (Discover tags, Check out to matching local branch, Custom user name/e-mail address)
Thank you!

I think what you want is managed through traits (I haven't actually tried this):
import jenkins.plugins.git.traits.*
def traits = []
// Add your traits...
traits.add(new TagDiscoveryTrait())
traits.add(new LocalBranchTrait())
gitSCMSource.setTraits(traits)

Related

Trigger Jenkins job on same node than parent with Groovy

In a Jenkins job, I want to trigger another Jenkins job from a Groovy script :
other_job.scheduleBuild();
But other_job is not launched on the same node than the parent job. How can I modify my script to launch other_job on the same node than the parent job ?
I used to do that with the "Trigger/call builds on other project" and "NodeLabel Parameter" plugins but I would like now to do that inside a script.
Firstly, check Restrict where this project can be run option in 'other_job' configuration - you must specify the same node name there.
Then, this should work:
import hudson.model.*
def job = Hudson.instance.getJob('other_job')
job.scheduleBuild();
If you don't want to use this option in your 'other_job', then you can use NodeLabel Parameter Plugin (which you already used) and pass the NodeLabel parameter to downstream job.
In this case, see example from Groovy plugin page how to start another job with parameters (you need to use NodeParameterValue instead of StringParameterValue):
def job = Hudson.instance.getJob('MyJobName')
def anotherBuild
try {
def params = [
new StringParameterValue('FOO', foo),
]
def future = job.scheduleBuild2(0, new Cause.UpstreamCause(build), new ParametersAction(params))
println "Waiting for the completion of " + HyperlinkNote.encodeTo('/' + job.url, job.fullDisplayName)
anotherBuild = future.get()
} catch (CancellationException x) {
throw new AbortException("${job.fullDisplayName} aborted.")
}
println HyperlinkNote.encodeTo('/' + anotherBuild.url, anotherBuild.fullDisplayName) + " completed. Result was " + anotherBuild.result
If it's not working, probably the issue is with node restrictions (e.g., there is only one executor for the node).
NOTE: I prefer to use Jenkins pipelines for job configurations. It allows you to store your build configs in Jenkinsfiles which can be loaded from repository (e.g., from GitLab). See example of triggering job with NodeParameterValue.
Based on the answer of biruk1230, here is a full solution :
import hudson.model.*;
import jenkins.model.Jenkins
import java.util.concurrent.*
import hudson.AbortException
import org.jvnet.jenkins.plugins.nodelabelparameter.*
def currentBuild = Thread.currentThread().executable
current_node = currentBuild.getBuiltOn().getNodeName()
def j = Hudson.instance.getJob('MyJobName')
try {
def params = [
new NodeParameterValue('node', current_node, current_node),
]
def future = j.scheduleBuild2(0, new Cause.UpstreamCause(build), new ParametersAction(params))
println "Waiting for the completion of " + j.getName()
anotherBuild = future.get()
} catch (CancellationException x) {
throw new AbortException("aborted.")
}

Groovy Script to add new phase job to multi-job in Jenkins

For the already available multi-job in jenkins, need to add new phase jobs using Groovy Scripting. I have written the following groovy code which adds up an already existing job p25_deploy-1.
This code is working to create the multi-job but the phase job is not showing as mapped in the Jenkins UI. Where as if I see it config.xml, its created properly as expected except a tag <killPhaseOnJobResultCondition>. Not sure why the phase job is not mapped properly?
import jenkins.model.*
import hudson.model.*
import com.tikal.jenkins.plugins.multijob.*
import com.tikal.jenkins.plugins.multijob.PhaseJobsConfig.*
import com.tikal.jenkins.plugins.multijob.PhaseJobsConfig.KillPhaseOnJobResultCondition.*
import java.lang.String.*
import hudson.model.Descriptor;
import hudson.tasks.Builder;
def jenkinsInstance = jenkins.model.Jenkins.instance
def templateJobName = 'profile_p25'
def templateJob = jenkinsInstance.getJob(templateJobName)
// get MultiJob BuildPhases and clone each PhaseJob
builders = templateJob.getBuilders();
builders.each { b ->
if (b instanceof MultiJobBuilder){
def pj = b.getPhaseJobs()
hudson.model.Describable p1 = new PhaseJobsConfig("p25_deploy-1",null,
true,PhaseJobsConfig.KillPhaseOnJobResultCondition NEVER,null,false,false,null,0,false,true,null,false,false)
pj.add(p1)
}
}
templateJob.save()
// update dependencies
jenkinsInstance.rebuildDependencyGraph()
Any help will be really appreciated. Have tried many ways but was not able to figure out the problem with the script.
We can use DSL to create but I wanted it to be done in Groovy Scripting and moreover modify the existing job.
Blockquote
Yay! I am back with the answer for my question. Have tried this since very long time. Finally am able to make it though. I was aware that solution would be really simple but not able to figure out the hack of it.
import jenkins.model.*
import hudson.model.*
import com.tikal.jenkins.plugins.multijob.*
import com.tikal.jenkins.plugins.multijob.PhaseJobsConfig.*
import com.tikal.jenkins.plugins.multijob.PhaseJobsConfig.KillPhaseOnJobResultCondition.*
import java.lang.String.*
import hudson.model.Descriptor
import hudson.tasks.Builder
def jenkinsInstance = jenkins.model.Jenkins.instance
def templateJobName = 'profile_p25'
def templateJob = jenkinsInstance.getJob(templateJobName)
// get MultiJob BuildPhases and clone each PhaseJob
builders = templateJob.getBuilders();
builders.each { b -> if (b instanceof MultiJobBuilder)
{ def pj =
b.getPhaseJobs()
hudson.model.Describable newphase = new
PhaseJobsConfig(deploys[i],null,
true,null,null,false,false,null,0,false,false,"",false,false)
newphase.killPhaseOnJobResultCondition = 'NEVER'
pj.add(newphase)
}
}
templateJob.save()

Set StashNotifier with Groovy

I am trying to add the StashNotifier configuration to Jenkins via Groovy
import jenkins.model.*;
import org.jenkinsci.plugins.stashNotifier.*
def instance = Jenkins.getInstance()
def bitbucket = instance.getDescriptor(StashNotifier)
println "--> configure Stash Notifier..."
def bitBucketNotifier = new StashNotifier (
"https://servername:8443", //stashServerBaseUrl
"user", //credentialsId
false, //ignoreUnverifiedSSLPeer
"", //commitSha1
false, //includeBuildNumberInKey
"", //projectKey
false, //prependParentProjectKey
false //disableInprogressNotification
)
bitbucket.save()
println "--> configure Stash Notifier... done"
The xml configuration I am trying to implement is
<?xml version='1.0' encoding='UTF-8'?>
<org.jenkinsci.plugins.stashNotifier.StashNotifier_-DescriptorImpl plugin="stashNotifier#1.11.6">
<credentialsId>user</credentialsId>
<stashRootUrl>https://servername:8443/</stashRootUrl>
<ignoreUnverifiedSsl>false</ignoreUnverifiedSsl>
<includeBuildNumberInKey>false</includeBuildNumberInKey>
<prependParentProjectKey>false</prependParentProjectKey>
<disableInprogressNotification>false</disableInprogressNotification>
</org.jenkinsci.plugins.stashNotifier.StashNotifier_-DescriptorImpl>
I am new to Java and groovy, but I cannot get this to work. I feel I am close, probably missing one or two little bits.
I am trying to get Jenkins to configure upon start-up and then reconfigure itself if any changes are made to core integrations. In this case, the BitBucket server won't change but if users do make the change to point at something else, Jenkins is reconfigured to point at the correct thing
#flue42 has a great answer, though going through the JSON and FormData is a bit tough to follow. Instead you can simply write the values to their respective properties on the object and save it.
If you happened to have multiple Stash servers you wanted to notify (not suppported at the global configuration level), you'll need to override the global setting on a per job basis, see my other answer with the skeleton of doing it using the Job DSL plugin.
Perhaps the most annoying part of looking at this to implement myself was in the code it references stashServerBaseUrl (as you noted in your comment) but then the required name in the Groovy/form is stashRootUrl. The place to find the right names is right around here
#!groovy
import jenkins.model.*;
import org.jenkinsci.plugins.stashNotifier.*;
String url = 'https://stashblablablabla';
String credentials = '01111111-e222-3333-eeff-4f4444e44bc4';
def j = Jenkins.getInstance();
def stash = instance.getDescriptor(StashNotifier)
stash.stashRootUrl = url //stashServerBaseUrl
stash.credentialsId = credentials //credentialsId
stash.ignoreUnverifiedSsl = false //ignoreUnverifiedSSLPeer
stash.includeBuildNumberInKey = false //includeBuildNumberInKey
stash.projectKey = "" //projectKey
stash.prependParentProjectKey = false //prependParentProjectKey
stash.disableInprogressNotification = false //disableInprogressNotification
stash.save()
I've done something like that :
#!groovy
import jenkins.model.*;
import org.jenkinsci.plugins.*;
import net.sf.json.JSONObject;
String url = 'https://stashblablablabla';
String credentials = '01111111-e222-3333-eeff-4f4444e44bc4';
def j = Jenkins.getInstance();
def stash = j.getExtensionList(
stashNotifier.StashNotifier.DescriptorImpl.class)[0];
def formData = [
stashRootUrl: url,
credentialsId: credentials,
ignoreUnverifiedSsl: false,
includeBuildNumberInKey: false,
prependParentProjectKey: false,
disableInprogressNotification: false,
considerUnstableAsSuccess: false
] as JSONObject;
stash.configure(null, formData);
j.save();
I've figured that solution out reading that:
https://github.com/jenkinsci/stashnotifier-plugin/blob/release/1.x/src/main/java/org/jenkinsci/plugins/stashNotifier/StashNotifier.java
https://github.com/samrocketman/jenkins-bootstrap-slack/blob/master/scripts/configure-slack.groovy
It appears to be working in my test platform.
If you are looking to do it via Job DSL you can use this example from the Job DSL repo.
// notify Stash using the global Jenkins settings
job('example-1') {
publishers {
stashNotifier()
}
}
// notify Stash using the global Jenkins settings and sets keepRepeatedBuilds to true
job('example-2') {
publishers {
stashNotifier {
keepRepeatedBuilds()
}
}
}
https://github.com/jenkinsci/job-dsl-plugin/blob/master/job-dsl-core/src/main/docs/examples/javaposse/jobdsl/dsl/helpers/publisher/PublisherContext/stashNotifier.groovy

Adding Global Password to Jenkins with init.groovy

How can I add a global passwords to Jenkins through the init.groovy that runs at startup?
To be clear, in the Manage Jenkins -> Configure Jenkins page, there is a section titled "Global Passwords". I would like to add entries in that section via Groovy code during the startup of Jenkins.
I am trying to provision my jenkins environment through groovy code by using the init.groovy. I need to add global passwords through the EnvInject plugin. I can successfully add path to a file for the same plugin using this code:
def instance = Jenkins.getInstance()
DescribableList<NodeProperty<?>, NodePropertyDescriptor> globalNodeProperties =
instance.getGlobalNodeProperties();
globalNodeProperties.add(
new EnvInjectNodeProperty(false, "/var/lib/jenkins/secret.properties")
);
However, I am failing to understand the mechanics needed to programmatically add global passwords.
Here is the code example that should work. It seems that save() method also adds it to GlobalNodeProperties, so you don't have to add to that collection manually.
import jenkins.model.*
import hudson.util.*
import hudson.slaves.NodeProperty
import hudson.slaves.NodePropertyDescriptor
import org.jenkinsci.plugins.envinject.*
def instance = Jenkins.getInstance()
DescribableList<NodeProperty<?>, NodePropertyDescriptor> globalNodeProperties
= instance.getGlobalNodeProperties();
envInjectNodeProperty= new EnvInjectNodeProperty(false, "/var/lib/jenkins/secret.properties"
propDescriptor = envInjectNodeProperty.getDescriptor()
//password entry
def passEntry = new EnvInjectGlobalPasswordEntry("some_username", "password")
//password entries list, add you global password here
List<EnvInjectGlobalPasswordEntry> envInjectGlobalPasswordEntriesList= [passEntry];
propDescriptor.envInjectGlobalPasswordEntries =
envInjectGlobalPasswordEntriesList.toArray(
new EnvInjectGlobalPasswordEntry[envInjectGlobalPasswordEntriesList.size()]
);
propDescriptor.save();
https://github.com/jenkinsci/envinject-plugin/tree/master/src/main/java/org/jenkinsci/plugins/envinject
I did not try this plugin, but there is a class : EnvInjectGlobalPasswordEntry
i guess it could be like this:
globalNodeProperties.add(
new EnvInjectGlobalPasswordEntry("pass-name", "the-password")
);

How to get all branches/jobs of a multibranch pipeline job?

Is there a way to get the names of all branches that the scan of a multibranch pipeline job has gathered?
I would like to set up a nightly build with dependencies on existing build jobs and therefore need to check if the multibranch jobs contain some certain branches. An other way would be to check for an existing job.
I found a way by using the Jenkins API.
In case anyone else is having this question: here is my groovy solution:
(Critics and edits welcome)
import java.util.ArrayList
import hudson.model.*;
def ArrayList<String> call(String pipelineName) {
def hi = hudson.model.Hudson.instance;
def item = hi.getItemByFullName(pipelineName);
def jobs = item.getAllJobs();
def arr = new ArrayList<String>();
Iterator<?> iterator = jobs.iterator();
while (iterator.hasNext()) {
def job = iterator.next();
arr.add(pipelineName + "/" + job.name);
}
return arr;
}

Resources