Skip to content

A preview channel lives as long as its PR, and a failed deploy says why (#736) - #738

Merged
markgoho merged 1 commit into
trunkfrom
fix/736-preview-channel-cleanup
Sep 5, 2026
Merged

A preview channel lives as long as its PR, and a failed deploy says why (#736)#738
markgoho merged 1 commit into
trunkfrom
fix/736-preview-channel-cleanup

Conversation

@markgoho

@markgoho markgoho commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Closes #736.

The app site reached Firebase Hosting's cap of fifty preview channels on 2026-09-04 and every PR's preview deploy went red — on five branches before anyone looked, because the failure said nothing. Both halves of that are fixed here.

A channel now lives as long as its PR, and no longer

Nothing released a pr-<n> channel when its PR closed, so channels only aged out on --expires 7d. At this repo's rate — the fifty channels spanned 2026-08-31 12:03 to 2026-09-04 16:20, about twelve a day — a seven-day window settles near eighty-four live channels against a cap of fifty. Expiry is a clock and the cap is a count, so no value of --expires fixes this on its own.

firebase-hosting-preview-cleanup.yml is the count half: pull_request: closed, no paths filter (the two deploy workflows have different ones, so which sites a given PR holds a channel on is not knowable from here), deleting pr-<n> from doula-cloud-app and doula-cloud and tolerating "no such channel" as the ordinary case. --expires drops to 3d as a backstop that bounds how long a missed release lingers — roughly thirty-six channels at this rate, inside the cap — rather than as the mechanism.

A failed preview deploy now says why

--json sends firebase-tools' error to stdout as well as its result, and stdout was redirected into deploy-output.json, which nothing reads on the failure path and which is never uploaded. So the job log showed the command and then Process completed with exit code 1: no quota message, no auth error, nothing. Telling a quota wall from a bad build took reproducing it by hand. Both deploy steps now echo that output before giving up.

The cleanup step matches the API's literal HTTP Error: 404 for a channel that is not there — checked against the real message, not guessed:

Error: Request to https://firebasehosting.googleapis.com/v1beta1/projects/doula-cloud/sites/doula-cloud-app/channels/pr-999999 had HTTP Error: 404, Could not delete channel `…/channels/pr-999999`: Not Found

Matching the prose instead would swallow any future error whose wording happens to contain "not found".

What was ruled out, so nobody re-hunts it

There is no setting for this, and two candidates look like there is. Firebase's Release storage settings / Channel settings are real but count releases inside a channel, never channels, and are console-only. FirebaseExtended/action-hosting-deploy has PR #400 totalPreviewChannelLimit — exactly this knob — open and unmerged since 2024-12-10, on an Action this repo does not use; its companion issue #60 Delete preview channel on close/merge is open too. The full reasoning is on #736.

Verification, and the one thing this PR cannot prove

actionlint 1.7.12 passes locally on all workflows, which also shellchecks the run: blocks. The fifty stale channels were deleted by hand before this branch existed — every one belonging to a closed or merged PR, live all that remained — and #735's preview job was then rerun on its identical commit and passed, which is what confirms the cap was the cause.

The cleanup workflow itself cannot run until it is on trunk, since pull_request: closed fires from the base branch's copy. So the honest state is: the deploy-side changes are exercised by this PR's own preview run, and the release-on-close half is verified by the first PR that closes after this merges. Worth watching that one run rather than assuming it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NByTz9qWmxuWp8UeUykyDZ

…hy (#736)

The app site reached Firebase Hosting's cap of fifty preview channels on
2026-09-04 and every PR's preview deploy went red. Nothing released a
channel when its PR closed, so they only aged out on `--expires 7d`, and
at about twelve PRs a day that window settles near eighty-four live
channels -- well past the cap. Expiry is a clock and the cap is a count,
so no value of `--expires` fixes it alone.

So the count half is now explicit: a new workflow on `pull_request:
closed` deletes `pr-<n>` from both sites, and `--expires` drops to 3d as
a backstop bounding how long a missed release lingers -- roughly
thirty-six channels at this rate, inside the cap.

The second defect was that none of this was visible. `--json` puts the
command's error on stdout, and stdout was redirected into a file nothing
read on the failure path, so the job log showed the command and then
`Process completed with exit code 1` -- no quota message, no auth error,
nothing. Both deploy steps now echo that output before giving up, and
the cleanup step does the same, matching the API's literal `HTTP Error:
404` for a channel that is not there rather than prose that could
swallow a real failure.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NByTz9qWmxuWp8UeUykyDZ
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Hugo Preview Deployment

Preview URL: https://doula-cloud--pr-738-svzchcco.web.app

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

App Preview Deployment

Preview URL: https://doula-cloud-app--pr-738-2vu6mite.web.app

@markgoho
markgoho merged commit a9b67e8 into trunk Sep 5, 2026
10 checks passed
@markgoho
markgoho deleted the fix/736-preview-channel-cleanup branch September 5, 2026 02:34
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.

Every PR's preview deploy is red: the app site is at Firebase's 50 preview-channel cap, and the failure says nothing

1 participant