jenkinsjenkins-pipeline

In a Jenkins pipeline, how can I get the upstream job of an upstream job in a chain of jobs?


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?


Solution

  • 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.