A preview channel lives as long as its PR, and a failed deploy says why (#736) - #738
Merged
Merged
Conversation
…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
Hugo Preview DeploymentPreview URL: https://doula-cloud--pr-738-svzchcco.web.app |
App Preview DeploymentPreview URL: https://doula-cloud-app--pr-738-2vu6mite.web.app |
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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--expiresfixes this on its own.firebase-hosting-preview-cleanup.ymlis the count half:pull_request: closed, nopathsfilter (the two deploy workflows have different ones, so which sites a given PR holds a channel on is not knowable from here), deletingpr-<n>fromdoula-cloud-appanddoula-cloudand tolerating "no such channel" as the ordinary case.--expiresdrops 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
--jsonsendsfirebase-tools' error to stdout as well as its result, and stdout was redirected intodeploy-output.json, which nothing reads on the failure path and which is never uploaded. So the job log showed the command and thenProcess 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: 404for a channel that is not there — checked against the real message, not guessed: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-deployhas PR #400totalPreviewChannelLimit— 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
actionlint1.7.12 passes locally on all workflows, which also shellchecks therun:blocks. The fifty stale channels were deleted by hand before this branch existed — every one belonging to a closed or merged PR,liveall 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, sincepull_request: closedfires 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