# PR#156: A failed build is shown as outdated once its branch is gone or a newer build ended > **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. ## The Problem The History shows every failed build in red, with a red row, for as long as it is recorded. A failure is still red after the branch went green again, at the same commit or a newer one. It is still red after its branch was merged and deleted. So the page shows many red rows, and most of them say nothing about how a branch stands now. A reader cannot see at a glance which failure still needs work. The bar strips on the home page have the same problem. ## Non-Goals - No change to the Latest and Branches views: they show the newest run of each name, and a gone branch is not there. - No change to the counters "failed this week", the red repository chips or the card tint: they count only the newest run of each name already. - No change to the commit statuses in Gitea. - No stored mark: the decision is made on read, like the duration trend. - No build-definition key, so ADR 0010 is not touched. ## The Scenarios ### Feature: an overtaken failure is shown as outdated #### Background - A run's *name* is its pool, `` or `@`. - A *verdict* is the end of a run that says how the code stands: `success`, `failed` or `timed_out`. - `pending`, `running`, `cancelled` and `interrupted` are no verdict. #### Scenario#156.01: A failure a newer green run followed is outdated! So that a branch that is green again shows no red for its old failure. - **Given** a failed run of a name - **When** a newer run of the same name succeeds, at the same commit or a newer one - **Then** the failed run is outdated, superseded by that green run ##### Verified by - [OutdatedRunsUnitTest: a failure a newer green run followed is outdated](../../src/test/kotlin/de/hoennig/werkator/build/OutdatedRunsUnitTest.kt) #### Scenario#156.02: A newer failure outdates the older one, and the newest stays a problem! So that a branch that fails again and again shows one red row, the one that says how it stands now. - **Given** a failed or timed-out run of a name - **When** a newer run of the same name fails or times out - **Then** the older run is outdated - **and** the newest failure is not ##### Verified by - [OutdatedRunsUnitTest: a newer failure outdates the older one](../../src/test/kotlin/de/hoennig/werkator/build/OutdatedRunsUnitTest.kt) #### Scenario#156.03: A failure of a branch deleted from origin is outdated! So that a merged and deleted branch leaves no red row behind. - **Given** a failed or timed-out run - **When** its branch is gone from origin (`branchGoneAt`) - **Then** the run is outdated, even as the newest run of its name ##### Verified by - [OutdatedRunsUnitTest: a failure of a branch deleted from origin is outdated](../../src/test/kotlin/de/hoennig/werkator/build/OutdatedRunsUnitTest.kt) #### Scenario#156.04: A newer run without a verdict leaves the failure a problem! So that a queued, running, cancelled or interrupted run does not hide a failure it has not yet answered. - **Given** a failed run of a name - **When** the only newer run of the same name is pending, running, cancelled or interrupted - **Then** the failed run is not outdated ##### Verified by - [OutdatedRunsUnitTest: a newer run without a verdict leaves the failure a problem](../../src/test/kotlin/de/hoennig/werkator/build/OutdatedRunsUnitTest.kt) #### Scenario#156.05: The History shows an outdated failure grey, with its reason! So that a reader sees at once which failures still count, and why the others do not. - **Given** an outdated run in the History - **When** the page renders it, first by the server and then by every poll - **Then** the row loses its red tint and has dimmed text - **and** the status keeps its word, with a grey outlined dot - **and** a tag `outdated` stands beside it, with the reason as its title - **and** the tag links to the run that superseded it, while that run has its artifacts ##### Verified by - [BuildsApiControllerRestTest: history names why a failure is outdated](../../src/test/kotlin/de/hoennig/werkator/server/BuildsApiControllerRestTest.kt) - [UiBuildListsRestTest: an outdated failure is a dimmed row with a tag](../../src/test/kotlin/de/hoennig/werkator/server/UiBuildListsRestTest.kt) - [UiViewsUnitTest: an outdated row names why in its tag's title](../../src/test/kotlin/de/hoennig/werkator/server/UiViewsUnitTest.kt) #### Scenario#156.06: The home strip draws an outdated failure grey! So that a repository card shows red only for the failures that still count. - **Given** an outdated run among the last twelve builds of a repository - **When** the home page draws the bar strip - **Then** the bar keeps its height and is grey instead of red - **and** the legend names it "outdated failure" ##### Verified by - [RepoOverviewsUnitTest: the strip marks a failure a newer run overtook](../../src/test/kotlin/de/hoennig/werkator/server/RepoOverviewsUnitTest.kt) - [UiViewsUnitTest: an outdated failure is a grey bar of its own height](../../src/test/kotlin/de/hoennig/werkator/server/UiViewsUnitTest.kt) #### Scenario#156.07: A private repository tells why a run is outdated, but not which commit superseded it! So that the reason stays metadata and names no work (RFC 0003, D8). - **Given** an outdated run of a private repository - **When** a visitor without the control token reads the History - **Then** the reason, the outcome and the time of the newer run stay - **and** its commit is `n/a` and its page is not linked ##### Verified by - [RedactionUnitTest: an outdated run keeps why and when](../../src/test/kotlin/de/hoennig/werkator/server/RedactionUnitTest.kt) ## The Solution - `OutdatedRuns.of(history)` walks the history newest first and keeps, per name, the nearest newer verdict. A failed or timed-out run is outdated by a gone branch first, else by that verdict. The result is a map by artifact key, so nothing is stored, and a branch that comes back is current again with its mark. - The history endpoints of the API and the page compute the map over the whole history, then take their 200 rows. `BuildResultDto.outdated` carries it as `OutdatedDto`: the reason, and for `superseded` the commit, status, start and artifact key of the newer run. The key is set only while that run has its artifacts, so the link never leads to a removed page. - `UiFormats.outdatedTitle` and its twin `outdatedTitle` in `werkator.js` word the reason. The status badge keeps its word; the colour and the filled dot go. The row is dimmed by text colour, not by opacity: opacity already says "this browser lost the server". The red row tint applies only to a failure that is not outdated. - `RecentBuildDto.outdated` marks the bar, and `HomeBarView.strip` and `barStrip` give it the level `outdated`. - `Redaction` keeps the reason, outcome and time, and replaces the commit and drops the key. - Werkbaum: a node under `#ui`. - Version 1.42.0, with an entry in the release notes.