magicciv/tools/deploy-guide.sh
Natalie 2d9554d9ff feat(@projects): update wasm build and guide deployment workflows
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-04-17 13:06:14 -07:00

90 lines
3.8 KiB
Bash
Executable file

#!/usr/bin/env bash
# Build + deploy the player guide (Age of Dwarves).
#
# Usage:
# tools/deploy-guide.sh build Build only — dist/ ready under the guide package
# tools/deploy-guide.sh serve [port] Build + serve locally (default port 5801)
# tools/deploy-guide.sh apricot [version] Build + rsync to apricot:~/public/guide/<version>/
# tools/deploy-guide.sh zip [version] Build + zip dist/ into .local/guide-<version>.zip
#
# WASM prerequisite: .local/build/wasm/magic_civ_physics.js must exist.
# (Build output never under src/ — see .claude/instructions/build-output-locations.md.)
# If the guide's `@magic-civ/physics-rs` alias can't resolve, the build fails.
# Rebuild via: ssh "$AUTOPLAY_HOST" "cd $PROJECT_ROOT_REMOTE/src/simulator && bash build-wasm.sh"
# (per CLAUDE.md Two-Host Workflow — WASM is an apricot-side artifact)
# or locally via: (cd src/simulator && bash build-wasm.sh).
#
# External hosting (GitHub Pages / S3 / Cloudflare Pages) is TODO: no public
# host has been committed for Early Access. Until that decision lands, `zip`
# produces a publishable artifact the team can hand to whichever host wins.
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
GUIDE_DIR="$REPO_ROOT/public/games/age-of-dwarves/guide"
DIST_DIR="$GUIDE_DIR/dist"
PKG_NAME="@magic-civilization/guide-age-of-dwarves"
mode="${1:-build}"
_run_build() {
if [ ! -f "$REPO_ROOT/.local/build/wasm/magic_civ_physics.js" ]; then
echo -e "${YELLOW}warning: .local/build/wasm/magic_civ_physics.js missing — WASM may not be built.${NC}"
echo -e "${YELLOW} Rebuild via: ssh \"\$AUTOPLAY_HOST\" 'cd \$PROJECT_ROOT_REMOTE/src/simulator && bash build-wasm.sh'${NC}"
echo -e "${YELLOW} or locally: (cd src/simulator && bash build-wasm.sh)${NC}"
fi
echo -e "${BLUE}Building $PKG_NAME ...${NC}"
(cd "$REPO_ROOT" && pnpm --filter "$PKG_NAME" build)
if [ ! -f "$DIST_DIR/index.html" ]; then
echo -e "${RED}✗ dist/index.html not generated — build reported success but produced no output.${NC}"
return 1
fi
local size
size="$(du -sh "$DIST_DIR" | cut -f1)"
echo -e "${GREEN}✓ dist/ ready ($size)${NC}"
}
case "$mode" in
build)
_run_build
;;
serve)
port="${2:-5801}"
_run_build
echo -e "${BLUE}Serving $DIST_DIR on http://localhost:$port ${NC}"
echo -e "${YELLOW}(Ctrl-C to stop)${NC}"
(cd "$DIST_DIR" && exec python3 -m http.server "$port")
;;
apricot)
version="${2:-$(date +%Y%m%d_%H%M%S)}"
: "${AUTOPLAY_HOST:=lilith@apricot.local}"
_run_build
echo -e "${BLUE}Rsyncing dist/ → $AUTOPLAY_HOST:~/public/guide/$version/${NC}"
ssh "$AUTOPLAY_HOST" "mkdir -p \$HOME/public/guide/$version"
rsync -az --delete "$DIST_DIR/" "$AUTOPLAY_HOST:\$HOME/public/guide/$version/"
echo -e "${GREEN}✓ Deployed to $AUTOPLAY_HOST:~/public/guide/$version/${NC}"
echo -e "${YELLOW}Serve it remotely: ssh $AUTOPLAY_HOST 'cd ~/public/guide/$version && python3 -m http.server 8080'${NC}"
;;
zip)
version="${2:-$(date +%Y%m%d_%H%M%S)}"
out_dir="$REPO_ROOT/.local/build/guide"
mkdir -p "$out_dir"
archive="$out_dir/guide-age-of-dwarves-$version.zip"
_run_build
echo -e "${BLUE}Zipping dist/ → $archive ${NC}"
(cd "$DIST_DIR" && zip -qr "$archive" .)
local_size="$(du -h "$archive" | cut -f1)"
echo -e "${GREEN}✓ Archive ready: $archive ($local_size)${NC}"
;;
*)
echo -e "${RED}Unknown mode: $mode${NC}"
echo "Usage: $0 {build|serve [port]|apricot [version]|zip [version]}"
exit 1
;;
esac