Get parameters of Jenkins build by job name and build id - jenkins

I am using Jenkins Pipeline plugin and I need to get all parameters of particular build by its id and job name from other job.
So, basically i need something like this.
def job = JobRegistry.getJobByName(jobName)
def build = job.getBuild(buildId)
Map parameters = build.getParameters()
println parameters['SOME_PARAMETER']

I figured it out.
I can retrieve parameters like this
def parameters = Jenkins.instance.getAllItems(Job)
.find {job -> job.fullName == jobName }
.getBuildByNumber(buildId.toInteger())
.getAction(hudson.model.ParametersAction)
println parameters.getParameter('SOME_PARAMETER').value

I suggest you to review "Pipeline Syntax" in a pipeline job, at bottom of Pipeline plugin, and you can see Global Variable Reference, like docker/pipeline/env/etc.
So what you need, JOB_NAME / BUILD_ID is given in "env" list

Related

Select job as parameter in Jenkins (Declarative) Pipeline

I would like to set a parameter in Jenkins Declarative Pipeline enabling the user to select one of the jobs defined on Jenkins. Something like:
parameters {
choice(choices: getJenkinsJobs())
}
How can this be achieved?
Background info: I would like to implement a generic manual promotion job with the Pipeline, where the user would select a build number and the job name and the job would get promoted.
I dislike the idea of using the input step as it prevents the job from completing and I can't get e.g. the junit reports on tests.
You can iterate over all existing hudson.model.Job instances and get their names. The following should work
#NonCPS
def getJenkinsJobs() {
Jenkins.instance.getAllItems(hudson.model.Job)*.fullName.join('\n')
}
pipeline {
agent any
parameters {
choice(choices: getJenkinsJobs(), name: 'JOB')
}
//...
}
Use http://wiki.jenkins-ci.org/display/JENKINS/Extended+Choice+Parameter+plugin
and use basic groovy script as a input.
Refer the below URL for how to list the build/jobs.
https://themettlemonkey.wordpress.com/2013/01/29/jenkins-build-number-drop-down/

How to trigger a different jobs in a master job

I have a job which contains a field of type string parameter (called JOB_NAME), in this string parameter, I will just fill it with another job name.
in the same job, I created "trigger/call builds on another project", in the latest, I will just provide the $JOB_NAME but it is not working.
My second question is how to fill $JOB_NAME field with some existing job using regular expresion or something else.
Can someone provide me clear steps, I am not that expert in Jenkins.
Thanks a lot
You can use Groovy Postbuild Plugin to achieve this.
Once you install the plugin, go to Post-build Actions and choose Groovy Postbuild option and add the following script to it.
Then, whenever you run your job it will ask for JOB_NAME as you have defined it as a parameter in your job and whatever project name you will enter, it will trigger that job in the downstream.
import hudson.model.*
import jenkins.model.*
def build = Thread.currentThread().executable
def jobPattern = manager.build.buildVariables.get("JOB_NAME")
def matchedJobs = Jenkins.instance.items.findAll { job ->
job.name =~ /$jobPattern/
}
matchedJobs.each { job ->
println "Triggering ${job.name} in the down stream...."
job.scheduleBuild(1, new Cause.UpstreamCause(build), new ParametersAction([ new StringParameterValue("PROPERTY1", "PROPERTY1VALUE"),new StringParameterValue("PROPERTY2", "PROPERTY2VALUE")]))
}

Set the pipeline name and description from Jenkinsfile

I am trying to do a poc of jenkins pipeline as code. I am using the Github organization folder plugin to scan Github orgs and create jobs per branch. Is there a way to explicitly define the names for the pipeline jobs that get from Jenkinsfile? I also want to add some descriptions for the jobs.
You need to use currentBuild like below. The node part is important
node {
currentBuild.displayName = "$yournamevariable-$another"
currentBuild.description = "$yourdescriptionvariable-$another"
}
Edit: Above one renames build where as Original question is about renaming jobs.
Following script in pipeline will do that(this requires appropriate permissions)
item = Jenkins.instance.getItemByFullName("originalJobName")
item.setDescription("This description was changed by script")
item.save()
item.renameTo("newJobName")
I'm late to the party on this one, but this question forced me in the #jenkins chat where I spent most of my day today. I would like to thank #tang^ from that chat for helping solve this in a graceful way for my situation.
To set the JOB description and JOB display name for a child in a multi-branch DECLARATIVE pipeline use the following steps block in a stage:
steps {
script {
if(currentBuild.rawBuild.project.displayName != 'jobName') {
currentBuild.rawBuild.project.description = 'NEW JOB DESCRIPTION'
currentBuild.rawBuild.project.setDisplayName('NEW JOB DISPLAY NAME')
}
else {
echo 'Name change not required'
}
}
}
This will require that you approve the individual script calls through the Jenkins sandbox approval method, but it was far simpler than anything else I'd found across the web about renaming the actual children of the parent pipeline. The last thing to note is that this should work in a Jenkinsfile where you can use the environment variables to manipulate the job items being set.
I tried to used code snippet from accepted answer to describe my Jenkins pipeline in Jenkinsfile. I had to wrap code snippet into function with #NonCPS annotation and use def for item variable. I have placed code snippet in root of Jenkinsfile, not in node section.
#NonCPS
def setDescription() {
def item = Jenkins.instance.getItemByFullName(env.JOB_NAME)
item.setDescription("Some description.")
item.save()
}
setDescription()

Call a jenkins job by using a variable for build the name

