Files
werkator/src/main/resources/templates/artifact.html
T
mhoennigandClaude 021d97eca8 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>
2026-08-11 10:11:45 +02:00

82 lines
4.2 KiB
HTML

<!doctype html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<head th:replace="~{fragments :: head(${pageTitle})}"></head>
<body>
<main>
<h1 th:replace="~{fragments :: header(${pageTitle})}"></h1>
<div th:replace="~{fragments :: nav(${view})}"></div>
<article class="panel">
<p th:if="${permanentBranch != null}" class="muted">
Permanent link: this page always shows the latest green build of branch
<b th:text="${permanentBranch}">main</b> — every link on it stays valid across new builds.
<a th:href="${concreteUrl}">Open this specific build</a> instead.
</p>
<h2>Build</h2>
<ul th:if="${result != null}" class="build-facts">
<li>
<span th:class="'status status-' + ${result.status}" th:text="${result.status}">success</span>
</li>
<li>Branch:
<span class="branch link-tools">
<a th:if="${result.branchUrl != null}" th:href="${result.branchUrl}" target="_blank"
rel="noopener noreferrer" th:text="${result.branch}">main</a>
<span th:if="${result.branchUrl == null}" th:text="${result.branch}">main</span>
<button class="copy-button" type="button" th:attr="data-copy=${result.branch}"
title="Copy branch name" aria-label="Copy branch name"></button>
</span>
</li>
<li>Commit:
<span class="link-tools">
<code>
<a th:if="${result.commitUrl != null}" th:href="${result.commitUrl}" target="_blank"
rel="noopener noreferrer" th:text="${result.commitAbbrev}">0123abc</a>
<span th:if="${result.commitUrl == null}" th:text="${result.commitAbbrev}">0123abc</span>
</code>
<button class="copy-button" type="button" th:attr="data-copy=${result.commit}"
title="Copy full commit ID" aria-label="Copy full commit ID"></button>
</span>
</li>
<li>Started: <span th:text="${result.startedAt}">2026-07-07 12:00</span>
<th:block th:if="${result.duration != ''}">— Duration: <span th:text="${result.duration}">1:23</span></th:block>
</li>
<li th:if="${buildCommand != null}">Build command (as currently configured):<br>
<code th:text="${buildCommand}">./gradlew test</code>
</li>
</ul>
<p th:if="${result == null}" class="muted">
This build has no stored result anymore — only its artifact files remain.
</p>
<h2>Logs</h2>
<ul th:if="${!#lists.isEmpty(logs)}">
<li th:each="log : ${logs}">
<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">
No log files are stored for this build<th:block th:unless="${hasArtifacts}">
— the build has not finished yet, or its artifacts were pruned</th:block>.
</p>
<h2>Build Artifacts</h2>
<ul th:if="${!#lists.isEmpty(reportIndexes)}">
<li th:each="report : ${reportIndexes}">
<a th:href="${filesBase} + '/reports/' + ${report.path}" target="_blank"
rel="noopener noreferrer" th:text="'reports/' + ${report.path}">reports/tests/index.html</a>
<span th:if="${report.failures != null and report.failures > 0}" class="status status-failed"
th:text="${report.failures} + ' failed'">2 failed</span>
</li>
</ul>
<p th:if="${#lists.isEmpty(reportIndexes)}" class="muted">
No artifact directories were produced by this build.
</p>
</article>
</main>
<footer th:replace="~{fragments :: footer}"></footer>
<script src="/gittally.js"></script>
</body>
</html>