feat(deploy): production on tablo.run + preview-<N>.tablo.run subdomains#18
Merged
Conversation
Cloudflare answers DELETE /workers/domains/{id} with an empty 200 body.
The beta CF client falls through to envelope-schema decode, fails, and
aborts the whole deploy/destroy with the misleading
`CloudflareHttpError: null` — orphaning the worker and its state. This
fires on every custom-domain teardown (the PR-close cleanup job) and on
any production domain switch (reconcileDomains deletes the old domain).
Patch the client (via `bun patch`) to treat an empty/null 2xx body as
no-content, mirroring its own 204 branch. `bun install --frozen-lockfile`
re-applies it on every CI runner. Drop once the upstream fix
alchemy-run/distilled#344 ships in a released @distilled.cloud/core.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gp4ZeUYKtUbPkhjM8Gb4TN
…tablo.run Move the production custom domain from tablo.i11v.com to the apex tablo.run, and give every PR preview its own preview-<N>.tablo.run hostname (previously workers.dev only). The hostname is derived from the deploy stage by a new workerDomain() helper co-located with workerName(): production -> tablo.run, pr-<N> -> preview-<N>.tablo.run, everything else -> none. The worker name keeps the pr- scheme (tablo-pr-<N>); only the public hostname reads preview-. Both workers.dev URLs stay live via `url: true`, so the health smoke test keeps hitting the deterministic workers.dev URL while the PR comment now advertises the custom domain (workers.dev as a fallback line). Switching production's domain detaches tablo.i11v.com on the next prod deploy; that delete is made safe by the @distilled.cloud/core patch in the preceding commit. The tablo.run zone already exists in the account, so Cloudflare auto-provisions DNS + TLS on deploy. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Gp4ZeUYKtUbPkhjM8Gb4TN
|
🚀 Preview deployed: https://preview-18.tablo.run |
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.
What
Moves tablo's production custom domain to the apex
tablo.runand gives every PR preview its ownpreview-<N>.tablo.runhostname (previews wereworkers.dev-only before). Also lands the@distilled.cloud/corepatch that makes custom-domain deletes (preview teardown + the production cutover itself) survive a beta CF-client bug.Why two commits, in this order
fix(deploy): patch @distilled.cloud/core empty-body DELETE crash— Cloudflare answersDELETE /workers/domains/{id}with an empty200body; the beta CF client falls through to envelope-schema decode, fails, and aborts the wholedeploy/destroywith the misleadingCloudflareHttpError: null, orphaning the worker + its state. This fires on every custom-domain teardown (the PR-close cleanup job) and on any production domain switch (reconcileDomainsdeletes the old domain). Patched viabun patchto treat an empty/null 2xx body as no-content, mirroring the client's own204branch.bun install --frozen-lockfilere-applies it on every CI runner. Drop once upstream alchemy-run/distilled#344 ships in a released@distilled.cloud/core.feat(deploy): serve production on tablo.run, previews on preview-<N>.tablo.run— newworkerDomain()helper co-located withworkerName():production → tablo.run,pr-<N> → preview-<N>.tablo.run, everything else → none. The worker name keeps thepr-scheme (tablo-pr-<N>); only the public hostname readspreview-. Bothworkers.devURLs stay live viaurl: true, so the health smoke test keeps hitting the deterministicworkers.devURL while the PR comment now advertises the custom domain (withworkers.devas a fallback line).The patch lands first so the production cutover — which detaches
tablo.i11v.com— and every preview teardown are both safe.Deploy / cutover
Merging triggers the existing CI prod deploy (
--stage production), which attachestablo.runand detachestablo.i11v.com(replace, not keep-both). Thetablo.runzone already exists in the account, so Cloudflare auto-provisions the proxied DNS record + TLS cert — no per-deploy dashboard or DNS steps.One manual prerequisite (dashboard)
tablo.runis apex and Workers Custom Domains create the apex DNS record. Before merging, confirm thetablo.runzone has no conflicting proxied A/AAAA/CNAME at the apex (a parking/placeholder record), or the first prod deploy's domain attach will fail.preview-<N>.tablo.runsubdomains are covered by Universal SSL's*.tablo.run.Verification
typecheckclean, 79/79 unit tests pass (incl. 4 newworkerDomaincases), and the patch was confirmed to re-apply on a cleanbun install --frozen-lockfilewith alchemy resolving to the patched copy. Live domain provisioning + teardown against the Cloudflare API only run in CI — this PR's own preview deploy exercises apreview-<N>.tablo.runattach, and closing it exercises the patched teardown.🤖 Generated with Claude Code
https://claude.ai/code/session_01Gp4ZeUYKtUbPkhjM8Gb4TN