Skip to content

ci: keep a stalled pnpm bootstrap from cancelling a green run - #894

Open
kmonsoe wants to merge 1 commit into
mainfrom
ci/pnpm-setup-stall
Open

ci: keep a stalled pnpm bootstrap from cancelling a green run#894
kmonsoe wants to merge 1 commit into
mainfrom
ci/pnpm-setup-stall

Conversation

@kmonsoe

@kmonsoe kmonsoe commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Problem

Three of four first attempts on main today (2026-09-04) lost ~7 minutes inside pnpm/action-setup, a step that normally takes 4 s. The build job then ran out of its 15-minute budget during Test, GitHub reported the job as cancelled rather than failed, release (changesets) was skipped, and a green push produced no publish until a manual gh run rerun --failed.

Run pnpm/action-setup Outcome
33863649886 attempt 1 10:32:46Z → 10:39:49Z (7m03s) Test cancelled 10:47:36Z, release skipped; rerun passed in 9m34s
33867350482 attempt 1 11:19:14Z → 11:26:18Z (7m04s) Test cancelled 11:34:09Z, release skipped; rerun passed in 11m15s
33863399119 10:28:52Z → cancelled 10:32:21Z Superseded by the next push via the concurrency group, not a stall

The stall is not specific to the build job. In 33863649886 the e2e job's setup also took 7m03s (it survived only because e2e has more slack), and in 33867350482 the license policy job's setup took 7m08s, turning a 30-second job into a 7.5-minute one.

What the logs show

pnpm/action-setup v6.0.10 bootstraps by writing a package.json for pnpm@11.19.0, running npm ci against registry.npmjs.org, then pnpm self-update 10.28.0 to reach the packageManager version. In all three stalled jobs the log is identical:

##[group]Running self-installer...
                                   <- seven minutes of nothing ->
added 1 package in 7m
Checking for updates...
Switching pnpm from v11.19.0 to v10.28.0...
... | Progress: resolved 1, reused 0, downloaded 1, added 1, done
Successfully updated pnpm to v10.28.0

No retry or HTTP error is logged, and the self-update download that follows completes in under a second. Three independent runners landing within five seconds of each other points at a timeout inside npm on a hung registry connection, not slow transfer.

The alternative install shapes don't avoid that path, so this PR doesn't switch to them: standalone: true runs the same npm ci (for @pnpm/exe), and corepack fetches from the same registry while being deprecated on the Node 24 that .nvmrc (lts/krypton) resolves to. No upstream issue tracks this and v6.0.10 (2026-08-03) is the latest release.

Change

Two edits to .github/workflows/ci.yml, nothing else touched:

  • Build job timeout-minutes: 15 → 25. A healthy run takes 9–11 min, so 15 left no room for the stall; 25 lets a run that absorbed one still finish and publish.
  • timeout-minutes: 3 on every pnpm/action-setup step (build, release, licenses, e2e). A genuine stall now fails that step at three minutes, visibly and attributed to the right step, instead of silently spending the job's budget so that Test gets cancelled downstream. The release job is included because a stall there would block publishing just the same.

Verification

  • actionlint 1.7.12: no findings.
  • YAML parse asserting jobs.build.timeout-minutes == 25 and that all four pnpm/action-setup steps carry timeout-minutes: 3.
  • grep -nA1 'pnpm/action-setup@' shows the step timeout on every occurrence.

No changeset: nothing under packages/ changed (same as #887).

🤖 Generated with Claude Code

Three of four first attempts on main on 2026-09-04 lost ~7 min inside
pnpm/action-setup, a step that normally takes 4 s. The build job then ran out
of its 15 min budget during Test, GitHub reported the job as cancelled rather
than failed, and the release job was skipped, so a green push produced no
publish until someone ran `gh run rerun --failed`:

- run 33863649886 attempt 1: setup 10:32:46Z -> 10:39:49Z (7m03s), Test
  cancelled at 10:47:36Z, release skipped. Rerun passed in 9m34s.
- run 33867350482 attempt 1: setup 11:19:14Z -> 11:26:18Z (7m04s), Test
  cancelled at 11:34:09Z, release skipped. Rerun passed in 11m15s.
- run 33863399119 was different: superseded by the next push through the
  concurrency group, not a stall.

The same runs show the stall is not specific to the build job. In 33863649886
the e2e job's setup also took 7m03s (it survived only because e2e has more
slack), and in 33867350482 the license job's setup took 7m08s, turning a
30-second job into a 7.5-minute one.

The step logs show where the time went. pnpm/action-setup v6.0.10 bootstraps
by writing a package.json for pnpm@11.19.0 and running `npm ci` against
registry.npmjs.org, then runs `pnpm self-update 10.28.0` to reach the version
in packageManager. In all three stalled jobs the group opens, nothing is
printed for seven minutes, and then npm reports `added 1 package in 7m`. No
retry or HTTP error is logged, and the self-update download that follows
completes in under a second. Three independent runners landing within five
seconds of each other points at a timeout inside npm on a hung registry
connection, not at slow transfer. The alternative install shapes don't avoid
that path: `standalone: true` runs the same `npm ci` for @pnpm/exe, and
corepack fetches from the same registry while being deprecated on the Node 24
that .nvmrc (lts/krypton) resolves to. Timeouts are the fix that matches the
evidence.

Two changes, nothing else in the workflow touched:

- The build job's timeout-minutes goes 15 -> 25. A healthy run takes 9-11 min,
  so 15 left no room for the stall; 25 lets a run that absorbed one still
  finish and publish.
- Every pnpm/action-setup step (build, release, licenses, e2e) gets
  timeout-minutes: 3. A genuine stall now fails that step at three minutes,
  visibly and attributed to the right step, instead of silently spending the
  job's budget so that Test gets cancelled downstream.

Verified with actionlint 1.7.12 (no findings), a YAML parse asserting the
build timeout and that all four pnpm/action-setup steps carry the step
timeout, and a grep of the file.

No changeset accompanies this: nothing under packages/ changed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant