Jenkins get user who aborted a build - jenkins

Is there a way to get the username when a build is aborted by a user?
Preferably using jenkins pipeline code.
When a build is aborted by a user, it logs:
Aborted by <username>
so I hope it is stored as a variable for a brief period.
Use case: username to be later used to inform the user itself or other users via email or other means of messaging.

It seems that a InterruptedBuildAction object is inserted in to the list of build action if a job is aborted. This object can be used to retrieve the user that aborted the build. I use the following function in my Jenkinsfile:
#NonCPS
def getAbortUser()
{
def causee = ''
def actions = currentBuild.getRawBuild().getActions(jenkins.model.InterruptedBuildAction)
for (action in actions) {
def causes = action.getCauses()
// on cancellation, report who cancelled the build
for (cause in causes) {
causee = cause.getUser().getDisplayName()
cause = null
}
causes = null
action = null
}
actions = null
return causee
}

In fact you can have this information with the REST API, just use the following URL with an appropriate build:
/api/json?tree=actions[causes[*]]&pretty=true
And you should be able to find the requested information under actions[causes], e.g.:
{
"_class" : "jenkins.model.InterruptedBuildAction",
"causes" : [
{
"_class" : "jenkins.model.CauseOfInterruption$UserInterruption",
"shortDescription" : "Aborted by some_user_name"
}
]
},

Unfortunately there seem to be no other solutions at the moment but to tweak Jenkin's code itself and a workaround.
Post-Build actions → Editable Email Notification → Triggers → Add Trigger → Aborted → Send To → Add → Requestor → → ... Jenkins Mailer Plugin:
Sends email to the user who initiated the build.
There's no Aborter to add.
http://<jenkins>/job/<project name>/lastBuild/api/xml shows:
...
<result>ABORTED</result>
...
but there's no info who aborted the build either.
A workaround could be to curl http://<jenkins>/job/<project name>/<build #> in a Post build task script and to grep for <p>Aborted by user username</p>.

Related

Jenkins Plugins update email notification

I need a script to get a list of jenkins plugins that need to be updated and send weekly email notification about them.
You can use the following script as a reference and build a Pipeline to send an Email.
// This cript prints all the installed plugins and if there are updates, the latest version available.
jenkins.model.Jenkins.getInstance().getUpdateCenter().getSites().each { site ->
site.updateDirectlyNow(hudson.model.DownloadService.signatureCheck)
}
hudson.model.DownloadService.Downloadable.all().each { downloadable ->
downloadable.updateNow();
}
def pluginList = new ArrayList(Jenkins.instance.pluginManager.plugins)
pluginList.sort { it.getShortName() }.each{ plugin ->
println ("${plugin.getDisplayName()} (${plugin.getShortName()}): ${plugin.getVersion()} : ${plugin.hasUpdate() ? plugin.getUpdateInfo().version : 'No Update'}")
}

How do I always get a user who triggered a job?

I have a code which displays on Slack user's mail who triggered a build:
def startedBy = "${currentBuild.getBuildCauses()[0].userId}#mycompany.com"
def message = \nJob started by: ${startedBy}"
return message
which gives on Slack:
Job started by: john.doe#mycompany.com
However, when same build is triggered by another build, I get:
Job started by: null#mycompany.com
because triggering build does not include userId class in "causes":
[[_class:hudson.model.Cause$UpstreamCause,
shortDescription:Started by upstream project "Production/myjob-starter" build number 3,
upstreamBuild:3,
upstreamProject:Production/myjob-starter,
upstreamUrl:job/Productionmyjob-starter/]]
On the other side, in UI there is a phrase:
originally caused by:
Started by user John Doe
My question is - how do I always get userId, no matter if build is triggered by another build or directly by a user?
Preferably, I would like to get userId, however Started by user John Doe - shortDescription would also be valid.
==================
EDIT: The solution was to install build-user-vars plugin which globally identifies user who triggered a job. Therefore groovy script looks like this:
def startedBy = "${env.BUILD_USER_ID}#mycompany.com"
def message = \nJob started by: ${startedBy}"
return message
and it prints userId no matter of build was started directly or by another build (triggered by a user)

Retrieve jenkins job builder credentials in groovy

