Jenkins is an automation server for building, deploying and automating software deployment and test.
It can be useful, to read in results in OpenHAB, maybe you want to turn on the candy maker when all tests pass?
Architecture
Jenkins provides a JSON interface with all / specialized test results we can read in.
I use a Item to store raw JSON string, and if this changes (= at least one test result changed), I trigger a rule to parse the values.
OpenHAB Prerequisites
OpenHAB: Version 2.3.0 or newer (could be adapted to older versions by not using Units Of Measurement in items definition)
Bindings: http1
Transformations: RegEx, Map
OpenHAB Configuration
rules/jenkins.rules
rule "Update Jenkins Status"
when
Item Debug_Trigger_Jenkins_Update changed to ON or
Item Jenkins_json changed
then
var jenkinsJobsCountSuccessful = 0
var jenkinsJobsCountFailed = 0
var jenkinsJobsCount = 0
//logInfo("jenkins.rules", "Update Jenkins Status rule triggered")
jenkinsJobsCount = Integer.parseInt(transform("JSONPATH", "$.jobs.length()", Jenkins_json.state.toString))
//logInfo("jenkins.rules", "found " + jenkinsJobsCount + " jobs")
val currentJob = 0
val currentJobResult_string = ""
val currentJobResult_integer = 0
try {
while (currentJob < jenkinsJobsCount) {
currentJobResult_string = transform("JSONPATH", "$.jobs[" + currentJob + "].color", Jenkins_json.state.toString)
currentJobResult_integer = transform("MAP", "jenkins.map", currentJobResult_string)
//logInfo("jenkins.rules", "Job " + currentJob + " result: " + currentJobResult_string + " => " + currentJobResult_integer)
// map transforms to strings, so compare with strings
if(currentJobResult_integer == "1") {
jenkinsJobsCountSuccessful += 1
}
if(currentJobResult_integer == "0") {
jenkinsJobsCountFailed += 1
}
currentJob += 1
}
}
catch(Throwable t) {
logError("jenkins.rules", "Some bad stuff happened in my rule: " + T.toString)
}
finally {
Jenkins_Successful_Percent.postUpdate(jenkinsJobsCountSuccessful * 100.0 / (jenkinsJobsCountSuccessful + jenkinsJobsCountFailed))
Jenkins_Job_Count.postUpdate(jenkinsJobsCount)
Jenkins_Job_Failed.postUpdate(jenkinsJobsCountFailed)
Jenkins_Job_Successful.postUpdate(jenkinsJobsCountSuccessful)
logInfo("jenkins.rules", "found " + jenkinsJobsCount + " jobs, " + jenkinsJobsCountSuccessful + " of them successful (" + Jenkins_Successful_Percent.state.toString + ")")
}
if(Debug_Trigger_Jenkins_Update.state == ON) { Debug_Trigger_Jenkins_Update.postUpdate(OFF) }
end
This rule depends on:
services/http.cfg
jenkinsCache.url=https://amplab.cs.berkeley.edu/jenkins/api/json
jenkinsCache.updateInterval=60000
Use your own Jenkins URL here.
This can be the main URL to Jenkins or the URL of a view (each appended with api/json
). Caution: URL of a view changes when view name gets changed!
items/jenkins.items
Switch Debug_Trigger_Jenkins_Update
String Jenkins_json "Raw JSON Value of Jenkins result" { http="<[jenkinsCache:60000:REGEX((.*))]" }
Number Jenkins_Job_Count "Jenkins Job Count [%s]"
Number Jenkins_Job_Successful "Jenkins Job Successful [%s]"
Number Jenkins_Job_Failed "Jenkins Job Failed [%s]"
Number:Dimensionless Jenkins_Successful_Percent "Jenkins Successful Jobs [%.2f %%]"
I use REGEX((.*))
transformation to put all content into the string. Currently there’s no other solution for that.
transform/jenkins.map
aborted=-1
aborted_anime=-1
blue=1
blue_anime=1
disabled=-1
disabled_anime=-1
grey=-1
grey_anime=-1
notbuilt=-1
notbuilt_anime=-1
red=0
red_anime=0
yellow=0
yellow_anime=0
I just care for good (green/blue) and bad (red) tests, so I map it accordingly. Could be more detailed if needed.
Have fun
Questions and suggestions for improvement are welcome!