ea8d8eee9a
Test / test (pull_request) Successful in 35m33s
The wasm bundles in solitaire_server/web/pkg/ are no longer tracked. The web-wasm-rebuild workflow (which rebuilt them in CI and committed them back to master) is gone; instead: - solitaire_server/Dockerfile gains a wasm-builder stage that runs build_wasm.sh with the same pinned toolchain (wasm-bindgen 0.2.120, wasm-pack 0.14.0, binaryen 130) and the runtime image copies pkg/ from it — the image build is now the artifacts' single source of truth. - web-e2e builds the wasm before Playwright runs, and its trigger paths now include the wasm-feeding crates it actually tests. - docker-build triggers on solitaire_data/** and build_wasm.sh too, so every wasm-affecting change redeploys. - Self-hosters serving /web or /play from a source checkout run ./build_wasm.sh once (script header and ARCHITECTURE.md updated). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
101 lines
4.2 KiB
Bash
Executable File
101 lines
4.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Rebuild WASM artifacts and install them into solitaire_server/web/pkg/.
|
|
#
|
|
# Two artifacts are produced:
|
|
# solitaire_wasm.* — thin replay-viewer + interactive JS API (wasm-pack)
|
|
# canvas.* — full Bevy WASM app for play.html (cargo + wasm-bindgen)
|
|
#
|
|
# Prerequisites:
|
|
# cargo install wasm-pack wasm-bindgen-cli
|
|
# rustup target add wasm32-unknown-unknown
|
|
# (optional) cargo install wasm-opt # for smaller canvas_bg.wasm
|
|
#
|
|
# Run from the repo root:
|
|
# ./build_wasm.sh
|
|
#
|
|
# The generated pkg/ files are NOT committed to git (issue #156). CI builds
|
|
# them where needed: the Docker image's wasm-builder stage for deployment,
|
|
# and the web-e2e workflow for browser tests. Run this script locally before
|
|
# serving /web or /play from a source checkout.
|
|
|
|
set -euo pipefail
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
OUT_DIR="$REPO_ROOT/solitaire_server/web/pkg"
|
|
|
|
# Reproducible builds. The wasm artifacts otherwise bake in machine-specific
|
|
# absolute source paths (the cargo registry, the rustup std sources, and this
|
|
# checkout), so a rebuild on a different machine produces different bytes and
|
|
# the CI freshness gate (rebuild-and-diff) false-positives. Remap all three
|
|
# prefixes to fixed names so the output is byte-identical anywhere.
|
|
#
|
|
# We must use CARGO_ENCODED_RUSTFLAGS (not RUSTFLAGS) and re-state the
|
|
# getrandom backend cfg here: a `*_RUSTFLAGS` env var *replaces* — does not
|
|
# merge with — the `[target.wasm32-unknown-unknown] rustflags` in
|
|
# .cargo/config.toml, so dropping that cfg would break the wasm getrandom build.
|
|
# Keep this `--cfg` in sync with .cargo/config.toml.
|
|
CARGO_HOME_DIR="${CARGO_HOME:-$HOME/.cargo}"
|
|
RUSTUP_HOME_DIR="${RUSTUP_HOME:-$HOME/.rustup}"
|
|
US=$'\x1f' # unit separator: CARGO_ENCODED_RUSTFLAGS arg delimiter
|
|
export CARGO_ENCODED_RUSTFLAGS="--cfg${US}getrandom_backend=\"wasm_js\"${US}--remap-path-prefix=${CARGO_HOME_DIR}=/cargo${US}--remap-path-prefix=${RUSTUP_HOME_DIR}=/rustup${US}--remap-path-prefix=${REPO_ROOT}=/build"
|
|
|
|
if ! command -v wasm-pack &> /dev/null; then
|
|
echo "error: wasm-pack not found." >&2
|
|
echo " Install with: cargo install wasm-pack" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "Building solitaire_wasm (target: web)..."
|
|
wasm-pack build \
|
|
--target web \
|
|
--out-dir "$OUT_DIR" \
|
|
--no-typescript \
|
|
"$REPO_ROOT/solitaire_wasm"
|
|
|
|
# wasm-pack writes a package.json and .gitignore into the output dir.
|
|
# Remove them — we manage the output directory ourselves.
|
|
rm -f "$OUT_DIR/package.json" "$OUT_DIR/.gitignore"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Bevy WASM app (solitaire_web → canvas.js + canvas_bg.wasm)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
if ! command -v wasm-bindgen &> /dev/null; then
|
|
echo "error: wasm-bindgen not found." >&2
|
|
echo " Install with: cargo install wasm-bindgen-cli" >&2
|
|
echo " The CLI version must match the wasm-bindgen crate dep." >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "Building solitaire_web (Bevy WASM app)..."
|
|
# wasm-release is the size-focused profile (fat LTO, CGU=1, opt-level "s") —
|
|
# see [profile.wasm-release] in Cargo.toml. Download size is the constraint.
|
|
cargo build --profile wasm-release --target wasm32-unknown-unknown -p solitaire_web
|
|
|
|
echo "Running wasm-bindgen for solitaire_web..."
|
|
wasm-bindgen \
|
|
--out-dir "$OUT_DIR" \
|
|
--out-name canvas \
|
|
--target web \
|
|
--no-typescript \
|
|
"${CARGO_TARGET_DIR:-$REPO_ROOT/target}/wasm32-unknown-unknown/wasm-release/solitaire_web.wasm"
|
|
|
|
# Optional size optimisation — Bevy bundles are large (~5-15 MB uncompressed).
|
|
# wasm-opt passes are skipped silently when the tool is not installed.
|
|
if command -v wasm-opt &> /dev/null; then
|
|
echo "Running wasm-opt on canvas_bg.wasm..."
|
|
# Use -O2 (not -Oz): Bevy's render pipeline uses deep call stacks and
|
|
# complex memory patterns that wasm-opt -Oz can miscompile, resulting
|
|
# in a grey screen on first load. -O2 is speed-optimised and avoids
|
|
# the size-focused transforms that trigger the regression.
|
|
wasm-opt -O2 \
|
|
-o "$OUT_DIR/canvas_bg.wasm" \
|
|
"$OUT_DIR/canvas_bg.wasm"
|
|
else
|
|
echo "note: wasm-opt not found; skipping size optimisation."
|
|
echo " Install with: cargo install wasm-opt (or via binaryen)"
|
|
fi
|
|
|
|
echo "Done. Output:"
|
|
ls -lh "$OUT_DIR"
|