fix: timeout Cloudflare cutover API fetches - #167
Conversation
The host cutover script called api.cloudflare.com with no AbortSignal. A stalled API socket could hang the pages.yml cutover step until the job was killed. Attach AbortSignal.timeout (default 30000ms, CLOUDFLARE_API_TIMEOUT_MS) on every Cloudflare API fetch. Signed-off-by: Sebastien Tardif <SebTardif@ncf.ca>
Consolidate release notes for the prepared dependency and publishing fixes in the final PR to avoid changelog conflicts. Document the R2 and hostname cutover request budgets.
|
Verified final head Ran The maintainer follow-up rejects malformed and overflowing timeout settings before network operations. All 134 Exact-head checks succeeded:
This PR contains the shared Unreleased entries for #132, #152, #161, #163, #164, #165, #166, and #167, plus the request-timeout documentation. Land it last, after the other seven. All eight changes apply cleanly in that order to main |
What Problem This Solves
Fixes an issue where operators running the docs hostname cutover would hang until the GitHub runner hit its job limit if the Cloudflare API socket stalled.
scripts/cloudflare-cutover-docs-hosts.mjscalledapi.cloudflare.comwith noAbortSignal, so a dry-run or live cutover frompages.ymlnever returned while the TCP connection sat idle.Why This Change Was Made
Every Cloudflare API
fetchin the cutover script now carriesAbortSignal.timeout. The default budget is 30000ms and can be raised withCLOUDFLARE_API_TIMEOUT_MS. Reads and writes share the same helper, so zone lookup, DNS, and Worker route calls all abort. R2 upload, live-smoke, locale commit, and the four workflowtimeout-minuteschanges from sibling PRs are unchanged.User Impact
A docs host cutover fails closed on a stalled Cloudflare API request instead of occupying a runner until the workflow times out. Operators can raise the per-request budget when a slow API call needs more than 30 seconds.
Evidence
terminal output from running
scripts/cloudflare-cutover-docs-hosts.mjsagainst the unfixed tree, then the same script after the patch.Before, a successful zone lookup had no abort signal, and a hung lookup never returned:
After the patch, the same production script attaches an AbortSignal on every Cloudflare API call and aborts a hung request inside the 80ms budget:
node --check scripts/cloudflare-cutover-docs-hosts.mjsexits 0.This missing abort signal has been present since the cutover script landed in
bebb9a9fab(2026-05-23, 105 days). Sibling abort work is #163 and #164 and is not changed here.Real behavior proof
pages.ymlCut over docs hostnames could occupy a runner until the job was killed.--importpreload.node --check scripts/cloudflare-cutover-docs-hosts.mjs. ThenCLOUDFLARE_API_TOKEN=test-token node --import file:///C:/Users/sebta/AppData/Local/Temp/docs-f006-signal-fetch.mjs scripts/cloudflare-cutover-docs-hosts.mjs --dry-run. Then the same production script withCLOUDFLARE_API_TIMEOUT_MS=80and a hungfetchthat only settles when the request signal aborts.Summary
Same abort class as #163 (R2 signed fetch) and #164 (live-smoke fetch), applied to the remaining operator cutover helper. Public path is
node scripts/cloudflare-cutover-docs-hosts.mjsfrom.github/workflows/pages.yml.