From 5f17b8602e115b13095961bfb32618d8436920f3 Mon Sep 17 00:00:00 2001 From: Matthew Podwysocki Date: Mon, 14 Sep 2026 23:14:54 -0400 Subject: [PATCH] ci: bound every job, so a hang fails instead of idling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit None of the four jobs had a `timeout-minutes`, so each inherited GitHub's six-hour default. That is what a test blocking on `accept()` with no deadline cost the Windows leg — six hours per run, and the only reason it went unnoticed for a day is that every run on `main` was cancelled by the next push before it could finish. Twenty minutes is not a budget; these legs take one to two minutes. It is a tripwire, set about ten times longer than anything here has ever needed. On all four rather than the one that broke. `installer` and `installer-windows` both stand up local servers in `test-install.sh` and `test-install.ps1` and could wedge exactly the same way, and a job that suddenly needs twenty minutes has something wrong with it worth hearing about whichever it is. The comment explaining this lives once, on `build`, where it happened. --- .github/workflows/ci.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b90bfb0..41eb5e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,6 +32,18 @@ jobs: matrix: os: [ubuntu-latest, macos-14, windows-2022] runs-on: ${{ matrix.os }} + # These legs take one to two minutes. Twenty is not a budget, it is a + # tripwire: without one, a job that stops making progress runs to GitHub's + # six-hour default before anyone hears about it. That is not hypothetical — + # a test that blocked on `accept()` with no deadline wedged the Windows leg + # for its full six hours, and the only reason it went unnoticed for a day + # is that every run on `main` was cancelled by the next push first. + # + # On all three rather than Windows alone: nobody here runs Windows as a + # daily driver, so CI is the only signal it has — but a Unix leg that + # suddenly needs twenty minutes has something wrong with it worth hearing + # about too. + timeout-minutes: 20 permissions: contents: read steps: @@ -113,6 +125,7 @@ jobs: matrix: os: [ubuntu-latest, macos-14] runs-on: ${{ matrix.os }} + timeout-minutes: 20 permissions: contents: read steps: @@ -148,6 +161,7 @@ jobs: matrix: shell: [powershell, pwsh] runs-on: windows-2022 + timeout-minutes: 20 permissions: contents: read steps: @@ -268,6 +282,7 @@ jobs: audit: name: advisories (blocks on a vulnerability) runs-on: ubuntu-latest + timeout-minutes: 20 permissions: contents: read steps: