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.
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:
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>/"
}
]
},
{
},
{
},
{
}
]
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With