fix(pages): publish to scanner.registry.coder.com#13
Merged
Conversation
With GitHub Pages deployed via actions/deploy-pages, the custom-domain setting is restored from the CNAME file at the root of the uploaded artifact on every deploy. Without it, each scheduled scan silently wiped the Pages custom-domain binding. Vite copies the entire site/public/ tree verbatim into site/dist/, so putting CNAME here lands it at the root of the Pages artifact built by the scan workflow.
The production build hardcoded `/coder-skill-scanner/` as the asset base prefix (derived from $GITHUB_REPOSITORY). On a custom domain the site is served at the apex, so every asset URL 404s. resolveProductionBase() now checks public/CNAME and returns `/` when present. Forks without a CNAME keep the project-page behaviour. The change flows through automatically to: + asset URLs emitted by Vite + index.html %BASE_URL% substitutions (favicon, noscript link) + the rewrite-public-base-url plugin's 404.html SPA-fallback target + React Router's `basename`, which already uses import.meta.env.BASE_URL
Mirror the new vite.config.ts behaviour: when site/public/CNAME exists, the canonical Pages URL is https://<CNAME>, not the github.io project page. Carrying history from the canonical origin avoids a redirect hop and ensures the manifest URLs we mirror match the host the SPA fetches them from at runtime. PAGES_URL repo var override still takes precedence; only the fallback is newly CNAME-aware.
Also document the CNAME-as-source-of-truth convention so a fork only needs to edit (or delete) site/public/CNAME to control where its Pages site is served, with no workflow edits required.
There was a problem hiding this comment.
Pull request overview
This PR updates the GitHub Pages deployment so the scanner SPA and related URLs work correctly when served from the custom domain scanner.registry.coder.com (apex) instead of the default *.github.io/<repo>/ project path.
Changes:
- Add a Pages
CNAMEfile undersite/public/so it is included in the built Pages artifact. - Update the Vite production
baseresolution to use/when apublic/CNAMEis present. - Update history-carrying logic and public documentation to prefer the custom-domain host.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
site/vite.config.ts |
Adjusts production base-path resolution to return / when a custom domain (CNAME) is configured. |
site/public/CNAME |
Adds the custom domain so Pages can re-bind the domain from the deployed artifact. |
scanner/_carry_history.py |
Changes the default history-fetch origin to prefer the custom domain when configured. |
README.md |
Updates reader-facing URLs and documents the intended custom-domain configuration approach. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+25
to
+38
| def _default_base() -> str: | ||
| """Return the canonical Pages URL for this repo. | ||
|
|
||
| Prefer ``site/public/CNAME`` when present so a custom-domain deploy | ||
| fetches prior history from the same origin it will publish to. Fall | ||
| back to the github.io project-page URL otherwise. | ||
| """ | ||
| cname = Path("site/public/CNAME") | ||
| if cname.is_file(): | ||
| for line in cname.read_text(encoding="utf-8").splitlines(): | ||
| host = line.strip() | ||
| if host: | ||
| return f"https://{host}" | ||
| return DEFAULT_BASE_FALLBACK |
Comment on lines
+84
to
+91
| For a fork, swap the host: `https://<your-host>/api/v1/...`. The scanner | ||
| picks the public base URL at publish time in this order: | ||
|
|
||
| 1. `site/public/CNAME` (the custom Pages domain, if set), | ||
| 2. otherwise `$GITHUB_REPOSITORY` -> `https://<owner>.github.io/<repo>`. | ||
|
|
||
| So a fork that just sets a CNAME gets the right URLs everywhere without | ||
| touching workflow code. |
Comment on lines
+40
to
+42
| if (fs.existsSync(path.resolve("public", "CNAME"))) { | ||
| return "/"; | ||
| } |
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 this does
Makes
scanner.registry.coder.comactually work as the Pages host. Two real things were keeping the site dark on the custom domain:actions/upload-pages-artifact+actions/deploy-pages. With that flow, the custom-domain binding is restored from theCNAMEfile at the root of the uploaded artifact on every deploy. There was noCNAMEanywhere in the repo, so every 6-hour scheduled scan silently wiped the Pages custom-domain setting./coder-skill-scanner/. vite.config.ts'sresolveProductionBase()derived the prefix from$GITHUB_REPOSITORY, which is correct forcoder.github.io/coder-skill-scanner/but wrong for a custom domain where the site lives at the apex. Every asset URL, the React Routerbasename, and the404.htmlSPA-fallback all 404'd on the new host.Fix: make
site/public/CNAMEthe single source of truth for whether a custom domain is configured. Everything that needs to know reads from it.Changes
site/public/CNAME(new) —scanner.registry.coder.com. Vite copiessite/public/verbatim intosite/dist/, so the CNAME lands at the root of the Pages artifact built by the scan workflow with zero workflow changes.actions/deploy-pagesreads it from the artifact root and configures the custom-domain binding on every deploy.site/vite.config.ts—resolveProductionBase()now checkspublic/CNAMEfirst and returns/when present. The change flows through automatically to:dist/index.html,index.html's%BASE_URL%substitutions (favicon, noscript link),rewrite-public-base-urlVite plugin's404.htmlSPA-fallback rewrite,basename, which already usesimport.meta.env.BASE_URL.scanner/_carry_history.py— the_default_base()fallback also readsCNAMEso theRestore prior historystep mirrors snapshots from the canonical custom-domain origin instead of bouncing through a github.io redirect. Thevars.PAGES_URLrepo-var override still wins.README.md— every reader-facing URL now points atscanner.registry.coder.com. The Forking section documents the CNAME-as-source-of-truth contract so a fork only needs to edit (or delete)site/public/CNAMEto control where its Pages site is served, no workflow edits required.Why no workflow change in this PR
The site works on
scanner.registry.coder.comend-to-end with just the changes above. There's one nice-to-have in.github/workflows/scan.yamlthat I couldn't push because the GitHub App backing my tooling doesn't have theworkflowspermission — GitHub returns 404 on workflow-file writes for those tokens, by design.The leftover hardcoded
github.ioURLs are in two places:publish-release → Create timestamped releasestep (release notes string),publish-pages → Build pages treestep (--public-base-urlpassed toscanner build-api-v1, which embeds it inlinks.status_badge_svgand friends inside the v1 per-skill detail JSON).Both keep working because GitHub Pages issues a 301 from the github.io project-page URL to the custom domain once CNAME is live. But the URLs embedded in the v1 API responses should be canonical so shields.io endpoint mode and downstream cached badge consumers don't follow a redirect.
Please apply the following patch yourself (it's the same pattern in both jobs, factored into a
Resolve canonical Pages URLstep inpublish-releaseand inlined inpublish-pages):Workflow patch (apply locally and commit to this branch)
Replace the
publish-release → Create timestamped releasestep with:And in
publish-pages → Build pages tree, replace:With:
After merge
Dispatch the
scanworkflow once (or wait for the next 6h cron). The Build SPA step will emit a/-based bundle, the artifact will containCNAMEat its root, andactions/deploy-pageswill rebindscanner.registry.coder.com. Confirm:https://scanner.registry.coder.com/renders the SPA.scanner.registry.coder.comand "DNS check successful".https://coder.github.io/coder-skill-scanner/301s to the new host.If the Pages settings were previously cleared by a wiped deploy, re-entering the domain there is not needed — the CNAME-in-artifact restores it. DNS is the user's responsibility (you said it's already pointed at
coder.github.io, which is correct).This PR was prepared with help from Coder Agents.