ci: add per-job timeout-minutes so a wedged runner fails fast - #71
Merged
Conversation
No job in .github/workflows/ set timeout-minutes, so a wedged GitHub-hosted runner sat "in_progress" for GitHub's 6h default — blocking merges and forcing manual cancels. Add a job-level timeout-minutes to every job (15 jobs across 5 workflows), sized comfortably above each job's worst-case (cold-cache) runtime so normal runs never trip, but well under 6h so a hung runner fails fast and the PR can be re-run. Values: ci.yml changes/inclusive-language/docs-sanity 10; lint/feature-clippy/ deny/web 20; asyncapi-validate 15; test (macOS is the long pole) 40. docker.yml + ffmpeg-base.yml build 90 (full image/source builds on native runners), merge 30. release.yml build 60 (release build + macOS notarization wait). release-plz 20. Pure CI-reliability change: only the timeout-minutes key is added — no job steps, logic, or triggers touched. actionlint passes (the two pre-existing SC2153 info notes are in unmodified merge-job scripts and are false positives). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Jun 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The gap
No job in
.github/workflows/settimeout-minutes. When a GitHub-hosted runner wedges (which has happened repeatedly this week), the job sitsin_progressfor GitHub's 6-hour default before it's killed — blocking merges and forcing manual cancels.The fix
Add a job-level
timeout-minutesto every job — 15 jobs across all 5 workflows. Each value is sized comfortably above that job's worst-case (cold-cache) runtime so a normal run never trips it, but well under 6h so a hung/wedged runner fails fast and the PR can simply be re-run. Job-level is the right granularity: it caps the whole job, including a runner that wedges before any step starts. When unsure, erred higher — a too-low timeout that kills real work is worse than a slightly-too-high one.Values chosen + rationale
ci.yml(9 jobs)changes(classify)lint(fmt + clippy)test(check + test, ubuntu + macOS)feature-clippy(per crate/feature leg)asyncapi-validatedeny(cargo-deny)inclusive-languagedocs-sanityweb(npm install + Vite build)docker.yml(2 jobs)buildmergeffmpeg-base.yml(2 jobs)buildmergerelease.yml(1 job)build(per target)--release --lockedcargo build, plus macOS codesign +notarytool --waitwhich can block on Apple's notarization servicerelease-plz.yml(1 job)release-prNo logic changed
Purely additive: 50 insertions, 0 deletions — only the
timeout-minuteskey (plus a one-line rationale comment) is added per job. No job's steps, logic, or triggers were touched. No Rust/web code touched, so this will not conflict with parallel work.Verification
actionlint(v1.7.7) run on every workflow file: passes. The only two notes are pre-existingSC2153info-level shellcheck false positives (DIGESTSenv var) in the unmodifiedmerge-job scripts — confirmed identical on pristineorigin/main, not introduced here.ci.yml9/9,docker.yml2/2,ffmpeg-base.yml2/2,release-plz.yml1/1,release.yml1/1 — every job has exactly one timeout.🤖 Generated with Claude Code