47 commits from the align branch merged onto the force-updated remote base (which had replayed an earlier snapshot of the same work plus new overlay/pointer features and CI fixes). Conflict resolution: kept the newer align side for the generation pipeline (orchestrator, mcp, skills, design tools), kept the base side for the chat-panel test semantics and graceful overlay teardown, fused both in sub_agent_session (design-turn thinking policy + graceful epoch finish), and dropped the files each side had deleted (legacy concurrent/dashboard paths, retired TS skills). Deduped two identical replayed hunks (export.rs, chat_session_tests.rs). Known issue carried over: provider_probe_host::landed_connected_outcome_ without_models_is_failure fails on a host with a live provider config (env-sensitive test, both sides byte-identical there; green on CI).
153 lines
7 KiB
YAML
153 lines
7 KiB
YAML
name: WASM bundle build (#56 — real canvaskit deployable)
|
|
|
|
# Builds the REAL production web bundle (the `canvaskit` cargo feature, not the
|
|
# `web` compile stub), size-gates it, and uploads it as a reproducible
|
|
# deployable artifact. This is the CI counterpart of the local
|
|
# `tools/check-wasm-bundle.sh` developer gate.
|
|
#
|
|
# Why a NEW file instead of un-deferring the block in `rust-release.yml`
|
|
# / `rust-multiplatform.yml`: those deferred blocks describe the RETIRED
|
|
# from-scratch skia pipeline (`--features skia`, `vendor/skia-safe-op`,
|
|
# `crates/wasm-libc-shim`, brew-emscripten + EMSDK + the `.wasm.a` → `.a`
|
|
# symlink hack). That whole path was retired 2026-06-17 (see the workspace
|
|
# `Cargo.toml` note + `tools/check-wasm-bundle.sh` lines 57-59): the editor now
|
|
# renders through the official CanvasKit skia WASM, so the Rust bundle is pure
|
|
# logic and needs NO EMSDK / skia-safe / libc shim. Un-deferring the stale
|
|
# blocks would mean rewriting them top to bottom; a clean new job that mirrors
|
|
# the CURRENT local script is the honest option.
|
|
#
|
|
# Authoritative recipe mirrored from `tools/check-wasm-bundle.sh`:
|
|
# prerequisites: cargo, wasm-bindgen, wasm-opt, node, gzip (NO EMSDK)
|
|
# 1. cargo build -p op-host-web --target wasm32-unknown-unknown \
|
|
# --no-default-features --features canvaskit --release
|
|
# 2. wasm-bindgen --target web --out-dir crates/op-host-web/pkg <target.wasm>
|
|
# 3. assert 0 env.* imports (LinkError guard)
|
|
# 4. wasm-opt -Oz with the rustc-emitted WebAssembly feature flags, then
|
|
# gzip size <= ceiling (default 6291456 bytes = 6 MiB, overridable via
|
|
# STEP1B_SHELL_WASM_GZIP_LIMIT_BYTES)
|
|
# The job calls the script directly rather than duplicating that logic — the
|
|
# script already runs non-interactively (`set -euo pipefail`, exit 0/1/2) and
|
|
# is the single source of truth for the gate.
|
|
|
|
on:
|
|
pull_request:
|
|
paths:
|
|
- 'Cargo.toml'
|
|
- 'Cargo.lock'
|
|
- 'crates/**'
|
|
- 'deny.toml'
|
|
- 'tools/check-wasm-bundle.sh'
|
|
- '.github/workflows/wasm-bundle-build.yml'
|
|
push:
|
|
branches: ['**']
|
|
paths:
|
|
- 'Cargo.toml'
|
|
- 'Cargo.lock'
|
|
- 'crates/**'
|
|
- 'tools/check-wasm-bundle.sh'
|
|
- '.github/workflows/wasm-bundle-build.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-canvaskit-bundle:
|
|
name: build + size-gate canvaskit web 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: wasm-bundle-build
|
|
|
|
# The CanvasKit bundle is pure Rust + web_sys + serde — no skia-safe, no
|
|
# emscripten, no system GL libs. So the toolchain footprint is just the
|
|
# wasm-bindgen CLI + wasm-opt (binaryen) + node, exactly the prerequisites
|
|
# `tools/check-wasm-bundle.sh` asserts via its `need` checks.
|
|
- 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 is the classic `wasm-bindgen`
|
|
# "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`).
|
|
version="$(cargo metadata --format-version 1 --locked --no-deps >/dev/null 2>&1; \
|
|
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) + headless server runtime deps
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y \
|
|
pkg-config \
|
|
libfreetype-dev \
|
|
libfontconfig1-dev \
|
|
fonts-noto-cjk
|
|
# Ubuntu's apt `binaryen` is v108 (2022) — far too old for rustc
|
|
# 1.94's wasm feature set (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.
|
|
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 + Chrome are present (script prerequisites)
|
|
run: |
|
|
node --version
|
|
gzip --version | head -n1
|
|
google-chrome --version || chromium --version || chromium-browser --version
|
|
|
|
# Single source of truth: run the local gate script verbatim. It performs
|
|
# cargo build (canvaskit) -> wasm-bindgen --target web -> 0-env-import
|
|
# assert -> wasm-opt -Oz with rustc's WebAssembly feature flags -> gzip
|
|
# size <= ceiling, and exits non-zero on any breach, which fails the job.
|
|
# The ceiling default (6 MiB gzip) lives in the script; override here only
|
|
# if a release intentionally re-baselines.
|
|
- name: Build + size-gate the canvaskit bundle
|
|
run: bash tools/check-wasm-bundle.sh
|
|
|
|
- name: Browser smoke the canvaskit bundle + daemon
|
|
run: OPENPENCIL_SKIP_WASM_BUILD=1 bash tools/check-web-browser-smoke.sh
|
|
|
|
# Assemble the deployable layout the daemon's `web_static.rs` expects: the
|
|
# wasm-bindgen `pkg/` output PLUS the vendored CanvasKit artifact under a
|
|
# `canvaskit/` subdir, all inside a single `web-bundle/` directory. This
|
|
# mirrors the `<exe_dir>/web-bundle` + `web-bundle/canvaskit` resolution
|
|
# order in `crates/op-host-services/src/web_static.rs`.
|
|
- name: Assemble deployable web-bundle/
|
|
run: |
|
|
set -euo pipefail
|
|
rm -rf web-bundle
|
|
mkdir -p web-bundle
|
|
cp -R crates/op-host-web/pkg/. web-bundle/
|
|
cp -R crates/op-host-web/assets/canvaskit web-bundle/canvaskit
|
|
echo "web-bundle contents:"
|
|
find web-bundle -maxdepth 2 -type f | sort
|
|
|
|
- name: Upload deployable web-bundle artifact
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: op-web-bundle
|
|
path: web-bundle
|
|
if-no-files-found: error
|
|
# The bundle is deterministic from the inputs; keep it briefly so a
|
|
# release / Docker build can pull it without rebuilding.
|
|
retention-days: 14
|