Compare commits

...

4 Commits

Author SHA1 Message Date
funman300 f6e57b759e ci: pin toolchain to 1.95.0 and install Bevy native deps
Test / test (pull_request) Successful in 27m47s
Review feedback on #135: floating 'stable' + -D warnings lets every new
clippy release redden master with new lints — pin 1.95.0 like the
web-wasm-rebuild workflow. And ubuntu-latest lacks the ALSA/udev/X11/
Wayland dev packages the Bevy crates link against; install the standard
Bevy CI set (the project's own builder images have no desktop-Bevy
precedent — android-builder targets the NDK and web-e2e only builds the
server).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 16:28:28 -07:00
funman300 c9adcaa5e4 ci: add workspace clippy + test gate workflow
Test / test (pull_request) Failing after 1m35s
Until now no CI workflow ran the test suite or clippy at all — the
android-release, docker-build, web-e2e, web-wasm-rebuild, and
builder-image workflows cover packaging and e2e, but a direct push to
master (including the web-wasm-rebuild bot commit) never executed
cargo test or clippy. The gate discipline in CLAUDE.md §6 existed only
on developer machines.

test.yml runs the exact §6 commands (clippy --workspace --all-targets
-D warnings; cargo test --workspace) on master pushes and PRs, with
SQLX_OFFLINE against the checked-in .sqlx cache, path-filtered so
docs-only merges don't burn CI. Toolchain/cache mirror web-e2e.yml.

Found during the 2026-07-06 large-scale review (finding H1).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 16:21:19 -07:00
funman300 15bb136c79 Merge pull request 'perf(web): size-focused wasm-release profile for the canvas build (36.2 → 23.2 MB)' (#134) from perf/wasm-size-profile into master
Build and Deploy / build-and-push (push) Successful in 7m4s
Web E2E / web-e2e (push) Successful in 4m51s
Web WASM Rebuild / rebuild (push) Successful in 9m30s
2026-07-06 22:44:33 +00:00
funman300 16a1139eab perf(web): size-focused wasm-release profile for the canvas build
canvas_bg.wasm shipped at 36.2 MB — plain release (opt-level 3, thin
LTO) piped through wasm-opt -O2. Download size, not throughput, is the
binding constraint for the browser canvas, so solitaire_web now builds
with a dedicated wasm-release profile: opt-level "s", fat LTO, one
codegen unit. Local result: 23.2 MB after the unchanged wasm-opt -O2
pass — 35.9% smaller.

The binaryen pass stays at -O2 (the -Oz grey-screen miscompile note in
build_wasm.sh still applies). profile.strip is deliberately NOT set: on
wasm it also removes the target_features custom section, which makes
wasm-opt reject the module ('all used features should be allowed' on
trunc_sat).

Verified with the new artifact: all 5 play_canvas e2e specs pass (debug
bridge, draw3 param, apply/undo, replay diagnostics, 40-seed autoplay
invariants). Headless pixel verification is inconclusive in this
environment — wgpu cannot create a usable adapter locally and panics
identically on the OLD artifact too — so visual parity should be
confirmed against production after the next deploy.

pkg/ artifacts are intentionally not committed: the web-wasm-rebuild
workflow is the single source of truth and will regenerate them with
this profile on merge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 15:44:16 -07:00
3 changed files with 86 additions and 2 deletions
+66
View File
@@ -0,0 +1,66 @@
# Workspace gate: the same clippy + test commands CLAUDE.md §6 requires
# locally, run on every master push and pull request. Until this workflow
# existed, nothing in CI ran the test suite at all — a direct push to
# master (or the web-wasm-rebuild bot commit) was entirely unguarded.
name: Test
on:
push:
branches: [master]
paths:
- 'solitaire_app/**'
- 'solitaire_assetgen/**'
- 'solitaire_core/**'
- 'solitaire_data/**'
- 'solitaire_engine/**'
- 'solitaire_server/src/**'
- 'solitaire_server/tests/**'
- 'solitaire_server/migrations/**'
- 'solitaire_sync/**'
- 'solitaire_wasm/**'
- 'solitaire_web/**'
- 'Cargo.toml'
- 'Cargo.lock'
- '.cargo/**'
- '.sqlx/**'
- '.gitea/workflows/test.yml'
pull_request:
workflow_dispatch:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust 1.95.0
uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.95.0
components: clippy
- name: Cache cargo build
uses: Swatinem/rust-cache@v2
# Native link deps for the Bevy crates (engine/app/web) on a bare
# ubuntu runner: ALSA + udev for input/audio, X11 + Wayland for winit.
- name: Install Bevy native dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
libasound2-dev libudev-dev pkg-config libx11-dev libxcursor-dev \
libxrandr-dev libxi-dev libwayland-dev libxkbcommon-dev
# SQLX_OFFLINE uses the checked-in `.sqlx/` query cache (no live DB),
# same as the web-e2e workflow's server prebuild.
- name: Clippy (deny warnings)
env:
SQLX_OFFLINE: 'true'
run: cargo clippy --workspace --all-targets -- -D warnings
- name: Test
env:
SQLX_OFFLINE: 'true'
run: cargo test --workspace
+16
View File
@@ -156,3 +156,19 @@ opt-level = 3
[profile.release]
opt-level = 3
lto = "thin"
# Size-focused profile for the browser canvas build (solitaire_web →
# canvas_bg.wasm). Download size is the constraint on the web, not peak
# throughput: fat LTO + one codegen unit + opt-level "s" cut the Bevy wasm
# bundle substantially versus plain release. This is rustc-side sizing only —
# the binaryen pass in build_wasm.sh stays at wasm-opt -O2 because -Oz has
# miscompiled Bevy's render pipeline before (grey screen on first load).
[profile.wasm-release]
inherits = "release"
opt-level = "s"
lto = "fat"
codegen-units = 1
# No `strip`: on wasm it also removes the target_features custom section,
# which makes wasm-opt reject the module ("all used features should be
# allowed" on trunc_sat). wasm-opt drops the name section in its output
# anyway, so strip buys nothing here.
+4 -2
View File
@@ -67,7 +67,9 @@ if ! command -v wasm-bindgen &> /dev/null; then
fi
echo "Building solitaire_web (Bevy WASM app)..."
cargo build --release --target wasm32-unknown-unknown -p solitaire_web
# 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 \
@@ -75,7 +77,7 @@ wasm-bindgen \
--out-name canvas \
--target web \
--no-typescript \
"$REPO_ROOT/target/wasm32-unknown-unknown/release/solitaire_web.wasm"
"$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.