2026-04-17 14:54:14 -07:00
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
|
# Deploy commands: guide:next (dev guide to mc.next.black.local).
|
|
|
|
|
|
#
|
|
|
|
|
|
# This module is Tourguide-owned (see .project/team-leads/tourguide.md).
|
|
|
|
|
|
#
|
|
|
|
|
|
# Host configuration (from .env or shell rc):
|
|
|
|
|
|
# NEXT_DEPLOY_HOST — SSH target for mc.next.black.local static root.
|
|
|
|
|
|
# Default: "lilith@black.local".
|
|
|
|
|
|
# NEXT_DEPLOY_PATH — destination directory on the remote host.
|
|
|
|
|
|
# Default: "/bigdisk/next/mc/".
|
|
|
|
|
|
#
|
|
|
|
|
|
# The target host-nginx vhost + bind-mount are set up in
|
|
|
|
|
|
# `/bigdisk/nginx/nginx.conf` + `/bigdisk/nginx/docker-compose.yml` on
|
|
|
|
|
|
# black.local. Infra + objective: p1-15.
|
|
|
|
|
|
|
|
|
|
|
|
: "${NEXT_DEPLOY_HOST:=lilith@black.local}"
|
|
|
|
|
|
: "${NEXT_DEPLOY_PATH:=/bigdisk/next/mc/}"
|
|
|
|
|
|
|
2026-04-17 15:36:01 -07:00
|
|
|
|
# Bake-simcache scenarios. Empty = skip bake step entirely in `deploy:guide:next`.
|
|
|
|
|
|
# Comma-separated list = bake those scenarios after `pnpm build`. `all` = every
|
|
|
|
|
|
# canonical scenario (1.1 GB × 6 ≈ 6.6 GB; minutes to bake). Default: empty
|
|
|
|
|
|
# (deploy ships only the client-WASM fallback path).
|
|
|
|
|
|
: "${DEPLOY_BAKE_SCENARIOS:=}"
|
|
|
|
|
|
|
|
|
|
|
|
cmd_bake_simcache() {
|
|
|
|
|
|
# `./run bake:simcache [ids…]` — pre-compute sim-cache frames into dist/.
|
|
|
|
|
|
# Pass scenario ids (space- or comma-separated) or the string `all`.
|
|
|
|
|
|
# Used standalone (post-`pnpm build`) or invoked from cmd_deploy_guide_next.
|
|
|
|
|
|
local scenarios="${1:-all}"; shift || true
|
|
|
|
|
|
if [ "$scenarios" = "all" ]; then
|
|
|
|
|
|
scenarios="" # empty arg list = bake-simcache defaults to ALL_SCENARIO_IDS
|
|
|
|
|
|
else
|
|
|
|
|
|
scenarios="${scenarios//,/ }"
|
|
|
|
|
|
fi
|
|
|
|
|
|
if [ ! -d "$GUIDE_DIR/dist" ]; then
|
|
|
|
|
|
echo -e "${RED}✗ $GUIDE_DIR/dist missing — run \`pnpm build\` first, then \`./run bake:simcache\`.${NC}"
|
|
|
|
|
|
return 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
echo -e "${BLUE}Baking sim-cache frames into $GUIDE_DIR/dist/__sim-cache/${NC}"
|
|
|
|
|
|
# shellcheck disable=SC2086
|
|
|
|
|
|
(cd "$GUIDE_DIR" && node --import tsx/esm tools/bake-simcache.ts $scenarios)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-17 14:54:14 -07:00
|
|
|
|
cmd_deploy_guide_next() {
|
|
|
|
|
|
# Build the dev bundle (all EpisodeGate subtrees visible) + rsync to black.
|
|
|
|
|
|
# Safe to run repeatedly — rsync --delete replaces the target dir with dist/.
|
|
|
|
|
|
|
|
|
|
|
|
# Prerequisite: WASM artifact present locally. The Vite build imports from
|
|
|
|
|
|
# the @magic-civ/physics-rs alias which resolves to .local/build/wasm/.
|
|
|
|
|
|
if [ ! -f "$REPO_ROOT/.local/build/wasm/magic_civ_physics.js" ]; then
|
|
|
|
|
|
echo -e "${RED}✗ .local/build/wasm/magic_civ_physics.js missing — can't build guide.${NC}"
|
|
|
|
|
|
echo -e "${RED} Build locally: (cd src/simulator && bash build-wasm.sh)${NC}"
|
|
|
|
|
|
echo -e "${RED} Or rsync from apricot:${NC}"
|
|
|
|
|
|
echo -e "${RED} rsync -a \"\$AUTOPLAY_HOST\":\"\$PROJECT_ROOT_REMOTE\"/.local/build/wasm/ .local/build/wasm/${NC}"
|
|
|
|
|
|
return 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
2026-04-17 15:36:01 -07:00
|
|
|
|
echo -e "${BLUE}[1/5] Building dev bundle (VITE_DEV_GUIDE=1 pnpm build)...${NC}"
|
2026-04-17 14:54:14 -07:00
|
|
|
|
if ! (cd "$GUIDE_DIR" && VITE_DEV_GUIDE=1 pnpm build 2>&1); then
|
|
|
|
|
|
echo -e "${RED}✗ pnpm build failed${NC}"
|
|
|
|
|
|
return 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
local dist="$GUIDE_DIR/dist"
|
|
|
|
|
|
if [ ! -f "$dist/index.html" ]; then
|
|
|
|
|
|
echo -e "${RED}✗ $dist/index.html not produced — build reported success but emitted no bundle.${NC}"
|
|
|
|
|
|
return 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
local size
|
|
|
|
|
|
size="$(du -sh "$dist" | cut -f1)"
|
|
|
|
|
|
echo -e "${GREEN}✓ dist/ ready ($size)${NC}"
|
|
|
|
|
|
|
2026-04-17 15:36:01 -07:00
|
|
|
|
if [ -n "$DEPLOY_BAKE_SCENARIOS" ]; then
|
|
|
|
|
|
echo -e "${BLUE}[2/5] Baking sim-cache scenarios: $DEPLOY_BAKE_SCENARIOS${NC}"
|
|
|
|
|
|
if ! cmd_bake_simcache "$DEPLOY_BAKE_SCENARIOS"; then
|
|
|
|
|
|
echo -e "${RED}✗ bake-simcache failed${NC}"
|
|
|
|
|
|
return 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
size="$(du -sh "$dist" | cut -f1)"
|
|
|
|
|
|
echo -e "${GREEN}✓ dist/ with baked frames ($size)${NC}"
|
|
|
|
|
|
else
|
|
|
|
|
|
echo -e "${YELLOW}[2/5] DEPLOY_BAKE_SCENARIOS unset — skipping sim-cache bake (client-WASM fallback in browser).${NC}"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo -e "${BLUE}[3/5] Verifying SSH to $NEXT_DEPLOY_HOST...${NC}"
|
2026-04-17 14:54:14 -07:00
|
|
|
|
if ! ssh -o ConnectTimeout=5 -o BatchMode=yes "$NEXT_DEPLOY_HOST" "test -d $NEXT_DEPLOY_PATH && echo ok" >/dev/null 2>&1; then
|
|
|
|
|
|
echo -e "${RED}✗ can't reach $NEXT_DEPLOY_HOST:$NEXT_DEPLOY_PATH (VPN or permissions).${NC}"
|
|
|
|
|
|
return 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
echo -e "${GREEN}✓ reachable${NC}"
|
|
|
|
|
|
|
2026-04-17 15:36:01 -07:00
|
|
|
|
echo -e "${BLUE}[4/5] Rsyncing dist/ → $NEXT_DEPLOY_HOST:$NEXT_DEPLOY_PATH${NC}"
|
2026-04-17 14:54:14 -07:00
|
|
|
|
if ! rsync -az --delete "$dist/" "$NEXT_DEPLOY_HOST:$NEXT_DEPLOY_PATH"; then
|
|
|
|
|
|
echo -e "${RED}✗ rsync failed${NC}"
|
|
|
|
|
|
return 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
echo -e "${GREEN}✓ deployed${NC}"
|
|
|
|
|
|
|
2026-04-17 15:36:01 -07:00
|
|
|
|
echo -e "${BLUE}[5/5] Probing https://mc.next.black.local ...${NC}"
|
2026-04-17 14:54:14 -07:00
|
|
|
|
local http_status
|
|
|
|
|
|
http_status="$(curl -sk -o /dev/null -w "%{http_code}" --max-time 10 https://mc.next.black.local)"
|
|
|
|
|
|
if [ "$http_status" = "200" ]; then
|
|
|
|
|
|
echo -e "${GREEN}✓ https://mc.next.black.local → HTTP 200${NC}"
|
|
|
|
|
|
else
|
|
|
|
|
|
echo -e "${YELLOW}! https://mc.next.black.local → HTTP $http_status (expected 200)${NC}"
|
|
|
|
|
|
echo -e "${YELLOW} Deploy may still be correct; check the vhost config on $NEXT_DEPLOY_HOST.${NC}"
|
|
|
|
|
|
return 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo -e "${GREEN}Deployed dev guide to https://mc.next.black.local${NC}"
|
|
|
|
|
|
}
|