From 4a3a7920bd7dbf480d823b38581078f487ace0e4 Mon Sep 17 00:00:00 2001 From: Don Johnson Date: Tue, 18 Aug 2026 12:51:07 -0700 Subject: [PATCH] ci: stop a hung step from costing an afternoon The quality job on 3ebd3df sat for eighty minutes and reported nothing. It was not a test failure: `apt-get` never returned, gates.sh never ran, and the job was killed before it could upload a log, so the only evidence left was a step stuck in_progress with no end timestamp. That apt-get was buying nothing. ubuntu-latest ships jq preinstalled, and the step's own output said so on every run that got that far -- "jq is already the newest version". It was a network dependency taken out on behalf of a package we already had, and it could only ever cost us. Bounding each job matters more than removing the one step that hung, since any step can stall. The limits are near ten times observed runtime, which is far too loose to interrupt real work and tight enough that the next stall reports a failure while someone is still watching. --- .github/workflows/ci.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d97d413..c5bcff6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,12 @@ permissions: jobs: quality: runs-on: ubuntu-latest + # A step that hangs rather than fails gets the six-hour default, and the job + # is killed without uploading a log, so it reports nothing about what stalled. + # One apt-get did exactly that for 80 minutes. Every job below is bounded at + # roughly ten times its observed runtime: slow enough never to cut off real + # work, fast enough that a stall costs a re-run instead of an afternoon. + timeout-minutes: 30 steps: - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@stable @@ -19,7 +25,10 @@ jobs: toolchain: 1.95.0 components: rustfmt, clippy - uses: Swatinem/rust-cache@v2 - - run: sudo apt-get update && sudo apt-get install -y jq + # gates.sh needs jq, which ubuntu-latest ships preinstalled. The apt-get + # that used to stand here only ever reported "already the newest version", + # so it bought a network dependency and a hang for nothing. If a future + # image drops jq, gates.sh says so outright instead of stalling. - run: scripts/gates.sh cross-platform: @@ -28,6 +37,7 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} + timeout-minutes: 30 steps: - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@stable @@ -48,6 +58,7 @@ jobs: dependency-audit: runs-on: ubuntu-latest + timeout-minutes: 15 steps: - uses: actions/checkout@v7 - uses: EmbarkStudios/cargo-deny-action@v2 @@ -57,6 +68,7 @@ jobs: supply-chain: runs-on: ubuntu-latest + timeout-minutes: 15 steps: - uses: actions/checkout@v7 with: