vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Record a job that never started as could-not-run, not as a failure
70c9ad4eb3f3d0cd39159e647cde77afba75b944 · Keenan Nemetz · 3h ago · parent 9704d735
Record a job that never started as could-not-run, not as a failure A run that never executed a step was recorded exit=1, steps=nil, and the run page said the same thing it says when a test fails. With checks required on a protected branch, a runner that could not build an image red-flagged a commit whose tests pass, and the only way back was a rerun by hand. Two facts were collapsed into one: the job ran and something failed, which is the repository's problem, and the job never ran, which is the machine's. The runner knows the difference exactly once, and it does not need to guess whose fault it was: if no step ran, nothing about the commit was tested. - A record can now say where it stopped: Failure=setup means the attempt ended before the job's first step, with the runner's own one-line reason in FailureMessage, masked the way the log is. The reason is what the page shows instead of making a reader open the log to learn the machine broke. - A run whose newest attempt has that origin is StatusError, which the pages call "could not run". It is not StatusFailed: it is not evidence against the commit. - The gate reads it as a wait, not a refusal. Landing stays blocked because nothing is verified, but the commit is not blamed, and the gap names the reason and the rerun command. - The run list counts and filters it, the run page explains it, and the change list says "CI could not run" rather than "CI failed". A step that exits non-zero is still a failure and still reds the check, because that one is the code's. `vole runner` still reports a setup failure with exit 1; the origin is what carries the meaning, so an old runner and an old instance keep talking. Not done here, on purpose: a run whose attempts all vanished before reporting (the lease-loss exhaustion in RequeueExpired) still ends as failed. That run has no record to say what ran, and a job that repeatedly kills its runner is not distinguishable from a machine problem from the queue's side; issue #243 is where that gets a signal. Nor is a setup failure requeued automatically: MaxAttempts is about flaky tests, not broken runners, and #247 already stops a runner whose runtime cannot start a container from serving at all. A rerun is a button. The finish path now takes an attemptOutcome instead of six positional arguments, which is also what lets a failure after the last step keep the steps that ran instead of dropping them. Closes 01M6Z05K5PM58EE3H6VE2P2EYD
docs/change-requests.md +3
| @@ -271,6 +271,9 @@ opening every change: | |||
| 271 | 271 | allowed by a maintainer yet. | |
| 272 | 272 | - **Waiting on CI jobs** — checks for the commit are queued or running. | |
| 273 | 273 | - **CI failed** — a check failed; pushing a fix starts a new review. | |
| 274 | - **CI could not run** — a runner could not start a job for this commit, so nothing | ||
| 275 | was tested. The commit is not what failed: rerun the job once the machine can | ||
| 276 | build, and the check takes the new result. | ||
| 274 | 277 | - **Waiting for review** — fewer current approvals than the base branch requires. | |
| 275 | 278 | - **Merge conflict** — the branch no longer merges into its base cleanly. | |
| 276 | 279 | - **Ready to merge** — the required approvals are in (or none are required) and | |