Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting SubProject Builds via Jenkins API

I have a Jenkins project configured (I'll call it SuperJob here) to simply call several different other jenkins projects in order.

I would like to be able to find out the result of all the subprojects for a specific build number of this SuperJob through Jenkins API

Looking at the code posted HERE I am able to get the list of the specific projects configured in the SuperJob project from each build however I am not able to find a way to query what specific build number of each of these projects were run from a specific build of SuperJob.

For example, I would like to find out that "SuperJob build #5" triggered "MyJob build #3" and "OtherJob build #20" so I can aggregated and check the results for all of them.

I have tried all the Upstream and Downstream APIs including using the sub projects as an argument for therelationship ones but they all return empty or null.

I am guessing this is possible since Jenkins itself is able to show that information in the web ui which is coming from a plugin but I have not been able to find out how.

like image 390
Alexandre Thenorio Avatar asked Oct 13 '15 14:10

Alexandre Thenorio


2 Answers

I have the same problem, and currently the solution I use to find sub builds, is by parsing the console log of each build. the log contains the triggered jobs names, and the builds numbers (after they finished).

import hudson.console.ConsoleNote;
jenkins = Jenkins.getInstance()
jobName = "root-job-name"     //just an example
buildNumber = 123             //just an example
job = jenkins.getItem(jobName)
startBuild = job.getBuildByNumber(buildNumber)

//scanning the tree using BFS
list = []
visitedList = []
q = list as java.util.Queue
q<<startBuild
visitedList.add(startBuild)
while (!q.empty){
   node = q.poll()

  subjobs = getTriggeredBuildssByBuild(node) //see method bellow
  subjobs.each{ subj ->
      if (!(subj in visitedList)){
          visitedList.add(subj)
          q<<subj
      }
  }
}

//printing results
visitedList.each{
    println "Job name and build number: ${it}"
}


//parsing the log of the Run object to get sub builds triggered by it
def getTriggeredBuildssByBuild(def run){
    list =[]
    if (run != null && ((reader = run.getLogReader()) != null)) {

        BufferedReader bufferedReader = new BufferedReader(reader);

        for (String line = bufferedReader.readLine();
            line != null;
            line = bufferedReader.readLine()) {

            //strip off jenkins specific encoding
            line = ConsoleNote.removeNotes(line);
            matcher = line=~/Finished Build : #(\d+) of Job : (.*) with/
            if(matcher){
               foundJob = matcher[0][2]
               foundBuildNum = Integer.parseInt(matcher[0][1])
               foundBuild=jenkins.getItem(foundJob).getBuildByNumber(foundBuildNum)
               list.add(foundBuild)
            }
        }
    }
return list
}

A few notes:

  1. you will need to check that the regex I used is suitable for all of your cases, of course you can change it to a method that checks for a few other regex matches.
  2. In case you use multijob plugin, and all of your jobs are from that type, it is much more easier, since MultijobBuild has a getSubBuilds() which returns exactly what you want.
  3. I'm still looking for a better way to find sub builds triggered by a given build, especially if it can return builds in all states, finished or still building.
like image 92
Tidhar Klein Orbach Avatar answered Oct 10 '22 01:10

Tidhar Klein Orbach


If you have the Jenkins server URL, job name and job number, you can swap the values into a request like this:

https://<jenkins server URL>/view/all/job/<job name>/<job number>/api/json?pretty=true&tree=actions[triggeredBuilds[number,url,result]]

Which will give you a JSON response like this:

{
  "_class" : "hudson.model.FreeStyleBuild",
  "actions" : [
    {
      "_class" : "hudson.model.CauseAction"
    },
    {

    },
    {
      "_class" : "hudson.model.ParametersAction"
    },
    {

    },
    {
      "_class" : "hudson.plugins.git.util.BuildData"
    },
    {
      "_class" : "hudson.plugins.git.GitTagAction"
    },
    {

    },
    {
      "_class" : "hudson.plugins.parameterizedtrigger.BuildInfoExporterAction",
      "triggeredBuilds" : [
        {
          "_class" : "hudson.model.FreeStyleBuild",
          "number" : <subjob number>,
          "result" : "SUCCESS",
          "url" : "https://<jenkins server URL>/job/<subjob name>/<subjob number>/"
        },
        {
          "_class" : "hudson.model.FreeStyleBuild",
          "number" : <subjob number>,
          "result" : "SUCCESS",
          "url" : "https://<jenkins server URL>/job/<subjob name>/<subjob number>/"
        }
      ]
    },
    {

    },
    {

    },
    {

    }
  ]
}
like image 36
Daniel Samuels Avatar answered Oct 09 '22 23:10

Daniel Samuels