Keeping GitHub Actions reruns in an attempt ledger
Description and use
The gha‑rerun‑ledger CLI accurately aggregates job times in GitHub Actions by avoiding double‑counting of rerun jobs and provides a snapshot for offline replay.
Problem
GitHub Actions reruns can duplicate successful jobs from earlier attempts, leading to inflated time and cost estimates when aggregating run data.
Outcome
The tool accurately reports elapsed job times for failed and successful attempts (163 s and 102 s in the demo) without double‑counting carried jobs, and provides an offline replayable snapshot.
Workflow
- 1. Run the CLI to walk attempts in order and assign each job ID to its first observed attempt.
- 2. For each subsequent attempt, check that the job name, execution owner, conclusion, timestamps, labels, and steps match the first record.
- 3. If any record conflicts, fail the report.
- 4. Sum job times only after a complete sequence of attempts and pages is collected.
- 5. Separate viewed jobs from owned jobs so carried rows remain visible without double‑counting elapsed time.
- 6. Generate a ledger row for every attempt, including empty attempts.
- 7. Report skipped jobs, missing or reversed intervals, inferred owners, and runs above the attempt cap in coverage counts or warnings.
- 8. Optionally save a schema‑version‑1 JSON snapshot of the run and job API responses for offline replay.
- 9. Replay the snapshot with the CLI using --input to validate without GitHub access.
Evidence
I built gha-rerun-ledger for a narrow task: inspect the attempts behind recent completed GitHub Actions runs, then keep enough metadata to replay the report offline.
A workflow rerun can show successful jobs that carried over from an earlier attempt. Counting every row in every attempt would count that work more than once.
The CLI walks attempts in order and assigns each job ID to its first observed attempt. If a later page returns that ID again, the report checks that the name, execution owner, conclusion, timestamps, labels, and steps agree.
The report separates viewed jobs from owned jobs, so a carried row stays visible without adding its elapsed interval twice.
Job time is the difference between the job start and completion timestamps. Parallel jobs add together. Step intervals are ranked separately and are not added to job time.
A live scan uses GET requests through GitHub CLI and can save a schema version 1 JSON snapshot.
Try the labeled synthetic demo with: npx --yes github:Arthur031221/gha-rerun-ledger --demo
- Record date: 2026-10-04T07:41:09.190Z