ci(host): build web image from op-host-web-server + headless-boundary guard (Phase 6, Tasks 6.2-6.4)
Dockerfile.web-rust builds -p op-host-web-server (was op-host-desktop) and drops ALL GL/X11 build + runtime apt deps (libegl/libgles/libgbm/libxkbcommon/libwayland/libxcb) — the raster server links none; only freetype/fontconfig + CJK fonts remain for skia text. COPY + CMD repointed to /app/op-host-web-server. New tools/check-web-server-headless.sh fails CI if op-host-web-server's isolated dep graph pulls winit/glutin/casement/muda/accesskit-adapters or skia-safe with gl (bare accesskit core allowed per Codex Issue 1); wired into rust-check.yml + its paths filter. Stale web_static.rs path comment fixed (op-host-desktop -> op-web-daemon). Desktop-app build job untouched.
This commit is contained in:
parent
f198cdf76a
commit
b7951fc598
6
.github/workflows/rust-check.yml
vendored
6
.github/workflows/rust-check.yml
vendored
|
|
@ -10,6 +10,7 @@ on:
|
|||
- 'rustfmt.toml'
|
||||
- 'deny.toml'
|
||||
- 'tools/check-jian-boundaries.sh'
|
||||
- 'tools/check-web-server-headless.sh'
|
||||
- 'tools/check-widget-boundary.sh'
|
||||
- 'tools/dump-diagnostics-golden.ts'
|
||||
- 'packages/pen-ai-skills/**'
|
||||
|
|
@ -27,6 +28,7 @@ on:
|
|||
- 'rust-toolchain.toml'
|
||||
- 'rustfmt.toml'
|
||||
- 'tools/check-jian-boundaries.sh'
|
||||
- 'tools/check-web-server-headless.sh'
|
||||
- 'tools/check-widget-boundary.sh'
|
||||
- 'tools/dump-diagnostics-golden.ts'
|
||||
- 'packages/pen-ai-skills/**'
|
||||
|
|
@ -92,6 +94,10 @@ jobs:
|
|||
if: runner.os == 'Linux'
|
||||
run: bash tools/check-widget-boundary.sh
|
||||
|
||||
- name: Verify op-host-web-server headless boundary (no winit/glutin/GL)
|
||||
if: runner.os == 'Linux'
|
||||
run: bash tools/check-web-server-headless.sh
|
||||
|
||||
- name: Install Bun (retry on transient infra flake)
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
|
|
|
|||
2
.github/workflows/wasm-bundle-build.yml
vendored
2
.github/workflows/wasm-bundle-build.yml
vendored
|
|
@ -113,7 +113,7 @@ jobs:
|
|||
# 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-desktop/src/web_static.rs`.
|
||||
# order in `crates/op-web-daemon/src/web_static.rs`.
|
||||
- name: Assemble deployable web-bundle/
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
|
|
|||
|
|
@ -47,18 +47,16 @@ ARG WEB_BUNDLE_SOURCE=build
|
|||
ARG SERVE_PORT=3100
|
||||
|
||||
# binaryen -> wasm-opt -Oz ; nodejs -> the 0-env-import assert in the gate
|
||||
# script ; the rest are op-host-desktop's Linux link-time deps (winit/skia GL
|
||||
# stack) so the daemon binary links. fonts-noto-cjk gives the daemon real CJK
|
||||
# glyphs at runtime (matches the rust-check.yml Linux prereqs).
|
||||
# script. op-host-web-server is the headless raster daemon (links op-web-daemon
|
||||
# only — no winit/glutin/skia-GL under Approach Y), so NONE of the GL/X11
|
||||
# link-time libs the desktop binary needed are required here; only
|
||||
# freetype/fontconfig (+ CJK fonts) for skia's raster text shaping at export.
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
binaryen \
|
||||
nodejs \
|
||||
gzip \
|
||||
ca-certificates \
|
||||
pkg-config \
|
||||
libxkbcommon-dev libxkbcommon-x11-dev \
|
||||
libwayland-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev \
|
||||
libegl1-mesa-dev libgles2-mesa-dev libgbm-dev \
|
||||
libfreetype-dev libfontconfig1-dev fonts-noto-cjk \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
|
@ -69,9 +67,10 @@ WORKDIR /src
|
|||
# the CI checkout uses `submodules: recursive`.
|
||||
COPY . .
|
||||
|
||||
# Build the desktop daemon binary (the `--serve-web` host). Always built; this
|
||||
# is the runtime binary regardless of how the web bundle is produced.
|
||||
RUN cargo build -p op-host-desktop --release
|
||||
# Build the headless web/MCP server binary (the `--serve-web` host) — links
|
||||
# op-web-daemon only, no winit/skia-GL. Always built; this is the runtime
|
||||
# binary regardless of how the web bundle is produced.
|
||||
RUN cargo build -p op-host-web-server --release
|
||||
|
||||
# Build the canvaskit wasm bundle in-image, UNLESS WEB_BUNDLE_SOURCE=copy.
|
||||
# Mirrors `tools/check-wasm-bundle.sh` exactly (cargo build --features canvaskit
|
||||
|
|
@ -111,10 +110,6 @@ ENV OPENPENCIL_SERVE_PORT=${SERVE_PORT}
|
|||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
libegl1 libgles2 libgbm1 \
|
||||
libxkbcommon0 libxkbcommon-x11-0 \
|
||||
libwayland-client0 libwayland-egl1 \
|
||||
libxcb-render0 libxcb-shape0 libxcb-xfixes0 \
|
||||
libfreetype6 libfontconfig1 fonts-noto-cjk \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
|
@ -124,7 +119,7 @@ WORKDIR /app
|
|||
# bundle as `<exe_dir>/web-bundle` (and CanvasKit as `<exe_dir>/web-bundle/
|
||||
# canvaskit`). Keep the binary + the bundle dir as siblings under /app so that
|
||||
# `<exe_dir> == /app`.
|
||||
COPY --from=builder /src/target/release/openpencil-desktop /app/openpencil-desktop
|
||||
COPY --from=builder /src/target/release/op-host-web-server /app/op-host-web-server
|
||||
COPY --from=builder /out/web-bundle /app/web-bundle
|
||||
|
||||
EXPOSE ${SERVE_PORT}
|
||||
|
|
@ -134,4 +129,4 @@ EXPOSE ${SERVE_PORT}
|
|||
# reverse proxy for anything beyond a trusted network. The port is taken from
|
||||
# the build-time SERVE_PORT (baked into OPENPENCIL_SERVE_PORT); `sh -c` lets the
|
||||
# env var expand at container start.
|
||||
CMD ["sh", "-c", "exec /app/openpencil-desktop --serve-web \"${OPENPENCIL_SERVE_PORT}\" --host 0.0.0.0"]
|
||||
CMD ["sh", "-c", "exec /app/op-host-web-server --serve-web \"${OPENPENCIL_SERVE_PORT}\" --host 0.0.0.0"]
|
||||
|
|
|
|||
43
tools/check-web-server-headless.sh
Executable file
43
tools/check-web-server-headless.sh
Executable file
|
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/env bash
|
||||
# Headless-boundary guard for the web / MCP server binary.
|
||||
#
|
||||
# The whole point of `op-host-web-server` (Approach Y) is that it links the
|
||||
# extracted `op-web-daemon` and NOTHING from the desktop GUI stack: no winit /
|
||||
# glutin / casement (windowing), no muda (native menus), no accesskit platform
|
||||
# ADAPTERS (a11y bridges), and skia-safe WITHOUT the `gl` feature (raster only).
|
||||
# This guard fails the build if any of those leak into the isolated dep graph,
|
||||
# so the web image stays GUI-free.
|
||||
#
|
||||
# Codex Issue 1: the bare `accesskit` CORE crate is allowed — `op-editor-ui`
|
||||
# pulls it unconditionally for the platform-free `Node` / `TreeUpdate` types
|
||||
# (no GUI runtime). We grep the platform ADAPTER crates only.
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
fail=0
|
||||
|
||||
# 1. No windowing / menu / a11y-adapter crates in the feature-resolved tree.
|
||||
gui=$(cargo tree -p op-host-web-server -e features 2>/dev/null \
|
||||
| grep -E 'winit|glutin|casement|muda|accesskit_(macos|unix|windows|winit)' || true)
|
||||
if [ -n "${gui}" ]; then
|
||||
printf 'FAIL: op-host-web-server links a desktop GUI crate:\n%s\n\n' "${gui}" >&2
|
||||
fail=1
|
||||
fi
|
||||
|
||||
# 2. skia-safe must be raster — NO `gl` feature. Under Approach Y, gl arrives
|
||||
# only via the desktop-only `gl-host` edge; its presence in this isolated
|
||||
# graph means a consumer leaked gl-host into the headless server.
|
||||
skia_feats=$(cargo tree -p op-host-web-server -f '{p} {f}' 2>/dev/null \
|
||||
| grep 'skia-safe v' | sed 's/.*skia-safe v[^ ]*//' | head -1)
|
||||
if printf '%s' "${skia_feats}" | grep -qE '(^| |,)gl(,| |$)'; then
|
||||
printf 'FAIL: op-host-web-server skia-safe carries the `gl` feature (must be raster):\n features:%s\n\n' "${skia_feats}" >&2
|
||||
fail=1
|
||||
fi
|
||||
|
||||
if [ "${fail}" -ne 0 ]; then
|
||||
printf 'FAIL: op-host-web-server headless boundary check\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "PASS: op-host-web-server headless boundary check (no winit/glutin/casement/muda/accesskit-adapter; skia raster, no gl)"
|
||||
Loading…
Reference in a new issue