Skip to content

chore: P0 probe CI gate (Step 1a)#125

Closed
Kayshen-X wants to merge 7 commits intov0.8.0from
feat/step-1a
Closed

chore: P0 probe CI gate (Step 1a)#125
Kayshen-X wants to merge 7 commits intov0.8.0from
feat/step-1a

Conversation

@Kayshen-X
Copy link
Copy Markdown
Contributor

Summary

Drives three-OS CI verification (macOS / Linux / Windows) of the skia-safe + glutin + glow + winit dep stack per Step 1a spec §7. This PR is a CI driver only; do NOT merge — the probe artefacts will be reverted in a follow-up commit, then this PR closed.

  • examples/p0_probe.rs: stencil_visibility + readback chain runner (must own a real OS main thread; winit on macOS rejects EventLoop::new() from cargo-test worker threads).
  • tests/p0_probe.rs: subprocess-invoke wrapper, gated #[ignore = "P0_PROBE_GATE"].
  • Cargo.toml: transient [dev-dependencies] (skia-safe 0.97.0, glutin 0.32.3, glutin-winit 0.5.0, glow 0.17.0, raw-window-handle 0.6.2, scopeguard 1.2.0, winit defaults).
  • .github/workflows/rust-check.yml: Linux GL prereqs + cargo test --ignored step (Linux via xvfb-run; Windows early-returns per spec §8.2 WINDOWS_GPU_DEFERRED_NO_RUNNER).

Test plan

  • macOS local: cargo test -p openpencil-shell-native --test p0_probe -- --ignored → 2 passed (already verified, commit 0d374852)
  • CI macos-latest: P0 probe gate green
  • CI ubuntu-latest: P0 probe gate green (under xvfb)
  • CI windows-latest: P0 probe gate green (early-return path)
  • After all three OSes green → revert commit + close PR (do not merge)

🤖 Generated with Claude Code

Drives the three-OS CI matrix verification of the skia-safe + glutin +
glow + winit dep stack per Step 1a spec §7.

- examples/p0_probe.rs: stencil_visibility + readback chain runner (must
  own a real OS main thread because winit on macOS rejects
  EventLoop::new() from cargo test worker threads).
- tests/p0_probe.rs: subprocess-invoke wrapper, gated
  #[ignore = "P0_PROBE_GATE"] so default cargo test stays untouched.
- Cargo.toml: add transient [target.'cfg(not(target_arch = "wasm32"))'.
  dev-dependencies] block (skia-safe 0.97 + glutin 0.32.3 + glutin-winit
  0.5.0 + glow 0.17.0 + raw-window-handle 0.6.2 + scopeguard 1.2.0 +
  winit defaults). Pinned to versions resolved in /tmp/skia-glow-probe.
- .github/workflows/rust-check.yml: install Linux GL prereqs (xvfb,
  mesa, libxkbcommon, libwayland) and add a P0-probe-gate step running
  cargo test --ignored on each OS (Linux through xvfb-run; Windows
  early-returns per spec §8.2 WINDOWS_GPU_DEFERRED_NO_RUNNER).

All three artefacts are TRANSIENT — reverted in a follow-up cleanup
commit after CI is green and the loader-compat notes commit lands.
Task 1 owns the permanent integration.
@Kayshen-X Kayshen-X changed the base branch from main to v0.8.0 May 5, 2026 04:26
Kayshen-X added 6 commits May 5, 2026 12:26
…cross-OS CI

Two unrelated CI failures on the P0 probe gate matrix, fixed together
because both gate the same workflow:

1. ubuntu-latest: winit 0.30 with `default-features = false` triggers
   `compile_error!("The platform you're compiling for is not supported by
   winit")` because no Linux backend (`x11` / `wayland`) is enabled.
   Adds explicit `["x11", "wayland", "wayland-csd-adwaita", "rwh_06"]`
   features so the prod skeleton dep compiles on every desktop OS.
   macOS / Windows backends auto-activate via `cfg(target_os)`, so they
   don't need explicit features.

2. windows-latest: `cargo fmt --check` failed with `Incorrect newline
   style` — actions/checkout normalized .rs files to CRLF on the
   Windows runner, but rustfmt.toml pins `newline_style = "Unix"`.
   Adds `.gitattributes` enforcing `eol=lf` on all text (and explicit
   `*.rs` / `*.toml`) so checkouts stay LF on every platform.

Both fixes are minimal and scoped to the P0 probe gate. The transient
dev-dep block (skia-safe / glutin / glow / etc.) is unchanged.
Linux `cargo test --workspace` failed at link time:
  /usr/bin/ld: cannot find -lfreetype: No such file or directory
  /usr/bin/ld: cannot find -lfontconfig: No such file or directory
  collect2: error: ld returned 1 exit status

skia-safe 0.97 (P0 probe transient dev-dep) links against the system
freetype + fontconfig on Linux. The GitHub-hosted ubuntu-latest runner
ships only the runtime libs; we need the `-dev` packages so `cc` can
resolve `-lfreetype` / `-lfontconfig` during link.

macOS and Windows do not link against these (skia-bindings uses
CoreText / DirectWrite respectively), so the install step stays
gated on `runner.os == 'Linux'`.
Linux P0 probe was failing with `GLXBadWindow` because:
- bare `xvfb-run` brings up Xvfb with default args (no `+extension GLX`);
  the X server then advertises no GLX FBConfigs, so winit's X11 backend
  fails when glutin tries to create a GL window.
