Say I have JobA
triggering JobB
which then triggers JobC
. I know I can do this to get the upstream job
def obj = currentBuild.rawBuild.getCause(Cause.UpstreamCause)
String upStreamJob = obj.getUpstreamProject()
So if this ran in JobC
, I'll get upStreamJob = JobB
, and if it ran in JobB
, upstreamJob = JobA
.
However, how can I code it so if I ran it in JobC
, I can ultimately get JobA
, which is the initial job trigger among the 3 jobs?
To achieve what you want you will need traverse the upstream causes of your build until you reach the build that started the chain.
The easiest way to do so is add a getUpstreamBuild
method to one of your utility shared libraries and then you can use it across all of your pipelines:
/**
* Get the last upstream build that triggered the current build
* @return Build object (org.jenkinsci.plugins.workflow.job.WorkflowRun) representing the upstream build
*/
@NonCPS
def getUpstreamBuild() {
def build = currentBuild.rawBuild
def upstreamCause
while (upstreamCause = build.getCause(hudson.model.Cause$UpstreamCause)) {
build = upstreamCause.upstreamRun
}
return build
}
You can then use this function as a base for other utility functions that can supply more info on the triggering build. For example:
/**
* Get the properties of the build Cause (the event that triggered the build)
* @param upstream If true (Default) return the cause properties of the last upstream job (If the build was triggered by another job or by a chain of jobs)
* @return Map representing the properties of the cause that triggered the current build.
*/
@NonCPS
def getCauseProperties(Boolean upstream = true) {
def build = upstream ? getUpstreamBuild() : currentBuild.rawBuild
return build.getCauses()[0].properties
}
/**
* Get the description of the build Cause (the event that triggered the build)
* @param upstream If true (Default) return the cause properties of the last upstream job (If the build was triggered by another job or by a chain of jobs)
* @return String representing the description of the cause that triggered the current build.
*/
@NonCPS
def getCauseDescription(Boolean upstream = true) {
return getCauseProperties(upstream).shortDescription
}
You can also use these function code directly in your pipeline if you want it for a single use.