deploy: purge cloudflare, document the two silent-failure traps
Cloudflare fronts monsterrobot.games and serves the modules with max-age=14400, so a redeploy left you running four-hour-old code — the same staleness the dev server's /v<timestamp>/ prefix exists to prevent, just moved upstream. deploy.sh now purges the deployed paths, reading CF_API_TOKEN from deploy/.env (gitignored) at run time, and warns loudly rather than failing when it isn't set. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
83ed074175
commit
6466973f4e
3
.gitignore
vendored
3
.gitignore
vendored
@ -16,3 +16,6 @@ __pycache__/
|
|||||||
# scratch
|
# scratch
|
||||||
test/tmp/
|
test/tmp/
|
||||||
*.log
|
*.log
|
||||||
|
|
||||||
|
# deploy secrets — never commit
|
||||||
|
deploy/.env
|
||||||
|
|||||||
28
README.md
28
README.md
@ -21,6 +21,7 @@ No dependencies. No build step. Vanilla JS + Canvas 2D.
|
|||||||
| **space** (hold) | grab two things and squeeze them together |
|
| **space** (hold) | grab two things and squeeze them together |
|
||||||
| **Q** | heat — area shove, breaks every bond in radius (40% go homolytic) |
|
| **Q** | heat — area shove, breaks every bond in radius (40% go homolytic) |
|
||||||
| **R** | retry |
|
| **R** | retry |
|
||||||
|
| **F** | frame-time readout (off by default) |
|
||||||
| **shift+A** | jump straight to CASCADE |
|
| **shift+A** | jump straight to CASCADE |
|
||||||
|
|
||||||
Aim at your own feet to charge **yourself** — that's how you go neutral and
|
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
|
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.
|
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<timestamp>/` 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
|
## Dev note
|
||||||
|
|
||||||
`serve.py` strips a `/v<timestamp>/` prefix off request paths, and `index.html`
|
`serve.py` strips a `/v<timestamp>/` prefix off request paths, and `index.html`
|
||||||
|
|||||||
@ -31,6 +31,38 @@ rsync -az --delete \
|
|||||||
echo "==> ensuring the /mollycool route"
|
echo "==> ensuring the /mollycool route"
|
||||||
ssh "$HOST" "ln -sfn games/mollycool '$LANDER/mollycool' && ls -ld '$LANDER/mollycool'"
|
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<timestamp>/ 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"
|
echo "==> verifying live"
|
||||||
STAMP="$(date +%s)"
|
STAMP="$(date +%s)"
|
||||||
code=$(curl -s -o /dev/null -w '%{http_code}' "$URL?cb=$STAMP")
|
code=$(curl -s -o /dev/null -w '%{http_code}' "$URL?cb=$STAMP")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user