I am trying to extract the username and password in jenkins groovy script who has initiated the build. I need these details to post comments on jira from my name.
So for eg.. I login into jenkins and start a job, then my login credentials should be used to post the comment on jira..
I tried alot of posts but didnt find anytihng related to my requirement.
Any help will be appreciated..
after few seconds of Googling, I found this script officially published by cloudbees.
So, as follows:
Jenkins.instance.getAllItems(Job).each{
def jobBuilds=it.getBuilds()
//for each of such jobs we can get all the builds (or you can limit the number at your convenience)
jobBuilds.each { build ->
def runningSince = groovy.time.TimeCategory.minus( new Date(), build.getTime() )
def currentStatus = build.buildStatusSummary.message
def cause = build.getCauses()[0] //we keep the first cause
//This is a simple case where we want to get information on the cause if the build was
//triggered by an user
def user = cause instanceof Cause.UserIdCause? cause.getUserId():""
//This is an easy way to show the information on screen but can be changed at convenience
println "Build: ${build} | Since: ${runningSince} | Status: ${currentStatus} | Cause: ${cause} | User: ${user}"
// You can get all the information available for build parameters.
def parameters = build.getAction(ParametersAction)?.parameters
parameters.each {
println "Type: ${it.class} Name: ${it.name}, Value: ${it.dump()}"
}
}
}
You will get the user ID of the user, which start the job, for sure you will not be able to get his credentials, at least not in the plain text.
Little explanation
//to get all jobs
Jenkins.instance.getAllItems(Job)
{...}
//get builds per job
def jobBuilds=it.getBuilds()
//get build cause
def cause = build.getCauses()[0] //we keep the first cause
//if triggered by an user get id, otherwise empty string
def user = cause instanceof Cause.UserIdCause? cause.getUserId():""

Trigger "perform maven release" of a jenkins job from another job

Looking for ways to trigger a "perform maven" release job from another jenkins job. It can be a rest api (or) a plugin that can do it. I saw posts about "trigger paramterized" plugin which can do this, but I cant see a way to do it . So I need real examples on how to try it.
Thanks!
This task has been open in Jenkin's Jira since July 2015 with no movement yet.
Since this is the case, I suggest using an HTTP POST to accomplish this task. To do this, you will need to do the following:
Install the HTTP Request Plugin
Create an httpUser (or use an existing one) with the appropriate Matrix Permissions and then grab its API Token Jenkins -> People -> httpUser -> Configure -> API Token -> Show API Token...
Jenkins -> Manage Jenkins -> Configure System -> HTTP Request -> Basic/Digest Authentication -> Add -> create a Global HTTP Authentication Key with the information from step 2
Create a "parent" job that will trigger other Jenkins job(s) via the M2-Release-Plugin and configure it as follows:
This build is parameterized
releaseVersion (Text Parameter)
developmentVersion (Text Parameter)
(add other parameters as required, look in the doSubmit method for details)
Build -> Add build step -> HTTP Request
URL (should have this format) = http://JenkinsServerName/job/JenkinsJobName/m2release/submit
HTTP mode = POST
Advanced...
Authorization -> Authenticate = select the Authenticate option created in step 3
Headers -> Custom headers -> Add
Header = Content-type
Value = application/x-www-form-urlencoded
Body -> Pass build params to URL? = Yes
Request body = (your parameters from step 5 and a json parameter object with any additional parameters required)
Response body in console? = Yes
These are the steps I followed to have one Jenkins job trigger an m2release on another job in my environment. Hopefully this helps others and should I lose my notes or memory, I can refer to this post as well.

How to know which user answered a Jenkins-Pipeline input step?

I have a Jenkinsfile script that tests for the possibility to perform an SVN merge and then asks the user for the permission to commit the merge.
I would like to know the username that answers the "input" step in order to write it into the commit message.
Is this possibile?
This is what hypothetically I would like to do:
outcome = input message: 'Merge trunk into branch?', ok: 'Merge'
echo "User that allowed merge: ${outcome.user}"
The input step got an optional submitterParameter, which allows to specify the key of the returned Map that should contain the user who's submitting the input dialog:
If specified, this is the name of the return value that will contain the ID of the user that approves this input.
The return value will be handled in a fashion similar to the parameters value.
Type: String
This looks then as follows:
def feedback = input(submitterParameter: 'submitter', ...)
echo "It was ${feedback.submitter} who submitted the dialog."
P.S: If anybody is interested in a full-fledged code snippet returning the user both for positive and negative feedback to the dialog (and timeout as well), I kindly point to our pipeline library.
It is not currently possible, for now only entry parameters are returned in the input step answer, as mentionned in source code :
// TODO: perhaps we should return a different object to allow the workflow to look up
// who approved it, etc?
switch (mapResult.size()) {
case 0:
return null; // no value if there's no parameter
case 1:
return mapResult.values().iterator().next();
default:
return mapResult;
}
If you'd like to restrict which user(s) can approve the input step, you can however use the submitter parameter, e.g. :
input message: 'Approve ?', submitter: 'authorized-submitter'
EDIT
Since January 2017 it is now possible to request additional parameters to be sent. Please see StephenKing answer above.
If you are not asking for any parameters on the input, then adding the submitterParameter kind of worked. It didn't add it as a parameter on the return object, instead, it turned the returned object into a string with the username in it.
def feedback = input(submitterParameter: 'submitter')
echo "It was ${feedback} who submitted the dialog."
You can do this for exceptions if you turn off the groovy-sandbox:
try {
'Deploy to production?'
node {
sh 'echo deploying'
}
} catch(e) {
def user = e.getCauses()[0].getUser()
echo "Production deployment aborted by:\n ${user}"
}

Resources