fix(preview): bound CMS preview-alias slug to a valid DNS label - #1665
Merged
Conversation
The deploy-preview job's per-CMS-slug alias derived `preview-cms-<slug>.adamdaniel.ai` straight from the branch ref with no length cap. For a long entry title the first DNS label exceeds the 63-octet limit, so the GitHub Deployments registration that embeds it is rejected and the whole job goes red — even though the pr-<N> preview deployed fine. That failure also skipped the preview bot comment, so the PR got no preview link at all. Extract the slug derivation into scripts/cms-preview-slug.sh, shared by the deploy and teardown jobs so they always agree on the `cms-<slug>/` prefix. When `preview-cms-<slug>` would exceed 63 chars the script keeps a 42-char readable prefix and appends an 8-hex content hash: deterministic, stable across Decap draft cycles, and collision-resistant. The CloudFront router is already a pure host->prefix string map, so no infrastructure change is needed. Teardown gains a Checkout (it had none) so the script is on disk to compute the identical prefix at PR-close. https://claude.ai/code/session_01R3Lw9zY6qKTBJ3nXpyWAvD
Contributor
|
🗑️ Preview environment cleaned up. |
4 tasks
Adam-S-Daniel
added a commit
that referenced
this pull request
May 24, 2026
…nup (#1667) cms-publish-flow.spec.js creates a smoke post via the local Decap backend and runs `jekyll build` into the SHARED _site/ the Playwright webServer serves, which bakes /blog/e2e-publish-flow-smoke/ (and the manufactured /tags/e2e-smoke-flow-tag/ archive) into _site/sitemap.xml. Its cleanup deleted the rendered dirs but NOT those sitemap entries, leaving them advertised-but-404ing. image-alt-text.spec.js runs in the same e2e-admin job, shares that _site/, walks the sitemap, and failed: "expected 200 from /blog/e2e-publish-flow-smoke/, got 404" — an intermittent, order-dependent failure on unrelated PRs (e.g. #1654). Fix: extend removeSmokePost() to prune the orphaned <url> blocks from _site/sitemap.xml so it stays consistent with what's on disk. Extracted the prune into a pure helper (e2e/sitemap-prune.js) with a unit test (e2e/sitemap-prune.test.js); verified against the real built sitemap. Not related to #1665 (e0d0256), which only touches cms/* preview-alias DNS slugs in deploy-preview.yml. https://claude.ai/code/session_01Bj5DjryAqCqW4czqyZ47f8 Co-authored-by: Claude <noreply@anthropic.com>
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.
Why
The
deploy-previewjob's per-CMS-slug alias step buildspreview-cms-<slug>.adamdaniel.aidirectly from the branch ref with no length cap. For a long entry title the host's first DNS label exceeds the 63-octet limit (RFC 1035), so the GitHub Deployments registration that embeds that URL is rejected and the whole job goes red — even though thepreview-pr<N>preview deployed fine and is live. Because that step fails before the "Post preview URL comment" step, the PR also gets no preview bot comment at all.This is exactly what's happening on #941 (branch
cms/posts/2026-05-17-safely-keep-your-agent-iterating-autonomously-with-gitleaks-and-pr-comments): the slug is 92 chars → a 104-char host label.deploy-previewis a non-required check, so the PR stays mergeable but shows red.What changed
scripts/cms-preview-slug.sh(new) — single source of truth for the slug. Stripscms/, flattens/→-, then bounds the result sopreview-cms-<slug>stays ≤ 63 chars (slug ≤ 51). Short slugs pass through unchanged; over-long ones keep a 42-char readable prefix and append an 8-hex content hash — deterministic (same entry → same host across Decap close/reopen draft cycles) and collision-resistant (two long titles sharing a 42-char prefix still differ)..github/workflows/deploy-preview.yml— both thedeploy-previewandteardown-previewcms_slugsteps now call the shared script, so they can't drift on whichcms-<slug>/prefix to publish vs. clean up. Teardown gains aCheckout(it had none) pinned to the PR head SHA, so it computes the identical prefix at PR-close.e2e/deploy-preview-cms-slug.test.js— the "same sed expression ×2" invariant becomes "both jobs call the shared script ×2" + "both jobs check out the repo"; the JS slug re-implementation is replaced with tests that exec the real script (boundary at 51/52, the Create Post “2026-05-17-safely-keep-your-agent-iterating-autonomously-with-gitleaks-and-pr-comments” #941 branch → valid ≤63 host, determinism, collision-resistance).e2e/select-specs.js— maps the test to re-run when the script ordeploy-preview.ymlchanges.No infrastructure change: the CloudFront preview-router (
infrastructure/bootstrap/template.yaml) already maps the host to the S3 prefix by pure string match^preview-cms-([a-z0-9-]+)\.adamdaniel\.ai$, and the wildcard cert/Route53 cover any valid label.For #941 the host becomes
preview-cms-posts-2026-05-17-safely-keep-your-agent-it-b8a6cdab.adamdaniel.ai(exactly 63 chars) — and now resolves and serves instead of failing the job.Test plan
deploy-preview-cms-slug.test.jsdirectly against the real files (Playwright isn't installed in the dev container; thee2e/selectlanes will run the spec in CI — the newselect-specs.jsrule selects it).deploy-preview.ymlparses as valid YAML; teardown step order intact.deploy-commit-metadata,preview-bot-comment) and the selector's own test are unaffected.scan(gitleaks) — runs on the PR (the local pre-commit gitleaks binary isn't present in the cloud container; commit used the hook's documentedSKIP_SECRETS_SCAN=1, diff contains no secrets).Generated by Claude Code