openpencil/.github/workflows/web-sdk-bundle.yml
Kayshen-X ace4c7257e feat(web): fetch preview assets at runtime instead of embedding them
The preview JPEGs (~2.4 MiB, already compressed so gzip passed them
straight through) leave the wasm data segment: a platform-free asset
registry in op-editor-core tracks per-route Absent/Pending/Ready/Failed
with single-flight and install-once semantics, the browser half fetches
over ArrayBuffer XHR with managed-mode headers and a slot-wrapped
callback so no synchronous failure can strand a route in Pending, and
paint sites fall back to the existing placeholder when bytes are not
(yet) there. Native keeps include_bytes verbatim. The staging script
copies the asset dirs into pkg/assets/ — under /pkg/ because the hub
frontend owns /assets/ — and the gate, CI workflow, and web image all
run it and assert the layout. Bundle: 7.13 → 5.10 MiB gzip, so the
tripwire returns to 6 MiB (85% occupancy); the sdk bundle keeps its own
8 MiB pending a real measurement.

Also closes the final review test gaps: the owner-session fixture now
returns a must-use lane guard (a dropped receiver made the saturated
lane read as Disconnected, not Full) and seeds the daemon's baseline
document so the hash check exercises the real path, and the closed
write barrier has a direct multi-page active-page regression test.
2026-08-09 01:37:06 +08:00

117 lines
5 KiB
YAML

name: op-web-sdk bundle build + size gate
# Builds the op-web-sdk WASM package (canvaskit feature), asserts 0 env.*
# imports and gzip size <= 8 MiB (this viewer bundle's own tripwire — op-host-web
# re-baselined to 6 MiB separately), then uploads pkg/ as the `op-web-sdk-bundle`
# artifact. This is the CI counterpart of the local
# `crates/op-web-sdk/tools/build-wasm.sh` developer gate.
#
# Mirrors `wasm-bundle-build.yml` (op-host-web gate) verbatim except for the
# crate path, artifact name, and env-var ceiling override name. In particular,
# this job does NOT use wasm-pack: wasm-pack 0.13.1 is broken on stable Rust
# (schema mismatch) and introduces a floating binary install risk. Instead we
# use the same cargo + wasm-bindgen-cli (version-pinned from Cargo.lock) +
# wasm-opt pipeline that `wasm-bundle-build.yml` uses.
#
# Authoritative recipe mirrored from `crates/op-web-sdk/tools/build-wasm.sh`:
# prerequisites: cargo, wasm-bindgen, wasm-opt, node, gzip (NO wasm-pack, NO EMSDK)
# 1. cargo build -p op-web-sdk --target wasm32-unknown-unknown
# --features canvaskit --release
# 2. wasm-bindgen --target web --out-dir crates/op-web-sdk/pkg <target.wasm>
# 3. assert 0 env.* imports (LinkError guard)
# 4. wasm-opt -Oz with rustc-emitted WebAssembly feature flags, then
# gzip size <= ceiling (default 8388608 bytes = 8 MiB, overridable via
# OP_WEB_SDK_WASM_GZIP_LIMIT_BYTES)
# The job calls the script directly — it is the single source of truth for the
# gate logic.
on:
pull_request:
paths:
- 'Cargo.toml'
- 'Cargo.lock'
- 'crates/op-web-sdk/**'
- 'deny.toml'
- '.github/workflows/web-sdk-bundle.yml'
push:
branches: ['**']
paths:
- 'Cargo.toml'
- 'Cargo.lock'
- 'crates/op-web-sdk/**'
- '.github/workflows/web-sdk-bundle.yml'
# Allow on-demand runs so a release can produce the artifact without a code
# change (e.g. to re-bundle against an updated toolchain).
workflow_dispatch:
jobs:
build-web-sdk-bundle:
name: build + size-gate op-web-sdk wasm bundle
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: '1.94'
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@v2
with:
shared-key: web-sdk-bundle
- name: Install wasm-bindgen-cli (pinned to the locked version)
run: |
# Pin the CLI to the same version as the `wasm-bindgen` crate in
# Cargo.lock so the generated JS glue matches the linked runtime —
# a version skew between the two causes a "schema version mismatch"
# panic at mount time. Read the locked version straight out of
# Cargo.lock (the [[package]] block whose name is exactly `wasm-bindgen`).
# This mirrors wasm-bundle-build.yml exactly (same awk extractor).
version="$(awk '/^name = "wasm-bindgen"$/{found=1; next} found && /^version = /{gsub(/[" ]/,"",$3); print $3; exit}' Cargo.lock)"
if [ -z "$version" ]; then
echo "::error::could not resolve wasm-bindgen version from Cargo.lock"
exit 1
fi
echo "Installing wasm-bindgen-cli $version"
cargo install wasm-bindgen-cli --version "$version" --locked
- name: Install binaryen (pinned modern release)
run: |
# Ubuntu's apt `binaryen` is v108 — too old for rustc 1.94's wasm
# (memory.copy/fill from bulk-memory-opt), so `wasm-opt` rejects the
# bundle with "all used features should be allowed". Pin a modern
# release matching the local dev toolchain / wasm-bundle-build.yml.
BINARYEN_VERSION=version_123
curl -fsSL \
"https://github.com/WebAssembly/binaryen/releases/download/${BINARYEN_VERSION}/binaryen-${BINARYEN_VERSION}-x86_64-linux.tar.gz" \
| tar -xz
echo "${GITHUB_WORKSPACE}/binaryen-${BINARYEN_VERSION}/bin" >> "$GITHUB_PATH"
"${GITHUB_WORKSPACE}/binaryen-${BINARYEN_VERSION}/bin/wasm-opt" --version
- name: Verify node + gzip are present (script prerequisites)
run: |
node --version
gzip --version | head -n1
wasm-bindgen --version
# Single source of truth: run the crate-local gate script verbatim. It
# runs cargo build (canvaskit) -> wasm-bindgen --target web ->
# 0-env-import assert -> wasm-opt -Oz -> gzip size <= ceiling, and exits
# non-zero on any breach.
- name: Build + size-gate the op-web-sdk bundle
run: bash crates/op-web-sdk/tools/build-wasm.sh
- name: Upload op-web-sdk-bundle artifact
uses: actions/upload-artifact@v4
with:
name: op-web-sdk-bundle
# Upload the full wasm-pack output directory: wasm + JS glue + .d.ts.
path: crates/op-web-sdk/pkg
if-no-files-found: error
# Keep briefly so a downstream release / Docker build can pull it
# without rebuilding.
retention-days: 14