fix: Web deploy reds on every main push: the prod health gate finds no worker URL - #9510
Conversation
🚀 Preview deployed
|
|
governance: PASS @ b34bbc4 content:838f8e480422 — no contradiction, no weakening Derivation
Whether this diff also needs a code-owner approval is a separate question CODEOWNERS answers, not this one. Corpus half — does this contradict standing lawNo decision record is in the diff, so there was no subject to rank and Questions this change answers:
Records read by hand:
No contradiction found. Gate half — does this quietly weaken a guard
No weakening found; no invariant in this diff's reach was removed or softened. VerdictPASS — no contradiction with standing law, no guard weakened. Everything the two halves needed was read. |
|
review-code: PASS @ b34bbc4 content:838f8e480422 — merge-ready Scoped at Acceptance criteria1. The URL scrape extracts the deployed URL from Alchemy's
The old The quoting survives the shell: 2. 3. The empty-URL branch still exits non-zero and the 4. The and that same job's 5. The widened pattern is shown to match real Alchemy output, with the red prod block and the extracted URL in the PR description — MET. [evidence: the deploy-log excerpt and extracted URL in the PR description] — again read at source, not relayed. Job and at line 654 the job fails with All five criteria are discharged. Nothing is left open. FindingsNone in scope. The fan-out on silent failure, type design and test gaps:
CommentsThe eight added lines in Deviations
CI at head
GovernanceFired this round; VerdictPASS. Verdict-written: 2026-09-20T19:58:47Z |
|
ship: AWAITING-CP-APPROVAL — PR #9510 @ b34bbc4 → human
No base drift was reported, so no rebase is owed. Merge intent: cleared (nothing was armed). Branch untouched. |
The prod deploy job has reddened on every push to main since the Alchemy upgrade (#8934). The
deploy itself succeeds; the health gate after it fails because the URL scrape returns nothing.
deploy.ymlscraped the deployed URL by matching a*.workers.devhost anywhere indeploy.log.Alchemy prints a summary object whose
url:key carries the custom domain when the stage has one,and it no longer prints a workers.dev host beside it for prod. So the host-shaped pattern matched
nothing,
steps.deploy.outputs.urlcame back empty, and the verify step hit its fail-closedempty-URL branch before its first probe.
This matches on the
url:key instead of on the host shape, which covers both a custom domain anda workers.dev host with one pattern:
The empty-URL branch and the step's
if: github.event_name == 'push'guard are untouched — nooutputs.url != ''clause was added anywhere (#1617, ADR 0092). An unscrapeable URL still reds thejob.
The widened pattern against real Alchemy output
Red prod run
35531984366, job106134117846(the run the issue names) printed:Run against that block, the new pattern extracts
https://phoenix.kamp.us. The old pattern extractsthe empty string from it — that is the bug. Probing the custom domain is also the stronger check:
it is the host users actually hit.
I also ran the pattern against a log with no
url:line at all. It yields the empty string, so thefail-closed branch still fires on a genuinely URL-less deploy.
The preview regex in ci.yml is settled: no widening
Preview deploy log: https://github.com/kamp-us/phoenix/actions/runs/35476125242/job/105985669521
(PR #9279's preview,
pr-9279stage). Its Alchemy output:A
pr-<n>stage binds no custom domain —domains: []— so Alchemy still prints a workers.dev hostthere, and the same job's
PREVIEW_URLstep env carried that host. ThewebReinci.ymlistherefore not broken and is left unchanged. Widening it would be worse than a no-op: it would let a
custom-domain line, which only prod produces, satisfy a preview poll. I recorded that reasoning as a
comment beside the regex so the next reader does not re-open it.
Note that the preview comment's URL comes from this same
steps.deploy.outputs.url, so the scrapechange does reach previews — and the new pattern extracts the identical workers.dev host from the
preview block above, so the comment's contents do not move.
Deviations
.github/workflows/deploy.yml, andci.ymlis to be changed only if a preview URL can be non-workers.dev. Did: left theci.ymlregex unchanged but added a four-line comment above it recording why the workers.dev shape is
deliberate. Why: an acceptance criterion asks for a comment or a PR-body line recording the
finding, and a PR body is not a surface the next reader of that regex will find.
Disposition: stated here; comment only, no behavior change.
Fixes #9507