Skip to content

fix: bound every CI job with a timeout and stop masking install failures - #36

Merged
josephfusco merged 1 commit into
mainfrom
fix/ci-job-timeouts
Aug 20, 2026
Merged

fix: bound every CI job with a timeout and stop masking install failures#36
josephfusco merged 1 commit into
mainfrom
fix/ci-job-timeouts

Conversation

@josephfusco

@josephfusco josephfusco commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to #34. That PR bounded the Playwright browser install after a stalled apt mirror ate a full 30-minute job; this covers the same class of failure everywhere else it can still happen.

Job timeouts

playwright was the only test job with timeout-minutes. Every other job inherited GitHub's 360-minute default, so an equivalent hang outside Playwright would burn six hours before anyone noticed.

phpunit is the sharpest case — it clones Gutenberg trunk, runs npm install, and builds wp-env's Docker images, which is strictly more unbounded network work than Playwright does, and it's the job that actually failed on the last main run.

Job Typical Cap
phpunit (both legs) ~5 min 30
codeql ~45 s 20
plugin-check ~2 min 15
phpcs / phpstan ~20 s 10
gate 3 s 5

Playwright's own cap drops 30 → 15. Its install is separately bounded at 10 minutes worst case now, so 30 was ~5× a typical run and only delayed the report of a real hang.

Failure masking in build-gutenberg.sh

npm install --legacy-peer-deps 2>&1 | grep -E "…" || true swallowed a failing npm along with the grep it was meant to tolerate (grep exits 1 when it matches nothing). A broken Gutenberg install fell through to the build step and surfaced as a confusing downstream error rather than the real one. Now reads npm's own status out of PIPESTATUS so only grep is allowed to fail.

Test plan

  • actionlint clean on all workflows
  • shellcheck clean on build-gutenberg.sh
  • Script logic verified against stubbed npm on Ubuntu 24.04 / bash 5.2 — npm-ok, npm-ok-but-grep-matches-nothing, npm-fails, and exit-code propagation (7/7)
  • CI green on this PR

Not included

Reproducibility is a real gap but a genuine tradeoff, so it's left for separate discussion: build-gutenberg.sh tracks moving Gutenberg trunk, .wp-env.json sets "core": null, and composer.json sets "lock": false with no composer.lock — upstream can turn main red with no commit here, and a past run can't be reproduced as it was.

Use of AI Tools

Assisting with the workflow audit, timeout sizing, and the build-gutenberg.sh fix.

@josephfusco
josephfusco marked this pull request as draft August 20, 2026 14:41
@codecov

codecov Bot commented Aug 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 63.90%. Comparing base (cfef9d2) to head (38fff6a).

Additional details and impacted files
@@            Coverage Diff            @@
##               main      #36   +/-   ##
=========================================
  Coverage     63.90%   63.90%           
  Complexity       35       35           
=========================================
  Files             7        7           
  Lines           266      266           
=========================================
  Hits            170      170           
  Misses           96       96           
Flag Coverage Δ
multisite 63.90% <ø> (ø)
phpunit 64.63% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The Playwright job was the only test job with `timeout-minutes`, so the
recent stalled-mirror hang was capped at 30 minutes there but would have
run to GitHub's 360-minute default anywhere else. phpunit is the sharper
case: it clones Gutenberg trunk, runs npm install and builds wp-env's
Docker images -- strictly more unbounded network work than Playwright --
and it's the job that actually failed on the last main run. Give each job
a cap sized to a few times its observed runtime.

Also drop Playwright's own cap from 30 to 15 minutes. Its browser install
is separately bounded at 10 minutes worst case now, so the old number was
~5x a typical run and only delayed the report of a genuine hang.

In build-gutenberg.sh, `npm install ... | grep ... || true` swallowed a
failing npm alongside the grep it was meant to tolerate (grep exits 1 when
it matches nothing), letting a broken install fall through to a confusing
error from the build step instead. Check npm's own status via PIPESTATUS
so only grep is allowed to fail.
@josephfusco
josephfusco marked this pull request as ready for review August 20, 2026 15:01
@josephfusco
josephfusco merged commit 3401ef3 into main Aug 20, 2026
18 checks passed
@josephfusco
josephfusco deleted the fix/ci-job-timeouts branch August 20, 2026 15:08
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