fj run rerun: --failed and --job to rerun part of a run (#168) #177

Merged
stephen merged 1 commit from feat/168-rerun-failed into main 2026-06-15 16:48:53 +00:00
Owner

On a matrix where one job flaked, fj run rerun N reran the whole run, wasting minutes and runner cost re-doing the jobs that already passed. This adds two flags to rerun just the part that needs it.

What

  • fj run rerun N --failed reruns only the jobs that did not finish green (anything but success / skipped), reusing the same "non-green" definition as view --log-failed. If the run has no failed jobs it says so and does nothing.
  • fj run rerun N --job J reruns a single job. J is the job index in the order shown by fj run view; it is validated against the run first, so a typo fails with a clear out-of-range message instead of a bare web-route 404.
  • The two flags are mutually exclusive (conflicts_with), and bare fj run rerun N still reruns the whole run, unchanged.

Forgejo has no rerun API, so both flags POST the human-facing per-job web route, /actions/runs/{run}/jobs/{job}/rerun, one POST per targeted job. Worth noting: job index 0 is a real job there, not a "rerun all" sentinel. Forgejo keys "rerun all" off the absence of the {job} path segment, so --job 0 correctly reruns just the first job rather than the run.

Unit tests cover the flag parsing and mutual exclusivity, the failed-job selection, and the per-job vs run-level routing (including that index 0 hits the job route and that a token 404 surfaces the actionable message). docs/gh-to-fj.md and the changelog updated. cargo fmt --check, cargo clippy --all-targets, and the full test suite pass locally.

Closes #168.

On a matrix where one job flaked, `fj run rerun N` reran the whole run, wasting minutes and runner cost re-doing the jobs that already passed. This adds two flags to rerun just the part that needs it. ## What - `fj run rerun N --failed` reruns only the jobs that did not finish green (anything but `success` / `skipped`), reusing the same "non-green" definition as `view --log-failed`. If the run has no failed jobs it says so and does nothing. - `fj run rerun N --job J` reruns a single job. `J` is the job index in the order shown by `fj run view`; it is validated against the run first, so a typo fails with a clear out-of-range message instead of a bare web-route 404. - The two flags are mutually exclusive (`conflicts_with`), and bare `fj run rerun N` still reruns the whole run, unchanged. Forgejo has no rerun API, so both flags POST the human-facing per-job web route, `/actions/runs/{run}/jobs/{job}/rerun`, one POST per targeted job. Worth noting: job index `0` is a real job there, not a "rerun all" sentinel. Forgejo keys "rerun all" off the absence of the `{job}` path segment, so `--job 0` correctly reruns just the first job rather than the run. Unit tests cover the flag parsing and mutual exclusivity, the failed-job selection, and the per-job vs run-level routing (including that index 0 hits the job route and that a token 404 surfaces the actionable message). `docs/gh-to-fj.md` and the changelog updated. `cargo fmt --check`, `cargo clippy --all-targets`, and the full test suite pass locally. Closes #168.
fj run rerun: --failed and --job to rerun part of a run (#168)
All checks were successful
ci / check (pull_request) Successful in 10m14s
ci / live-e2e (pull_request) Successful in 1m54s
ci / coverage (pull_request) Successful in 2m2s
e3485befbe
Bare `fj run rerun N` still reruns the whole run. `--failed` reruns only
the jobs that did not finish green; `--job J` reruns a single job by the
index shown in `fj run view`. The two flags are mutually exclusive.

Forgejo has no rerun API, so both go through the per-job web route
(`/actions/runs/{run}/jobs/{job}/rerun`); job index 0 is a real job
there, not a "rerun all" sentinel (that is keyed off an absent `{job}`
segment). `--job` validates the index against the run first, and
`--failed` reuses the same non-green definition as `view --log-failed`.
stephen force-pushed feat/168-rerun-failed from e3485befbe
All checks were successful
ci / check (pull_request) Successful in 10m14s
ci / live-e2e (pull_request) Successful in 1m54s
ci / coverage (pull_request) Successful in 2m2s
to 88fe76d73f
All checks were successful
ci / check (pull_request) Successful in 10m1s
ci / coverage (pull_request) Successful in 2m2s
ci / live-e2e (pull_request) Successful in 1m50s
2026-06-15 15:59:34 +00:00
Compare
stephen force-pushed feat/168-rerun-failed from 88fe76d73f
All checks were successful
ci / check (pull_request) Successful in 10m1s
ci / coverage (pull_request) Successful in 2m2s
ci / live-e2e (pull_request) Successful in 1m50s
to c63b35a6ee
All checks were successful
ci / check (pull_request) Successful in 10m2s
ci / coverage (pull_request) Successful in 1m49s
ci / live-e2e (pull_request) Successful in 1m51s
2026-06-15 16:28:51 +00:00
Compare
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rasterstate/fj!177
No description provided.