diff --git a/.gitignore b/.gitignore index bb06056..9b3ff31 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,6 @@ __pycache__/ # scratch test/tmp/ *.log + +# deploy secrets — never commit +deploy/.env diff --git a/README.md b/README.md index cb95f94..667f9b0 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ No dependencies. No build step. Vanilla JS + Canvas 2D. | **space** (hold) | grab two things and squeeze them together | | **Q** | heat — area shove, breaks every bond in radius (40% go homolytic) | | **R** | retry | +| **F** | frame-time readout (off by default) | | **shift+A** | jump straight to CASCADE | Aim at your own feet to charge **yourself** — that's how you go neutral and @@ -112,6 +113,33 @@ packing distance (or outbreaks never bloom); and `RAD_STARVE_TIME` / should die fast, but one merely adrift in a sparse early arena must not, or the outbreak evaporates unattended and the meltdown lose state disappears. +## Deploy + +```bash +./deploy/deploy.sh +``` + +Live at **https://monsterrobot.games/mollycool/**. Rsyncs `index.html` + `src/` +to the games VPS at `/home/humanjing/monsterrobot.games/games/mollycool` and +symlinks `mollycool -> games/mollycool` at the lander root, which is the +convention `not-tonight` already uses — no nginx change needed. + +Two traps it handles for you, both of which produce a *silent* dead title +screen rather than an error: + +- **forum-nginx mounts the lander read-only**, so `docker cp` fails quietly. + Always write the host path. (Same trap as beyondmorp V2.) +- **The dev server's `/v/` prefix is absolute.** In production it + falls through nginx's `try_files` to the *lander's* `index.html` and gets + served as `text/html`, which the browser refuses to execute as a module. + `index.html` only uses the prefix on localhost and ships a relative + specifier everywhere else. The script verifies the module's content-type, + not just the page's status code. + +Cloudflare serves the modules with `max-age=14400`, so the script purges the +deployed paths. Put `CF_API_TOKEN` in `deploy/.env` (gitignored) or you'll be +running four-hour-old code after a redeploy until you hard-reload. + ## Dev note `serve.py` strips a `/v/` prefix off request paths, and `index.html` diff --git a/deploy/deploy.sh b/deploy/deploy.sh index 47f0247..47f7926 100755 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -31,6 +31,38 @@ rsync -az --delete \ echo "==> ensuring the /mollycool route" ssh "$HOST" "ln -sfn games/mollycool '$LANDER/mollycool' && ls -ld '$LANDER/mollycool'" +# ---- Cloudflare purge -------------------------------------------------- +# CF fronts monsterrobot.games and serves the modules with max-age=14400, so +# without this a redeploy leaves you running four-hour-old code — the exact +# bug the dev server's /v/ prefix exists to prevent, just moved +# upstream. Token is read from disk at run time and never printed. +if [ -z "${CF_API_TOKEN:-}" ] && [ -f "$SRC/deploy/.env" ]; then + # shellcheck disable=SC1091 + set +u; . "$SRC/deploy/.env"; set -u + CF_API_TOKEN="${CF_API_TOKEN:-${CLOUDFLARE_API_TOKEN:-}}" +fi + +if [ -n "${CF_API_TOKEN:-}" ]; then + echo "==> purging cloudflare" + API=https://api.cloudflare.com/client/v4 + ZONE=$(curl -s -H "Authorization: Bearer $CF_API_TOKEN" \ + "$API/zones?name=monsterrobot.games" | sed -n 's/.*"id":"\([a-f0-9]\{32\}\)".*/\1/p' | head -1) + if [ -n "$ZONE" ]; then + files=$(cd "$SRC" && find index.html src -type f \ + | sed "s|^|\"https://monsterrobot.games/mollycool/|; s|$|\"|" | paste -sd, -) + ok=$(curl -s -X POST "$API/zones/$ZONE/purge_cache" \ + -H "Authorization: Bearer $CF_API_TOKEN" -H 'Content-Type: application/json' \ + --data "{\"files\":[$files]}" | grep -o '"success":true' || true) + [ -n "$ok" ] && echo " purged" || echo " !! purge failed — hard-reload to be sure" + else + echo " !! could not resolve zone id — hard-reload to be sure" + fi +else + echo "==> NO CF_API_TOKEN — skipping purge." + echo " Cloudflare holds the old JS for up to 4h. Hard-reload (cmd+shift+R)," + echo " or put CF_API_TOKEN in deploy/.env so this is automatic." +fi + echo "==> verifying live" STAMP="$(date +%s)" code=$(curl -s -o /dev/null -w '%{http_code}' "$URL?cb=$STAMP")