fix(ci): repair three v0.8.0-new failures (canvaskit test, windows-aarch64 deps, windows nextest)
Three independent CI failures, none caused by the font-lock push: 1. CanvasKit web-host test variables_panel_open_does_not_paint_legacy_modal false-tripped: its '> half viewport' heuristic was a proxy for 'no full-viewport modal', but only passed because the property panel used to narrow the canvas and clamp the floating VariablesPanel below half-width. The nothing-selected-by-default change collapsed the property panel, widening the canvas so the legitimate 820x480 panel paints unclamped. There is no legacy modal. Retarget the assertion at a near full-viewport round fill and positively assert the panel paints. 2. windows-aarch64 cross-check failed: op-host-services + op-orchestrator pulled op-mcp's native-only 'script' feature unconditionally, dragging in rquickjs-sys which ships no bindings for aarch64-pc-windows-msvc. Enable 'script' per-target (off on that unshipped check-only arch). 3. Windows workspace tests segfaulted single-threaded (before the first test prints, under --test-threads=1) — an intra-test race a thread flag can't serialize. Switch the Windows runner to cargo-nextest (one process per test) so the crash is isolated + named; doctests run separately.
This commit is contained in:
parent
41a023ca9a
commit
8cd03adacd
28
.github/workflows/rust-check.yml
vendored
28
.github/workflows/rust-check.yml
vendored
|
|
@ -71,19 +71,29 @@ jobs:
|
|||
# EGL, so STEP1A_REQUIRE_GPU is left unset: the op-host-native GPU
|
||||
# smoke (memory_loop) self-uses the raster fallback instead of
|
||||
# hard-failing on EGL init. Real-GPU coverage runs on dev machines.
|
||||
# Windows runs the whole workspace single-threaded. Many crates' tests
|
||||
# (op-host-native / -desktop / -services / …) trigger a skia `FontMgr`
|
||||
# (DirectWrite on Windows) via NativeBackend or SkiaMeasure; concurrent
|
||||
# DirectWrite init across a test binary's parallel worker threads
|
||||
# segfaults (STATUS_ACCESS_VIOLATION). `--test-threads=1` serializes each
|
||||
# binary — cross-binary (separate-process) concurrency is safe, so one
|
||||
# flag covers every skia-touching crate. macOS / Linux run in parallel.
|
||||
- name: Test workspace (non-Windows, parallel)
|
||||
if: runner.os != 'Windows'
|
||||
run: cargo test --workspace
|
||||
- name: Test workspace (Windows, serialized — skia/DirectWrite)
|
||||
# Windows: skia's `FontMgr` is DirectWrite, which segfaults
|
||||
# (STATUS_ACCESS_VIOLATION) when a test spawns a worker thread doing
|
||||
# font layout (SkiaMeasure) concurrently with the main thread — an
|
||||
# intra-test race `--test-threads=1` can NOT serialize (it only
|
||||
# serializes tests against each other, not threads inside one test).
|
||||
# nextest runs every test in its OWN process, so such a crash is
|
||||
# isolated + named instead of taking down the whole test binary, and
|
||||
# cross-test DirectWrite state can't leak between them. Doctests run
|
||||
# separately (nextest doesn't execute them).
|
||||
- name: Install cargo-nextest (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: cargo test --workspace -- --test-threads=1
|
||||
uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: nextest
|
||||
- name: Test workspace (Windows, nextest per-process isolation)
|
||||
if: runner.os == 'Windows'
|
||||
run: cargo nextest run --workspace
|
||||
- name: Doctests (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: cargo test --workspace --doc
|
||||
- name: Run CanvasKit web host tests
|
||||
run: cargo test -p op-host-web --features canvaskit -- --test-threads=1
|
||||
- run: cargo clippy --workspace --all-targets -- -D warnings
|
||||
|
|
|
|||
24
.github/workflows/rust-multiplatform.yml
vendored
24
.github/workflows/rust-multiplatform.yml
vendored
|
|
@ -117,15 +117,23 @@ jobs:
|
|||
- name: Test (host, macOS — parallel)
|
||||
if: matrix.cross == false && matrix.check_only != true && runner.os == 'macOS'
|
||||
run: cargo test --workspace --target ${{ matrix.target }}
|
||||
# Windows runs the whole workspace single-threaded: many crates' tests
|
||||
# trigger a skia FontMgr (DirectWrite) via NativeBackend / SkiaMeasure,
|
||||
# and concurrent DirectWrite init across a test binary's parallel worker
|
||||
# threads segfaults (STATUS_ACCESS_VIOLATION). --test-threads=1 serializes
|
||||
# each binary; cross-binary (separate-process) concurrency is safe, so
|
||||
# one flag covers every skia-touching crate. Matches rust-check.yml.
|
||||
- name: Test (host, Windows — serialized skia/DirectWrite)
|
||||
# Windows: skia's FontMgr (DirectWrite) segfaults when a test spawns a
|
||||
# worker thread doing font layout (SkiaMeasure) concurrently with the
|
||||
# main thread — an intra-test race --test-threads=1 can't serialize.
|
||||
# nextest runs each test in its own process so such a crash is isolated
|
||||
# + named and cross-test DirectWrite state can't leak. Doctests run
|
||||
# separately (nextest doesn't execute them). Matches rust-check.yml.
|
||||
- name: Install cargo-nextest (Windows)
|
||||
if: matrix.cross == false && matrix.check_only != true && runner.os == 'Windows'
|
||||
run: cargo test --workspace --target ${{ matrix.target }} -- --test-threads=1
|
||||
uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: nextest
|
||||
- name: Test (host, Windows — nextest per-process isolation)
|
||||
if: matrix.cross == false && matrix.check_only != true && runner.os == 'Windows'
|
||||
run: cargo nextest run --workspace --target ${{ matrix.target }}
|
||||
- name: Doctests (host, Windows)
|
||||
if: matrix.cross == false && matrix.check_only != true && runner.os == 'Windows'
|
||||
run: cargo test --workspace --target ${{ matrix.target }} --doc
|
||||
# Desktop binary artifact upload is intentionally not wired here yet.
|
||||
# The real desktop binary lives in the `op-host-desktop` crate; a
|
||||
# build + upload step can be added once release packaging is finalized.
|
||||
|
|
|
|||
|
|
@ -22,7 +22,11 @@ mcp-debug-tools = ["op-mcp/debug-tools"]
|
|||
op-editor-core = { path = "../op-editor-core" }
|
||||
op-editor-ui = { path = "../op-editor-ui" }
|
||||
op-editor-host-core = { path = "../op-editor-host-core" }
|
||||
op-mcp = { path = "../op-mcp", features = ["script"] }
|
||||
# The native-only `script` feature (QuickJS via rquickjs-sys) is enabled
|
||||
# per-target below: rquickjs-sys ships no prebuilt bindings for
|
||||
# aarch64-pc-windows-msvc (an unshipped check-only arch), so it stays off
|
||||
# there while remaining on for every target we actually build/run.
|
||||
op-mcp = { path = "../op-mcp" }
|
||||
op-ai = { path = "../op-ai" }
|
||||
op-ai-skills = { path = "../op-ai-skills" }
|
||||
op-orchestrator = { path = "../op-orchestrator" }
|
||||
|
|
@ -70,3 +74,9 @@ skia-safe = { version = "0.97.0", default-features = false, features = [
|
|||
"textlayout",
|
||||
"pdf",
|
||||
] }
|
||||
|
||||
# Native-only QuickJS script feature — enabled everywhere except
|
||||
# aarch64-pc-windows-msvc, whose rquickjs-sys has no prebuilt bindings
|
||||
# (that arch is a check-only target, never shipped).
|
||||
[target.'cfg(not(all(target_os = "windows", target_arch = "aarch64")))'.dependencies]
|
||||
op-mcp = { path = "../op-mcp", features = ["script"] }
|
||||
|
|
|
|||
|
|
@ -369,12 +369,27 @@ fn variables_panel_open_does_not_paint_legacy_modal() {
|
|||
|
||||
host.paint_editor(&mut backend, W, H);
|
||||
|
||||
// The retired legacy variables surface was a near full-viewport modal
|
||||
// backdrop; the current surface is the floating VariablesPanel
|
||||
// (820x480, anchored beside the toolbar). Guard only against a round
|
||||
// fill spanning almost the whole viewport — the earlier "> half
|
||||
// viewport" heuristic false-tripped once the property panel collapsed
|
||||
// (nothing-selected default) widened the canvas so the legitimate
|
||||
// floating panel paints unclamped.
|
||||
assert!(
|
||||
!backend
|
||||
.round_fills
|
||||
.iter()
|
||||
.any(|r| r.size.x > W * 0.5 && r.size.y > H * 0.5),
|
||||
"variables_panel_open should not paint the legacy variables modal"
|
||||
.any(|r| r.size.x >= W * 0.9 && r.size.y >= H * 0.9),
|
||||
"variables_panel_open should not paint the legacy full-viewport modal"
|
||||
);
|
||||
// ...and the floating panel itself must actually paint.
|
||||
let panel = host
|
||||
.variables_panel_rect(W, H)
|
||||
.expect("variables panel fits in the test viewport");
|
||||
assert!(
|
||||
painted_inside(&backend, panel),
|
||||
"the floating VariablesPanel background should paint"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ repository.workspace = true
|
|||
|
||||
[dependencies]
|
||||
op-editor-core = { path = "../op-editor-core" }
|
||||
op-mcp = { path = "../op-mcp", features = ["script"] }
|
||||
# `script` feature enabled per-target below (off on aarch64-pc-windows-msvc,
|
||||
# whose rquickjs-sys has no prebuilt bindings; that arch is check-only).
|
||||
op-mcp = { path = "../op-mcp" }
|
||||
op-ai-skills = { path = "../op-ai-skills" }
|
||||
# Real jian flex layout (resolved absolute rects) for geometry-driven structural
|
||||
# validation — the deterministic analogue of Pencil's per-batch snapshot_layout.
|
||||
|
|
@ -28,3 +30,8 @@ tokio = { version = "1", features = ["sync", "rt", "macros"] }
|
|||
[dev-dependencies]
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
# Native-only QuickJS script feature — off on aarch64-pc-windows-msvc
|
||||
# (no rquickjs-sys prebuilt bindings; check-only target, never shipped).
|
||||
[target.'cfg(not(all(target_os = "windows", target_arch = "aarch64")))'.dependencies]
|
||||
op-mcp = { path = "../op-mcp", features = ["script"] }
|
||||
|
|
|
|||
Loading…
Reference in a new issue