How do I discover the additional causes of my Jenkins build?
Asked Answered
P

2

12

When attempting to query a build using groovy, I call

myBuild.getCauses()

I can see in the interface of Jenkins (the build screen) that this build has two causes, a UserIdCause, and an UpstreamCause. However, when I interrogate the same build with the groovy above, I only get a single cause back, which is the UserIdCause. There must be some method of getting the UpstreamCause from the build, or it wouldn't be present in the user interface.

I am using the Build Pipeline plugin to manually trigger the builds.

Plutocracy answered 25/9, 2013 at 9:3 Comment(3)
I've since learned that the getActions() method on the Run gives you another angle to come at causes. I'll post a more complete answer to the question when my time limit has expired.Plutocracy
will be nice to post the sample causes in JSON/XMLFemme
I have the opposite problem: thr = Thread.currentThread(); build = thr?.executable; and then build.getCauses() returns only a single upstream cause. I'm using the Build Pipeline plugin to launch from manually, and want ti know which user clicked the build/rebuild icon but I can't get the UserId cause even though as you say it is shown in the Jenkins build screenDepilatory
F
7

Here is the working groovy code (I tried in jenkins script console) to use build.getAction

job = hudson.model.Hudson.instance.getItem("demo-job")
build = job.getLastBuild()

// get action first
def action = build.getAction(hudson.model.CauseAction.class)
// get the list of causes
for (cause in action.getCauses()) {
    println cause.getShortDescription()
}
// another way to find specific UpsteamCause directly
cause = action.findCause(hudson.model.Cause.UpstreamCause.class)
println cause.getUpstreamRun() 

See reference

  1. see build-pipeline-plugin how to add cause in code BuildPipelineView.java
  2. see the hudson.model.Cause API
Femme answered 27/6, 2015 at 14:34 Comment(0)
D
7

It appears that build.getCauses() does not get all causes, but only the causes of the first causeAction of build.getActions(hudson.model.CauseAction.class), probably by calling build.getAction(hudson.model.CauseAction.class)

Additional actions with their own cause can be found with:

def actions = build.getActions(hudson.model.CauseAction.class)

and so we need to review the causes of each of those actions, so instead of def causes = build.causes() we have

def causes = build.getActions(hudson.model.CauseAction.class)
             .collect{ it.getCauses() }.flatten()

and in my case that will return a list something like:

[ 05b8ef62-d071-11e8-b9db-9fd4e0aedf12/job/MyView/1238[11ef1ed2-d071-11e8-8c81-b71616102fe9/job/MyJob/4250[hudson.model.Cause$UserIdCause@2ddf7e3e]],
  hudson.model.Cause$UserIdCause@3337c79c ]

Where the first member represents the build pipeline plugin upstreamCause and the second member represents the user who manually triggered this build.

Certainly I wish the Build User Vars plugin would use the shallowest hudson.model.Cause$UserIdCause, and not from any upstream cause!

In like manner, there is no point in simply traversing the chain of cause.upstreamCauses because each upstream may have multiple causes.

Instead of recursing along cause.upstreamCauses, access upstreamRun's cause actions using:

cause.upstreamRun.getActions(hudson.model.CauseAction.class).collect{ it.getCauses() }.flatten()

Note:

build.getCause(hudson.model.Cause$UserIdCause) may return NULL where build.getCause(hudson.model.Cause$UpstreamCause) will succeed, even when the there exists an action from getActions() whose cause is Cause$UserIdCause, so presumably getCause also calls getAction() instead of getActions()

Depilatory answered 15/10, 2018 at 12:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.