name: Web WASM Freshness # Guards against the committed solitaire_server/web/pkg/ artifacts going stale. # # A fresh build on a pinned toolchain is byte-for-byte reproducible (verified), # so this job rebuilds the artifacts and fails if they differ from what is # committed. Unlike a changed-files heuristic, this catches *any* drift in the # wasm-feeding crates — solitaire_core / _engine / _data / _sync / _wasm / _web — # including gameplay-logic changes that do not alter the JS API surface (e.g. # the v4->v5 save-schema change that the old heuristic let through as a # non-blocking "notice", leaving the deployed web build stale for ~3 weeks). # # Tool versions are pinned to whatever produced the committed artifacts. When # you regenerate the artifacts with a newer toolchain, bump these in lockstep: # rust 1.95.0 · wasm-bindgen 0.2.120 · wasm-pack 0.14.0 · binaryen 130 on: push: branches: [master] paths: - 'solitaire_core/**' - 'solitaire_engine/**' - 'solitaire_data/**' - 'solitaire_sync/**' - 'solitaire_wasm/**' - 'solitaire_web/**' - 'solitaire_server/web/pkg/**' - 'Cargo.toml' - 'Cargo.lock' - 'build_wasm.sh' - '.gitea/workflows/web-wasm-freshness.yml' pull_request: paths: - 'solitaire_core/**' - 'solitaire_engine/**' - 'solitaire_data/**' - 'solitaire_sync/**' - 'solitaire_wasm/**' - 'solitaire_web/**' - 'solitaire_server/web/pkg/**' - 'Cargo.toml' - 'Cargo.lock' - 'build_wasm.sh' - '.gitea/workflows/web-wasm-freshness.yml' workflow_dispatch: jobs: freshness: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Install Rust 1.95.0 (pinned for reproducible wasm output) uses: dtolnay/rust-toolchain@master with: toolchain: 1.95.0 targets: wasm32-unknown-unknown - name: Cache cargo build uses: Swatinem/rust-cache@v2 - name: Install wasm-bindgen-cli + wasm-pack (pinned) uses: taiki-e/install-action@v2 with: tool: wasm-bindgen-cli@0.2.120,wasm-pack@0.14.0 - name: Install binaryen 130 (wasm-opt, pinned) run: | set -euo pipefail curl -sSL \ https://github.com/WebAssembly/binaryen/releases/download/version_130/binaryen-version_130-x86_64-linux.tar.gz \ | tar xz echo "$PWD/binaryen-version_130/bin" >> "$GITHUB_PATH" - name: Rebuild WASM artifacts run: ./build_wasm.sh - name: Fail if committed pkg differs from a fresh build run: | set -euo pipefail if [ -z "$(git status --porcelain -- solitaire_server/web/pkg/)" ]; then echo "pkg/ artifacts match a fresh build." else echo "::error::solitaire_server/web/pkg/ is stale — a wasm-feeding crate changed without regenerating the artifacts." echo "Fix: run ./build_wasm.sh and commit the updated solitaire_server/web/pkg/." git status --porcelain -- solitaire_server/web/pkg/ git diff --stat -- solitaire_server/web/pkg/ exit 1 fi