diff --git a/AGENTS.md b/AGENTS.md index c45f361..f1d8c48 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -84,7 +84,7 @@ Each component adds one `Entry` in `gallery/demos_.go`: ID, Name, Zh, ## Deploy -- `npm run deploy` in `web/` (clean tree only): builds, uploads a Worker version, runs Playwright on its preview URL, promotes it to 100%, runs Playwright on https://8bitmygoui.zhangyanghaha0407.workers.dev. +- `npm run deploy` in `web/` (clean tree only) ships in two steps, because a rollout serves old and new versions side by side for a while. Step one promotes the live `index.html` with the new files beside the live ones; step two uploads the new page with both file sets, runs Playwright on its preview URL, promotes it, and runs Playwright on https://8bitmygoui.zhangyanghaha0407.workers.dev. A page from either build then finds its files on either version. - Rollback: `npx wrangler rollback ` in `web/`; `npx wrangler deployments list` shows versions. - Scripts and wasm sit under `a/`, named by content hash, and `_headers` makes them immutable; `index.html` revalidates. Never cache a path whose content can change. diff --git a/web/deploy.sh b/web/deploy.sh index 2f824df..55ff6e8 100755 --- a/web/deploy.sh +++ b/web/deploy.sh @@ -1,36 +1,60 @@ #!/bin/sh -# Uploads a version, tests its preview URL, then promotes it. +# Ships files first, then the page: no build misses a file. set -eu cd "$(dirname "$0")" +site=https://8bitmygoui.zhangyanghaha0407.workers.dev if [ -n "$(git status --porcelain)" ]; then echo "deploy: commit first; each version names its commit" >&2 exit 1 fi -./build.sh -rev=$(git rev-parse --short HEAD) -out=$(npx wrangler versions upload --message "$rev") -echo "$out" -id=$(echo "$out" | sed -n 's/^Worker Version ID: //p') -preview=$(echo "$out" | sed -n 's/^Version Preview URL: //p') -if [ -z "$id" ] || [ -z "$preview" ]; then - echo "deploy: wrangler printed no version id or preview URL" >&2 - exit 1 -fi -BASE_URL=$preview npx playwright test -npx wrangler versions deploy "$id@100%" --yes --message "$rev" -site=$(echo "$preview" | sed 's#https://[0-9a-f]*-#https://#') -main=$(sed -n 's#.*src="\(a/main\.[0-9a-f]*\.js\)".*#\1#p' dist/index.html) -tries=0 -until curl -fs "$site/" | grep -q "$main"; do - tries=$((tries + 1)) - if [ "$tries" -ge 30 ]; then - echo "deploy: $site still serves an older build than $main" >&2 +# patient runs a check every 2 s for a minute. +patient() { + tries=0 + until "$@"; do + tries=$((tries + 1)) + if [ "$tries" -ge 30 ]; then + echo "deploy: gave up waiting for: $*" >&2 + exit 1 + fi + sleep 2 + done +} +# upload makes a version from the assets in $1. +upload() { + out=$(npx wrangler versions upload --assets "$1" --message "$2") + echo "$out" >&2 + id=$(echo "$out" | sed -n 's/^Worker Version ID: //p') + preview=$(echo "$out" | sed -n 's/^Version Preview URL: //p') + if [ -z "$id" ] || [ -z "$preview" ]; then + echo "deploy: wrangler printed no version id or preview URL" >&2 exit 1 fi - sleep 2 +} +./build.sh +rev=$(git rev-parse --short HEAD) +main=$(sed -n 's#.*src="\(a/main\.[0-9a-f]*\.js\)".*#\1#p' dist/index.html) +stage=$(mktemp -d) +trap 'rm -rf "$stage"' EXIT +# The live build's files ride along, for pages already open. +if ! curl -fs "$site/" -o "$stage/index.html"; then + echo "deploy: cannot read the live page at $site" >&2 + exit 1 +fi +for f in $(sed -n 's#.*src="\(a/[^"]*\)".*#\1#p' "$stage/index.html"); do + curl -fs "$site/$f" -o "dist/$f" done -# A first fetch warms the edge before the browser tests. -wasm=$(sed -n "s#.*fetch('\\(a/app\\.[0-9a-f]*\\.wasm\\)').*#\\1#p" dist/a/main.*.js) -curl -fs --max-time 120 -o /dev/null "$site/$wasm" +old=$(sed -n 's#.*src="\(a/main\.[0-9a-f]*\.js\)".*#\1#p' "$stage/index.html") +wasm=$(sed -n "s#.*fetch('\\(a/app\\.[0-9a-f]*\\.wasm\\)').*#\\1#p" "dist/$old") +curl -fs --max-time 300 "$site/$wasm" -o "dist/$wasm" +cp -R dist/a dist/_headers "$stage/" +# Step one: the live page, with the new files beside it. +upload "$stage" "$rev files" +npx wrangler versions deploy "$id@100%" --yes --message "$rev files" +patient curl -fs -o /dev/null "$site/$main" +# Step two: the new page, tested on its preview first. +upload ./dist "$rev" +BASE_URL=$preview npx playwright test +npx wrangler versions deploy "$id@100%" --yes --message "$rev" +patient sh -c "curl -fs '$site/' | grep -q '$main'" BASE_URL=$site npx playwright test echo "deploy: $rev live at $site (version $id)"