in core/src/main/java/hudson/model/Job.java [1237:1297]
private HealthReport getBuildStabilityHealthReport() {
// we can give a simple view of build health from the last five builds
int failCount = 0;
int totalCount = 0;
RunT i = getLastBuild();
RunT u = getLastFailedBuild();
if (i != null && u == null) {
// no failures, like ever
return new HealthReport(100, Messages._Job_BuildStability(Messages._Job_NoRecentBuildFailed()));
}
if (i != null && u.getNumber() <= i.getNumber()) {
SortedMap<Integer, ? extends RunT> runs = _getRuns();
if (runs instanceof RunMap) {
RunMap<RunT> runMap = (RunMap<RunT>) runs;
for (int index = i.getNumber(); index > u.getNumber() && totalCount < 5; index--) {
if (runMap.runExists(index)) {
totalCount++;
}
}
if (totalCount < 5) {
// start loading from the first failure as we counted the rest
i = u;
}
}
}
while (totalCount < 5 && i != null) {
switch (i.getIconColor()) {
case BLUE:
case YELLOW:
// failCount stays the same
totalCount++;
break;
case RED:
failCount++;
totalCount++;
break;
default:
// do nothing as these are inconclusive statuses
break;
}
i = i.getPreviousBuild();
}
if (totalCount > 0) {
int score = (int) ((100.0 * (totalCount - failCount)) / totalCount);
Localizable description;
if (failCount == 0) {
description = Messages._Job_NoRecentBuildFailed();
} else if (totalCount == failCount) {
// this should catch the case where totalCount == 1
// as failCount must be between 0 and totalCount
// and we can't get here if failCount == 0
description = Messages._Job_AllRecentBuildFailed();
} else {
description = Messages._Job_NOfMFailed(failCount, totalCount);
}
return new HealthReport(score, Messages._Job_BuildStability(description));
}
return null;
}