152 lines
7.5 KiB
Markdown
152 lines
7.5 KiB
Markdown
> **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
|
|
|
|
A build row offered one restart, and what it built depended on the page.
|
|
Latest rebuilt the recorded commit, Branches built the origin head, History and the artifact page offered none.
|
|
Which commit a click built was therefore a matter of where the user stood, and easy to get wrong.
|
|
The restart also took a build name only: a "same commit" from an older History row would have repeated the newest run of that name.
|
|
|
|
## Non-Goals
|
|
|
|
- A follow-up build never starts at the newest commit: without its predecessor's green run it would, e.g., deploy untested code.
|
|
- A pull-request target build does not ask the forge for the newest head of its pull request; the watcher builds every new head.
|
|
- The Current page keeps its cards without restarts; a running build is cancelled there, not restarted.
|
|
|
|
## Specification
|
|
|
|
### Feature: Two restarts on every build row
|
|
|
|
#### Scenario#150.01: Every view offers both restarts on every row
|
|
|
|
So that the button, not the page, says which commit is built.
|
|
|
|
- **Given** a recorded build of `main`
|
|
- **When** Latest, Branches or History is shown
|
|
- **Then** its row has a button `Build commit <abbrev> again` and a button `Build the newest commit of main`
|
|
|
|
##### Verified by
|
|
|
|
- [UiBuildListsRestTest](../../src/test/kotlin/de/hoennig/werkator/server/UiBuildListsRestTest.kt) — Scenario#150.01
|
|
- `werkator.js` (`restartButtons`) renders the same two buttons; checked in the browser against a demo instance
|
|
|
|
#### Scenario#150.02: The same commit builds the run of its row
|
|
|
|
So that an older History row repeats that run, not the newest run of its name.
|
|
|
|
- **Given** two runs of `main@pitest`, an older one at commit `older1` and a newer one
|
|
- **When** the same commit of the older run is restarted
|
|
- **Then** commit `older1` is built with the `pitest` definition
|
|
|
|
##### Verified by
|
|
|
|
- [BuildsApiControllerRestTest](../../src/test/kotlin/de/hoennig/werkator/server/BuildsApiControllerRestTest.kt) — Scenario#150.02
|
|
|
|
#### Scenario#150.03: A refused restart stays visible, disabled, with its reason
|
|
|
|
So that the user sees why a restart is not offered, and the columns stay aligned.
|
|
|
|
- **Given** a run whose branch is gone, a follow-up run, a branch never built, and a viewer without the control token
|
|
- **When** the rows are shown
|
|
- **Then** the buttons that cannot run are disabled with `Branch deleted from origin`, `Runs after a green default; restart that one`, `Never built` or `Needs the control token` as title
|
|
|
|
##### Verified by
|
|
|
|
- [UiBuildListsRestTest](../../src/test/kotlin/de/hoennig/werkator/server/UiBuildListsRestTest.kt) — Scenario#150.03
|
|
- [BuildRestartsUnitTest](../../src/test/kotlin/de/hoennig/werkator/server/BuildRestartsUnitTest.kt) — Scenario#150.03
|
|
|
|
#### Scenario#150.04: The newest commit is refused for a follow-up, a pull-request target and a gone branch
|
|
|
|
So that no restart deploys a commit its predecessor has not passed, or hands the host's secrets to a stale pull request.
|
|
|
|
- **Given** the follow-up `main@deploy` of `default`, a pull-request target run, and a run whose branch is gone
|
|
- **When** the newest commit of each is requested
|
|
- **Then** each is refused with its reason, and no build starts
|
|
|
|
##### Verified by
|
|
|
|
- [BuildsApiControllerRestTest](../../src/test/kotlin/de/hoennig/werkator/server/BuildsApiControllerRestTest.kt) — Scenario#150.04
|
|
- [BuildRestartsUnitTest](../../src/test/kotlin/de/hoennig/werkator/server/BuildRestartsUnitTest.kt) — Scenario#150.04
|
|
- on a demo instance: `main@deploy` ran after a green `main`, and its newest commit answered `409`
|
|
|
|
#### Scenario#150.05: The artifact page offers both restarts of its build
|
|
|
|
So that a build can be repeated from the page that shows why it failed.
|
|
|
|
- **Given** the artifact page of a recorded build
|
|
- **When** it is shown
|
|
- **Then** it has a line `Restart:` with both buttons
|
|
|
|
##### Verified by
|
|
|
|
- [UiArtifactPageRestTest](../../src/test/kotlin/de/hoennig/werkator/server/UiArtifactPageRestTest.kt) — Scenario#150.05
|
|
|
|
#### Scenario#150.06: A private repository hides the name in a follow-up's refusal
|
|
|
|
So that a refusal does not reveal a build-definition name, which is content (RFC 0003, D8).
|
|
|
|
- **Given** the refusal `Runs after a green secret-deploy; restart that one` of a private repository
|
|
- **When** the row is redacted
|
|
- **Then** the refusal reads `Runs after a green n/a; restart that one`
|
|
|
|
##### Verified by
|
|
|
|
- [RedactionUnitTest](../../src/test/kotlin/de/hoennig/werkator/server/RedactionUnitTest.kt) — Scenario#150.06
|
|
|
|
#### Scenario#150.07: The API refuses the same commit of a gone branch with the reason
|
|
|
|
So that a script gets the same answer the disabled button gives.
|
|
|
|
- **Given** a run whose branch is gone from origin
|
|
- **When** `POST /api/builds/<artifactKey>/restart` is sent for it
|
|
- **Then** the answer is `409` with `Branch deleted from origin` in `error`, and no build starts
|
|
|
|
##### Verified by
|
|
|
|
- [BuildsApiControllerRestTest](../../src/test/kotlin/de/hoennig/werkator/server/BuildsApiControllerRestTest.kt) — Scenario#150.07
|
|
|
|
#### Scenario#150.08: The same commit of a pull-request target re-runs its pull request
|
|
|
|
So that a target build is repeated with the pull request it judged, never with a branch build.
|
|
|
|
- **Given** a recorded pull-request target run of pull request 7
|
|
- **When** its same commit is restarted
|
|
- **Then** pull request 7 is built again as a pull-request target
|
|
|
|
##### Verified by
|
|
|
|
- [BuildsApiControllerRestTest](../../src/test/kotlin/de/hoennig/werkator/server/BuildsApiControllerRestTest.kt) — Scenario#150.08
|
|
|
|
#### Scenario#150.09: A follow-up of a branch refuses the newest commit
|
|
|
|
So that a follow-up never starts before its predecessor is green.
|
|
|
|
- **Given** branch `feature/x` defines the follow-up `report` of `default` in its own `.werkator.yml`
|
|
- **When** the newest commit of `report` on `feature/x` is asked for
|
|
- **Then** it is refused
|
|
|
|
##### Verified by
|
|
|
|
- [RestartPolicyUnitTest](../../src/test/kotlin/de/hoennig/werkator/server/RestartPolicyUnitTest.kt) — Scenario#150.09
|
|
|
|
## Solution
|
|
|
|
- `BuildRestarts` decides why a restart cannot run: `sameCommitRefusal` and `newestCommitRefusal`.
|
|
`RestartPolicy` reads the follow-ups of each branch at its origin head, its own layer included, as the watcher does.
|
|
It reads them once per branch and head commit, since the pages poll every few seconds; a branch gone from origin, or one whose configuration cannot be read, falls back to the primary configuration.
|
|
- `BuildResultDto` and `BranchDto` carry both refusals; the rows, the template and `werkator.js` only show them.
|
|
- `POST /api/builds/<artifactKey>/restart` builds a run again by its key.
|
|
The existing `POST /api/builds/restart?atOriginHead=true` is the newest commit and now refuses with `409`.
|
|
A pull-request target used to re-run its recorded pull request even at origin head (Scenario#117.07); now it is refused there.
|
|
- The fragment `restartButtons` renders the two buttons for the build tables and the artifact page.
|
|
The page flags `allowRestart` and `restartAtOriginHead` are gone.
|
|
- The newest commit gets an icon of its own, an arrow to a line; the actions column is wider for the third button.
|
|
- `BuildsApiController.restart` stood at Mutation-CRAP 14.07; the start and the answer moved into `start` and `accepted`, which `rebuild` shares.
|
|
|
|
## Additional Changes
|
|
|
|
- `docs/deployment.md` names both forms of the restart and the `409` answer.
|
|
- Version 1.41.0 with its release note.
|