I try to launch a job from a parametrized trigger and I would compute the name from a given variable.
Is it possible to set in field :
Build Triggers Projects to build
a value like this
${RELEASE}-MAIN-${PROJECT}-LOAD_START
?
Unfortunately, this isn't possible with the Build Triggers. I looked for a solution for this "higher order build job" that would allow you to create a dynamic build name with a one of the parameterized build plugins, but I couldn't find one.
However, using the Groovy Postbuild Plugin, you can do a lot of powerful things. Below is a script that can be modified to do what you want. In particular, notice that it gets environmental variables using build.buildVariables.get("MY_ENV_VAR"). The environmental variable TARGET_BUILD_JOB specifies the name of the build job to build. In your case, you would want to build TARGET_BUILD_JOB using these two environmental variables:
build.buildVariables.get("RELEASE")
build.buildVariables.get("PROJECT")
The script is commented so that if you're not familiar with Groovy, which is based off Java, it should hopefully make sense!
import hudson.model.*
import hudson.model.queue.*
import hudson.model.labels.*
import org.jvnet.jenkins.plugins.nodelabelparameter.*
def failBuild(msg)
{
throw new RuntimeException("[GROOVY] User message, exiting with error: " + msg)
}
// Get the current build job
def thr = Thread.currentThread()
def build = thr?.executable
// Get the parameters for the current build job
// For ?:, see "Elvis Operator" (http://groovy.codehaus.org/Operators#Operators-ElvisOperator)
def currentParameters = build.getAction(ParametersAction.class)?.getParameters() ?:
failBuild("There are no parameters to pass down.")
def nodeName = build.getBuiltOnStr()
def newParameters = new ArrayList(currentParameters); newParameters << new NodeParameterValue("param_NODE",
"Target node -- the node of the previous job", nodeName)
// Retrieve information about the target build job
def targetJobName = build.buildVariables.get("TARGET_BUILD_JOB")
def targetJobObject = Hudson.instance.getItem(targetJobName) ?:
failBuild("Could not find a build job with the name $targetJobName. (Are you sure the spelling is correct?)")
println("$targetJobObject, $targetJobName")
def buildNumber = targetJobObject.getNextBuildNumber()
// Add information about downstream job to log
def jobUrl = targetJobObject.getAbsoluteUrl()
println("Starting downstream job $targetJobName ($jobUrl)" + "\n")
println("======= DOWNSTREAM PARAMETERS =======")
println("$newParameters")
// Start the downstream build job if this build job was successful
boolean targetBuildQueued = targetJobObject.scheduleBuild(5,
new Cause.UpstreamCause(build),
new ParametersAction(newParameters)
);
if (targetBuildQueued)
{
println("Build started successfully")
println("Console (wait a few seconds before clicking): $jobUrl/$buildNumber/console")
}
else
failBuild("Could not start target build job")

In Jenkins, how do builds know who requested them?

I need to pass the username of the requester of a build down to the script that is actually doing the work. Looking at the console output for a particular build, the first line is always "Started by user foo," so Jenkins is clearly keeping track of who triggered the build. So it should be possible to pass that information down to the job. The question is, how?
user30997
Please check out Jenkins Build User Vars plugin, it does what you need:
It is used to set following user build variables:
BUILD_USER – full name of user started build,
BUILD_USER_FIRST_NAME – first name of user started build,
BUILD_USER_LAST_NAME – last name of user started build,
BUILD_USER_ID – id of user started build.
The username isn't put in an easy-to-fetch environment variable, but you can get it using the xml (or json or python) api - as soon as you start a build, http://[jenkins-server]/job/[job-name]/[build-number]/api/xml is populated with details:
<freeStyleBuild>
<action>
<cause>
<shortDescription>Started by user foobar</shortDescription>
<userName>foobar</userName>
</cause>
</action>
<building>true</building>
[...]
I tried to use Jenkins Build User Vars plugin and notify a HipChat room that a build was started by a certain user, but BUILD_USER variable was not available to HipChat plugin, possibly because HipChat action happened before Build User Vars plugin injects the variable.
So I installed pre-scm-buildstep plugin and added:
]
// Inject environment variables using Groovy
import hudson.model.*
def build = Thread.currentThread().executable
def userCause = build.getCause(hudson.model.Cause$UserIdCause)
def userName = userCause?.userId ?: 'Jenkins'
def envVars = ['BUILD_USER': userName]
for (item in envVars) {
build.addAction(new ParametersAction([
new StringParameterValue(item.key, item.value)
]))
}
In your Job add "Execute system Groovy script":
def yourUserName = build.causes[0].userId
I managed to get it (on Jenkins 2.58):
currentBuild.getRawBuild().getCauses()[0].getUserId()
Of course you need to set permissions in Jenkins to be able to call these methods.
It's not always the 0th Cause object you are looking for, e.g. it may be another one if you replay another user's build (did not test this).
import os
import jenkinsapi.build
import jenkinsapi.jenkins
#Required Environment variables example:
#JENKINS_URL=http://jenkinsserver/
#JOB_NAME=TEST_GT
#BUILD_NUMBER=8
jenkins_inst = None
def get_jenkins_inst():
if jenkins_inst == None:
jenkins_url = os.environ['JENKINS_URL']
print("Connect to jenkins " + jenkins_url)
jenkins_inst = jenkinsapi.jenkins.Jenkins(jenkins_url)
return jenkins_inst
def get_jenkins_job():
jenkins_inst = get_jenkins_inst()
jenkins_job_name = os.environ['JOB_NAME']
print("Get jenkins job " + jenkins_job_name)
return jenkins_inst.get_job(jenkins_job_name)
def get_jenkins_user():
jenkins_job = get_jenkins_job()
jenkins_buildno = int(os.environ['BUILD_NUMBER'])
print("Get jenkins job build " + str(jenkins_buildno))
cur_build = jenkins_job.get_build(jenkins_buildno)
return cur_build.get_actions()['causes'][0]['userId']

Resources