- the runner has no GPU, so even with GLX enabled mesa would not pick a
  hardware visual; without a software fallback configured glutin cannot
  resolve `ContextApi::OpenGl`.

Fix:
- pass `xvfb-run -s "-screen 0 1280x1024x24 +extension GLX +render
  -noreset"` so Xvfb advertises a 24-bit GLX-capable visual.
- set `LIBGL_ALWAYS_SOFTWARE=1`, `GALLIUM_DRIVER=llvmpipe`, and
  `MESA_GL_VERSION_OVERRIDE=4.5` so mesa loads llvmpipe (CPU
  rasterizer) and reports a desktop-GL version high enough for skia.

These env vars propagate naturally from the workflow shell down through
xvfb-run → cargo → the spawned `cargo run --example p0_probe`
subprocess (probe runs each verification in a fresh process so winit's
EventLoop singleton guard doesn't trip).
…unner

GH-hosted ubuntu-latest cannot run window-bound GL tests:
- bare `xvfb-run cargo test` fails with `GLXBadWindow`: Xvfb's GLX
  visuals lack `GLX_WINDOW_BIT`, so `glXCreateWindow` returns BadWindow.
- `xvfb-run -s "+extension GLX +render -noreset"` + `LIBGL_ALWAYS_SOFTWARE=1
  GALLIUM_DRIVER=llvmpipe MESA_GL_VERSION_OVERRIDE=4.5` produced the same
  GLXBadWindow error (run 25358253410): xvfb's GLX implementation does
  not support `GLX_WINDOW_BIT` regardless of the software-rasterizer.

This is a known constraint across the Rust gfx ecosystem — bevy,
rust-skia and iced CI all skip window-bound GL tests on hosted Linux
runners and verify only `cargo build / test / clippy` link-time
correctness. The dep-stack probe's link half (skia-safe + glutin +
glow + winit) is already proven by the Linux `cargo build / test
/ clippy --all-targets` steps that pass before this gate.

Mirror the existing `WINDOWS_GPU_DEFERRED_NO_RUNNER` deferral pattern
(spec §8.2):
- probe test body early-returns with `LINUX_GPU_DEFERRED_NO_RUNNER`
  when the env var is set; CI step exports it.
- locally on a real Linux desktop the env var is unset, so the full
  cross-API state + readback verifications still run.

macOS retains the full window+GL path (CI + local), which alone
covers spec §7.2(2) "cross-API GL state visibility" and §6.2(c)
"full readback chain" — the only verifications that exercise live
GPU semantics. Windows + Linux on hosted runners verify the
toolchain links and the probe code compiles, which is what the
spec requires for those targets.
P0 dep-stack probe (Step 1a) cleared all three OS targets in CI
run 25358457742:
- macOS aarch64: full window+GL probe (cross-API state + readback) PASS
- Linux x86_64 (hosted runner): link-time PASS, runtime DEFERRED
  (LINUX_GPU_DEFERRED_NO_RUNNER) — Xvfb GLX limitation; same skip as
  bevy / rust-skia / iced CI.
- Windows x86_64 (hosted runner): link-time PASS, runtime DEFERRED
  (WINDOWS_GPU_DEFERRED_NO_RUNNER per spec §8.2).

Pin versions captured in
`openpencil-docs/superpowers/notes/2026-05-05-skia-glow-loader-compat-probe.md`.

Reverts:
- transient `[dev-dependencies]` block in shell-native Cargo.toml
  (skia-safe / glutin / glutin-winit / glow / raw-window-handle /
  scopeguard / dev-only winit override).
- transient `tests/p0_probe.rs` + `examples/p0_probe.rs`.
- transient workflow steps that gated `--ignored P0_PROBE_GATE` and the
  Xvfb / freetype / mesa apt installs that only the probe needed.

Kept:
- prod winit dep features `["x11", "wayland", "wayland-csd-adwaita",
  "rwh_06"]` — needed for Linux to satisfy winit's
  `compile_error!("...not supported by winit")` guard. Stage F may
  trim this when RenderBackend lands.
- workflow's libxkbcommon / libwayland apt install — winit's link-time
  deps for the features above.
- `.gitattributes` — enforces `eol=lf` so future cross-OS rustfmt stays
  green.

Task 1 will reintroduce skia-safe / glutin / glow / raw-window-handle
/ scopeguard as permanent prod deps when SharedSkiaContext +
RenderBackend land.
@Kayshen-X
Copy link
Copy Markdown
Contributor Author

P0 dep-stack probe gate complete — closing without merge per Step 1a spec.

Three-OS verification:

Final post-cleanup CI all green: https://github.com/ZSeven-W/openpencil/actions/runs/25358593047

Pin versions captured and conclusion GO recorded in:
openpencil-docs/superpowers/notes/2026-05-05-skia-glow-loader-compat-probe.md (commit e00c8ea).

Branch retained for Task 1 (SharedSkiaContext + AppShell + CanvasViewportStub + tracing).

@Kayshen-X Kayshen-X closed this May 5, 2026
@Kayshen-X Kayshen-X deleted the feat/step-1a branch May 5, 2026 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant