Files
werkator/docs/prs/2026-10-14-PR#160-home-builds-panel.md
claude-code f76fc59fef
werkator build succeeded after 02:56
werkator/deploy build succeeded after 00:20
The home page lists running, queued and failed builds, and its tiles are smaller (v1.43.0) (#160)
Co-authored-by: claude-code <claude-code@javagil.de>
2026-10-14 14:16:16 +02:00

233 lines
11 KiB
Markdown

# PR#160: The home page lists running, queued and failed builds, and its tiles are smaller
> **WARNING:** This document describes only the change applied in this PR.
> It may already be outdated once the next PR is merged.
> Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation.
## Problem
The home page has two panels: System and Repositories.
A repository card shows only its newest build and counts the running and failed ones.
To see which builds run, which wait and which failed, a reader has to open each repository's views.
Also, only three cards fit in one row on a desktop screen, so the mosaic grows tall quickly.
## Non-Goals
- No live log on the home page: a tile leads to the Current Builds view for that.
- No change to the repository cards' tags and tints: they keep counting as before.
- No build-definition key, so ADR 0010 is not touched.
- No new layout of the other pages: they only get wider.
## Specification
### Feature: the Builds panel on the home page
#### Background
- A run's *name* is its pool, `<branch>` or `<branch>@<build>`: one build definition on one branch.
- A *failure* is a run that ended `failed` or `timed_out`.
- A failure is *outdated* when its branch is gone or a newer run of its name ended with a verdict (PR#156).
#### Scenario#160.01: The panel shows the running builds first, then the queued ones, then the failures, at most five!
So that what happens now comes before what waits, and what waits before what is broken.
- **Given** running, queued and failed builds in several repositories
- **When** the home page shows the Builds panel
- **Then** the running builds come first, the one running longest first
- **and** then the queued builds, the one waiting longest first
- **and** then the failures, the newest first
- **and** the panel shows at most five builds
##### Verified by
- [BuildActivityUnitTest: running builds come first, then the queued ones, then the failures, at most five](../../src/test/kotlin/de/hoennig/werkator/server/BuildActivityUnitTest.kt)
#### Scenario#160.02: A failure whose name runs or waits again has no tile!
So that the panel does not show a failure twice, once as red and once as the build that answers it.
- **Given** a failure of a name
- **When** a newer run of the same name is running or queued
- **Then** the panel shows the newer run
- **and** not the failure
##### Verified by
- [BuildActivityUnitTest: a failure whose build definition runs or waits again has no tile of its own](../../src/test/kotlin/de/hoennig/werkator/server/BuildActivityUnitTest.kt)
#### Scenario#160.03: An outdated failure has no tile!
So that the panel shows only failures that still say how a branch stands.
- **Given** a failure
- **When** its branch is gone, or a newer run of its name ended with a verdict
- **Then** the failure has no tile
##### Verified by
- [BuildActivityUnitTest: an outdated failure has no tile](../../src/test/kotlin/de/hoennig/werkator/server/BuildActivityUnitTest.kt)
#### Scenario#160.04: A failure older than seven days has no tile!
So that the panel counts failures like the "failed" tag of the repository cards.
- **Given** a current failure
- **When** it started more than seven days ago
- **Then** it has no tile
##### Verified by
- [BuildActivityUnitTest: a failure older than seven days has no tile](../../src/test/kotlin/de/hoennig/werkator/server/BuildActivityUnitTest.kt)
#### Scenario#160.05: A failure followed only by a cancelled run keeps its tile!
So that cancelling a rebuild does not hide a failure nobody answered.
- **Given** a failure of a name
- **When** the only newer run of that name was cancelled
- **Then** the failure keeps its tile
##### Verified by
- [BuildActivityUnitTest: a failure followed only by a cancelled run keeps its tile](../../src/test/kotlin/de/hoennig/werkator/server/BuildActivityUnitTest.kt)
#### Scenario#160.06: A visitor sees a private repository's build counted and timed, but not named!
So that the panel keeps RFC 0003, D8: metadata for everyone, content only with the control token.
- **Given** a running build of a private repository
- **When** a visitor without the control token reads the home page or `GET /api/activity`
- **Then** the tile keeps the status and the times
- **and** the repository, the build name, the commit and the pull request are replaced
- **and** the tile leads nowhere
##### Verified by
- [BuildActivityUnitTest: a visitor sees a private repository's build counted and timed, but not named](../../src/test/kotlin/de/hoennig/werkator/server/BuildActivityUnitTest.kt)
- [ReposApiControllerRestTest: GET /api/activity answers the Builds panel's tiles as asked for by a visitor without the token](../../src/test/kotlin/de/hoennig/werkator/server/ReposApiControllerRestTest.kt)
- [UiHomeRestTest: a private build's tile is anonymous and leads nowhere](../../src/test/kotlin/de/hoennig/werkator/server/UiHomeRestTest.kt)
#### Scenario#160.07: The Builds panel stands above the Repositories panel!
So that the reader sees what happens before what each repository did last.
- **Given** builds for the panel
- **When** the home page renders
- **Then** the Builds panel stands above the Repositories panel
- **and** it shows one tile per build, in the order of the list
##### Verified by
- [UiHomeRestTest: the Builds panel stands above the Repositories, one tile per build](../../src/test/kotlin/de/hoennig/werkator/server/UiHomeRestTest.kt)
#### Scenario#160.08: A tile names the repository, the build and its commit!
So that a reader knows what a tile is about without opening it.
- **Given** a build of the panel
- **When** the home page renders its tile, first by the server and then by every poll
- **Then** the tile shows the repository, the status, the build name, its pull request, its commit and its start
##### Verified by
- [UiViewsUnitTest: a build tile names the repository, the build, its commit and its timing](../../src/test/kotlin/de/hoennig/werkator/server/UiViewsUnitTest.kt)
#### Scenario#160.09: A tile is tinted by its status!
So that what needs attention stands out, like on the repository cards.
- **Given** a build of the panel
- **When** the home page renders its tile
- **Then** a running tile is blue, a failed or timed-out one red, a queued one calm, a private one grey
##### Verified by
- [UiViewsUnitTest: a build tile's tint](../../src/test/kotlin/de/hoennig/werkator/server/UiViewsUnitTest.kt)
#### Scenario#160.10: The time of a running or queued build counts on!
So that the tile shows how long a build runs or waits without a new poll.
- **Given** a running or queued build of the panel
- **When** the home page shows its tile
- **Then** its time counts every second, a queued one italic
##### Verified by
- [UiHomeRestTest: a running or queued tile carries what the ticker counts from, a queued one italic](../../src/test/kotlin/de/hoennig/werkator/server/UiHomeRestTest.kt)
- [UiViewsUnitTest: a build tile names the repository, the build, its commit and its timing](../../src/test/kotlin/de/hoennig/werkator/server/UiViewsUnitTest.kt)
#### Scenario#160.11: A tile leads to where its build can be followed!
So that one click shows the live log of a running build, or the log of a failed one.
- **Given** a build of the panel
- **When** the reader clicks its tile
- **Then** a running or queued build leads to its repository's Current Builds view
- **and** a failure leads to its build page
##### Verified by
- [BuildActivityUnitTest: a running build leads to its repository's Current Builds view, a failure to its build page](../../src/test/kotlin/de/hoennig/werkator/server/BuildActivityUnitTest.kt)
- [UiHomeRestTest: a tile links where the list says](../../src/test/kotlin/de/hoennig/werkator/server/UiHomeRestTest.kt)
#### Scenario#160.12: An empty Builds panel says so!
So that a quiet instance does not look like a broken page.
- **Given** no running, queued or current failed build
- **When** the home page renders
- **Then** the Builds panel says that nothing is running, queued or failed this week
##### Verified by
- [UiHomeRestTest: an empty Builds panel says so](../../src/test/kotlin/de/hoennig/werkator/server/UiHomeRestTest.kt)
### Feature: five tiles per row
#### Scenario#160.13: Five tiles fit in one row on a desktop screen!
So that the five builds of the panel are one row, and the mosaic stays short.
- **Given** a browser window of 1366 px or more
- **When** the home page shows the Builds panel and the Repositories panel
- **Then** each panel puts five tiles in one row
##### Verified by
- Manual check on a demo instance with three repositories: five columns of 181 px at 1366 px, five of 208 px at 1920 px, one column and no sideways scrolling at 375 px.
#### Scenario#160.14: Every page has the same, larger width!
So that header and content do not jump when the reader goes from the home page to another page.
- **Given** any page of the instance
- **When** the browser window is wider than 1504 px
- **Then** the header, the content and the footer are 1440 px wide instead of 1180 px
##### Verified by
- Manual check on the demo instance: header and content 1302 px wide at 1366 px; the stylesheet sets one `min(1440px, …)` for all of them.
## Solution
- `BuildActivity` collects the panel's builds on read from each repository's history: running and queued runs, and the failures that are not outdated (`OutdatedRuns`, PR#156), are of the last seven days (`RepoOverviews.RECENT_FAILURE_WINDOW`) and have no running or queued run of their name.
It sorts and cuts to five over all repositories, so the first five are the most urgent of the instance, not of one repository.
- `OutdatedRuns.PROBLEMS` is public now, so both use the same set of failures.
- `GET /api/activity` serves the list; `Redaction.redact(ActivityBuildDto)` redacts a private repository's tile for a visitor.
- `HomeBuildView` is the tile for the server's first paint; `renderHomeBuild` in `werkator.js` renders the same markup on every poll.
The tile carries the data attributes of the existing ticker (`tickRunningDurations`), so a running or queued time counts every second without a new mechanism.
The card's head and middle line are shared helpers in `werkator.js` now (`homeCardHead`, `homeCardMid`).
- `home.html` puts both panels into one `main.home-main` column.
- CSS: every page is `min(1440px, …)` wide, the home grid's tiles are at least 180 px instead of 250 px, and the cards' padding and fonts are a little smaller to fit.
- Werkbaum: a node under `#ui`.
- Version 1.43.0, with an entry in the release notes.
## Additional Changes
- The architecture skill describes the panel.
- A private repository's card on the home page no longer has an empty `href`, which led to the home page itself until the first poll.
`th:href` with a null value wrote the attribute empty; `th:attrappend` leaves it out.
[UiHomeRestTest: a private repository is a card without a destination](../../src/test/kotlin/de/hoennig/werkator/server/UiHomeRestTest.kt) checks it now.