Mark the logs that carry a failure line on the artifact index

The artifact index listed the stored logs as bare file names, so a red build
gave no hint which of build.log, build.stdout.log and build.stderr.log actually
explains it — with stdout and stderr stored separately, the failure is usually
in only some of them.

Each log of a non-green build is now scanned for an upper-case FAILED/FAILURE,
which covers BUILD FAILED, Maven's BUILD FAILURE and Gradle's per-test
"SomeTest > works() FAILED"; lower-case prose does not count. The scan streams
line by line with an early exit and reads ISO-8859-1, so no byte sequence of a
build log can fail to decode. Logs of a successful build are not scanned at all
— that saves reading megabytes per page view and avoids an alarming badge on a
green build whose log mentions a deliberately failing sub-build.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
mhoennig
2026-08-11 10:11:45 +02:00
co-authored by Claude
parent cff365767e
commit 021d97eca8
5 changed files with 96 additions and 9 deletions
+4 -2
View File
@@ -50,8 +50,10 @@
<h2>Logs</h2>
<ul th:if="${!#lists.isEmpty(logs)}">
<li th:each="log : ${logs}">
<a th:href="${filesBase} + '/' + ${log}" target="_blank"
rel="noopener noreferrer" th:text="${log}">build.log</a>
<a th:href="${filesBase} + '/' + ${log.name}" target="_blank"
rel="noopener noreferrer" th:text="${log.name}">build.log</a>
<span th:if="${log.failed}" class="status status-failed"
title="this log contains the build tool's failure line">failed</span>
</li>
</ul>
<p th:if="${#lists.isEmpty(logs)}" class="muted">