sitemap.xml was 404 on the live host; make the build own it

sitemap.mjs was a step I ran by hand, so the moment I rebuilt without it the
file vanished from dist and the deploy shipped a site with no sitemap — on a
site whose entire point is being findable. Nothing caught it because nothing
was looking.

It is now inside `pnpm build`, CI asserts the file exists, and deploy.sh
smoke-tests /sitemap.xml, /robots.txt and an OG card against the live hostname.
The 404 assertion was also a warning rather than a failure; it exits now.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019mt6sHQHEnEYrJZvoMCJSB
This commit is contained in:
karti-ai
2026-08-28 16:48:50 -07:00
parent 1ace52b2ab
commit c4bf0c197e
3 changed files with 13 additions and 2 deletions
+4
View File
@@ -48,6 +48,10 @@ jobs:
grep -qv 'PIG Demo — RL environments you can play</title>' dist/demos/wordle/index.html \ grep -qv 'PIG Demo — RL environments you can play</title>' dist/demos/wordle/index.html \
|| { echo "demo route kept the homepage title"; exit 1; } || { echo "demo route kept the homepage title"; exit 1; }
test -f dist/404.html || { echo "no 404.html"; exit 1; } test -f dist/404.html || { echo "no 404.html"; exit 1; }
# sitemap.xml is written by a build step, not by Vite copying public/.
# It went missing once because the step was outside `pnpm build`, and
# nothing noticed until a 404 on the live host.
test -f dist/sitemap.xml || { echo "no sitemap.xml"; exit 1; }
# A blob-backed worker is blocked in production and nowhere else: the # A blob-backed worker is blocked in production and nowhere else: the
# site's CSP has no worker-src, so it falls back to default-src 'self'. # site's CSP has no worker-src, so it falls back to default-src 'self'.
+8 -1
View File
@@ -22,6 +22,7 @@ cd "$(dirname "$0")/.."
# The prerender pass is what makes shared links preview correctly. A dist # The prerender pass is what makes shared links preview correctly. A dist
# without it builds and serves fine, which is exactly why it needs asserting. # without it builds and serves fine, which is exactly why it needs asserting.
[ -f dist/404.html ] || { echo "dist/404.html missing — did prerender run?"; exit 1; } [ -f dist/404.html ] || { echo "dist/404.html missing — did prerender run?"; exit 1; }
[ -f dist/sitemap.xml ] || { echo "dist/sitemap.xml missing — run 'pnpm build', not 'vite build'"; exit 1; }
echo "==> preflight on ${HOST}" echo "==> preflight on ${HOST}"
ssh "$HOST" "set -e ssh "$HOST" "set -e
@@ -60,6 +61,12 @@ grep -q 'og:title' /tmp/pigdemo-demo.html || { echo "FAILED: demo route has no b
missing=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 30 "$URL/nope-not-a-page") missing=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 30 "$URL/nope-not-a-page")
echo " /nope-not-a-page -> $missing" echo " /nope-not-a-page -> $missing"
[ "$missing" = "404" ] || { echo "WARNING: unknown path returned $missing, expected 404"; } [ "$missing" = "404" ] || { echo "FAILED: unknown path returned $missing, expected 404"; exit 1; }
for path in /sitemap.xml /robots.txt /og/wordle.png; do
code=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 30 "$URL$path")
echo " $path -> $code"
[ "$code" = "200" ] || { echo "FAILED: $path returned $code"; exit 1; }
done
echo "==> live: $URL" echo "==> live: $URL"
+1 -1
View File
@@ -10,7 +10,7 @@
"packageManager": "pnpm@11.21.0", "packageManager": "pnpm@11.21.0",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "tsc --noEmit && vite build && node scripts/prerender.mjs", "build": "tsc --noEmit && vite build && node scripts/prerender.mjs && node scripts/sitemap.mjs",
"preview": "vite preview --port 4173", "preview": "vite preview --port 4173",
"typecheck": "tsc --noEmit", "typecheck": "tsc --noEmit",
"test": "tsx --test src/demos/*/__tests__/*.test.ts", "test": "tsx --test src/demos/*/__tests__/*.test.ts",