fix: deployment hygiene — concurrency, CNAME, per-branch previews#3
Merged
danielnaab merged 10 commits intomainfrom Apr 28, 2026
Merged
fix: deployment hygiene — concurrency, CNAME, per-branch previews#3danielnaab merged 10 commits intomainfrom
danielnaab merged 10 commits intomainfrom
Conversation
Covers four issues surfaced after the first merge to main: concurrency-group collision that cancels main deploys on branch delete, missing CNAME on gh-pages, shared preview environment, and deployments that never transition to inactive on branch delete.
Seven tasks, TDD-first where a test surface exists. Covers the CNAME fix in the build driver and the four workflow changes in deploy.yml, then an end-to-end verification task that exercises the full lifecycle against the real GitHub API.
The publish job does not check out the source repo, so its CNAME fallback silently fails and labs.flexion.us returns 404 after every main deploy. Include CNAME in the build output instead — the artifact then carries everything it needs to be deployed.
delete events report github.ref as refs/heads/main, so a branch-delete run was sharing a concurrency group with the main-deploy run it triggered — cancelling it. Keying on github.event.ref for delete and github.ref_name otherwise scopes cancellation correctly per branch.
Previously a manual run would build and test successfully but skip the publish job, which means workflow_dispatch could not be used for recovery. Allow it to take the same publish path as a push.
Previously every branch landed in a shared 'preview' environment, so the GitHub Deployments UI could not be used to navigate per-branch state. Deploy previews to 'preview/<sanitized-branch>' so every branch gets its own entry and its own 'View deployment' button on PRs.
When a branch is deleted, mark each of its preview deployments inactive so the GitHub UI stops showing them as live, and delete the per-branch environment so it drops out of the Deployments sidebar. Both calls use the existing GH_TOKEN and are idempotent.
Bring docs/deployment.md in line with the updated workflow: per-branch preview environments, branch-keyed concurrency, inactive-then-delete cleanup, and the fact that CNAME is now part of the build output.
CNAME is now copied into dist/ by the build driver on production builds (see Task 1 of this PR), so the workflow no longer needs to restore it. The fallback was dead anyway — it referenced $../CNAME which does not exist because the publish job doesn't check out the source repo.
The workflow was being rejected by GitHub's YAML validator with no jobs
running ('This run likely failed because of a workflow file issue'):
administration is not a valid GITHUB_TOKEN permissions scope.
Deleting an environment requires repo-admin rights that the built-in
GITHUB_TOKEN cannot hold regardless of the permissions: block. Doing
this right would require a PAT-backed secret — out of scope for this
PR.
Keep the deactivation step, which does land via deployments: write and
is the more important hygiene improvement (it stops the UI from
claiming stale previews are live). Environment entries will remain in
the sidebar.
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.
Summary
Fixes four deployment issues surfaced right after the first merge to
main.github.ref. Adeleteoffeat/fooand apushtomainno longer share a group, so branch cleanup can't cancel a production deploy.dist/by the build driver on production builds (basePath === '/'). Previews never carry a CNAME. The workflow's dead fallback is removed.preview/<sanitized-branch>, surfaced in the repo Deployments UI and on PR pages.preview/<branch>asinactiveand DELETE the environment via the REST API. Unexpected API failures now surface as::warning::annotations rather than silent|| true.workflow_dispatchnow publishes (not just builds), so manual reruns work without pushing a dummy commit.Also: updated
docs/deployment.mdto match the new workflow; design spec and implementation plan committed undernotes/.Reviewer callouts
previewenvironment (gh api --method DELETE /repos/flexion/flexion.github.io/environments/preview). This workflow won't touch it.mainpush and a branchdeletecould race ongh-pages.cleanup-previewhas no retry. Low frequency; follow-up if we see flakes.Test plan
bun test tests/build/cname.test.ts— 2/2 pass locally (production build copies CNAME, preview does not).tests/catalog tests/standards tests/views tests/enhancements tests/build) — 67/67 pass locally.preview/fix-deployment-hygieneenvironment; URL https://labs.flexion.us/preview/fix-deployment-hygiene/ returns 200.labs.flexion.us/returns 200 andgh api repos/flexion/flexion.github.io/pagesreports"cname": "labs.flexion.us".inactive, andpreview/fix-deployment-hygienedisappears from the Deployments sidebar.maindeploys successfully (no concurrency collision with the cleanup run).