Policy change (supersedes the system-first probe): build OpenColorIO
from the vendored sources and link it statically on every platform
that can -- packaged binaries carry no OCIO runtime dependency. The
[patch.crates-io] ocio-sys now tracks shaloong/ocio-rs main
explicitly; its vendored yaml-cpp has the <cstdint> include that makes
the vendored build work on GCC >= 16 (verified on GCC 16.2.1).
Windows/MinGW stays the exception (the vendored source needs MSVC-only
constructs): tooling/ocio-env.sh probes the MSYS2 system OCIO there,
static when libOpenColorIO.a ships, dynamic otherwise. The Linux jobs
drop the system OCIO dev packages the system-first policy needed.
- Install ffnvcodec headers everywhere the project FFmpeg is built
(distro packages on Debian/Ubuntu/Arch/MSYS2, nv-codec-headers from
source on Fedora) so the FFmpeg build picks up NVDEC/NVENC.
- ocio-sys 0.2.1's vendored yaml-cpp misses <cstdint> and fails on
GCC >= 16 (measured on GCC 16.2.1); patch the dependency to the
fixed upstream tree (shaloong/ocio-rs, 933c65dc) until a fixed
release lands on crates.io.
- New tooling/ocio-env.sh decides the OCIO build env per job: system
OCIO >= 2.5 when present (static when the package ships
libOpenColorIO.a, dynamic otherwise), vendored static build as the
fallback. The Arch package gains an 'opencolorio' dependency only
when the binaries link the system OCIO (build-pkg.sh probes ldd).
- CI 'Build' steps switch from cargo build to cargo check: the Test
step links the test binaries anyway, and a full build would codegen
every workspace crate twice.
Run 48's Linux leg flaked: full_res_worker_outlives_a_dropped_project
panicked with "the render manager failed to start" while all 236 other
tests passed -- a worker-pool startup race under full-suite parallelism,
not a regression (the same binary passes locally and passed on the
previous commit). Mirror the Windows job's retry-once policy and make
ensure_render_manager log the underlying init error so the next flake is
diagnosable. The Windows leg's real failure (gpui_widgets referenced
SurfaceSource::Texture, which only exists on linux/freebsd) is fixed in
the gpui submodule bump of the previous commit.
The probe step pointed OAK_OFX_FIXTURE_DIR at .cache/ofx-fixtre, so the
ofx_roundtrip test found no fixture plugin and failed with "the fixture
plugin registered (got [])".
The background watchdog subshell inherited the step's stdout/stderr; when
cargo test finished, its lingering sleep child kept the pipes open and
the runner aborted the step with "exec: WaitDelay expired before I/O
complete". Redirect the watchdog to /dev/null and reap it after the
test so the step's I/O closes cleanly.
ci (Windows): the runner's msys2 shell starts as the base MSYS
environment (MSYSTEM=MSYS), which install-deps.sh rejects. Set the
job-level MSYSTEM=UCRT64 env and prepend /ucrt64/bin to PATH in every
Windows step, so pacman installs and the toolchain resolve against the
mingw-w64-ucrt-x86_64 packages.
fixtures: the restructured workspace moved the media fixtures into
crates/oak-app/tests; the remaining references pointed at the old
repo-root tests/ — oak-codec realmedia_tests + hwdecode, oak-node
serializer golden, oak-worker procpool integration. All point at
../oak-app/tests now (oak-app's own tests/demo.mp4 references were
already correct after the move).
The Gitea runner's msys2 shell does not start in the checkout
directory, so "bash ./tooling/install-deps.sh" reported the file
missing even though the checkout succeeded (the Linux steps were fine —
only the custom msys2 shell has the wrong CWD). Every Windows step now
begins with cd "$GITHUB_WORKSPACE" to make all relative file
references resolve.
Three real-engine throughput loops (thumbnail pipeline, full-res fill
behind the proxy, playback window supply) failed on machine slowness:
their pass/fail was a wall-clock Instant deadline, so a loaded machine
broke them for speed, not for a broken pipeline. Each loop now counts
engine pumps — machine-speed independent — and asserts the condition
within a bounded number of pumps. The two single-frame worker channel
receives keep a generous 60 s recv_timeout (a one-shot bounded
operation, not a throughput loop).
oak-cli: the integration fixtures moved with the app crate during the
workspace restructure; point the fixture helpers at
../oak-app/tests instead of the (now empty) repo-root tests/.
All crates take the oak-* kebab-case naming (oak-audio, oak-codec,
oak-common, oak-core, oak-ffmpeg-link, oak-node, oak-otio, oak-plugin,
oak-render, oak-storage, oak-task, oak-timeline, oak-undo), with the
lib identifiers rewritten (oakrender:: -> oak_render::, oakcore_rs:: ->
oak_core::, ...) across all 226 referencing files.
The GUI application moves from the workspace root into
crates/oak-app/: src/, build.rs (paths fixed for the new location) and
tests/ travel with it, the root Cargo.toml becomes workspace-only
([workspace] + workspace.package + profiles), and the app package
inherits the workspace version. The screenshots example becomes a
standalone crate examples/simple_player/ with its own Cargo.toml.
Every crate now inherits the single workspace version
(version.workspace = true), and the workflows' crate paths and the
build docs follow the renames.
Validated with a clean cargo check --workspace.
The single matrix job becomes two independent jobs on the oak Gitea
runners (oak-ubuntu-2404 / oak-windows-2025 — the user's labels, kept
as-is). Every runner.os conditional collapses into the owning job and
all macOS steps are removed. actionlint.yaml whitelists the two oak
runner labels (actionlint needs -config-file now that the config lives
under .gitea/ instead of the default .github/ path).
Gitea prep: .github becomes .gitea (the act runner looks there), and
every actions/cache + Swatinem/rust-cache step is commented out until
the self-hosted instance has a cache provisioned. The remaining
marketplace actions (checkout/upload-artifact are act-compatible;
msys2/setup-msys2, dtolnay/rust-toolchain and softprops/action-gh-release
need a runner test / replacement) are a follow-up.
tests: the two gpui keystroke tests that flaked on Windows CI (undo
pair, snapping toggle — each once, values identical to the pass state,
Global-route keys) now dispatch each key with a double park. The root
cause is not fully pinned: the loss happens inside gpui's synthetic
key dispatch on Windows (both tests hold every test lock; production
is unaffected). The CI retry-once remains the backstop. The earlier
idea of advancing the simulated clock to flush gpui's pending-input
timer is off the table: the mock engine's playback ticks with executor
time, so a clock advance moves the playhead out from under the
assertions (observed: playhead 14 vs expected 9).