Skip to content

ci(integration): skip scheduled rebuild when main hasn't moved (#202) #415

ci(integration): skip scheduled rebuild when main hasn't moved (#202)

ci(integration): skip scheduled rebuild when main hasn't moved (#202) #415

Workflow file for this run

name: CI
# Integration gate for the `main` (integration) and `release` branches.
# Fast, Linux-only validation that formatting is clean, the renderer workspace
# builds + all its tests pass (including doctests), and the Studio frontend
# builds. Deliberately does NOT bundle Tauri or build the Windows/ASIO target —
# those are covered by the heavier tag-triggered release.yml.
#
# NOTE on scope: `clippy` is NOT gated yet — the workspace currently has ~70
# clippy warnings plus a couple of deny-level lints, several inside hot audio
# loops where the lint suggestions are not obviously safe. Cleaning that up is a
# separate, careful pass; until then a clippy gate would block merges for
# reasons unrelated to correctness.
on:
push:
branches: [main, release]
pull_request:
branches: [main, release]
workflow_dispatch:
# Cancel superseded runs on the same ref to save Actions minutes.
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-and-test:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v5
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: 20
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: Cache Cargo registry
uses: actions/cache@v5
# Caching is an optimization, not a correctness step: a crash of the
# cache action must never fail the build.
continue-on-error: true
with:
path: |
~/.cargo/registry
~/.cargo/git
omniphony-renderer/target
# omniphony-renderer/Cargo.lock is gitignored, so key off the tracked
# manifests instead (cache invalidates when a dependency changes).
key: ${{ runner.os }}-ci-cargo-${{ hashFiles('omniphony-renderer/**/Cargo.toml') }}
restore-keys: ${{ runner.os }}-ci-cargo-
# Fast fail before the heavy build if formatting drifts.
- name: Check formatting
working-directory: omniphony-renderer
run: cargo fmt --all -- --check
# ── Platform dependencies ─────────────────────────────────────────────
# Same PipeWire PPA as release.yml: ubuntu-22.04 ships PipeWire 0.3.48 but
# pipewire-rs 0.9.x needs >= 0.3.65. The GUI/Tauri libs are kept too so the
# whole workspace links exactly as in the release build (cheap, robust).
- name: Install Linux system dependencies
run: |
for attempt in 1 2 3; do
if sudo add-apt-repository ppa:pipewire-debian/pipewire-upstream -y; then
break
fi
if [ "$attempt" -eq 3 ]; then
echo "Failed to add PipeWire PPA after $attempt attempts" >&2
exit 1
fi
sleep 10
done
for attempt in 1 2 3; do
if sudo apt-get update; then
break
fi
if [ "$attempt" -eq 3 ]; then
echo "apt-get update failed after $attempt attempts" >&2
exit 1
fi
sleep 10
done
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
libssl-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
libpipewire-0.3-dev \
pkg-config
# ── Rust: build + test (strict gate) ──────────────────────────────────
# No --locked: omniphony-renderer/Cargo.lock is gitignored (matches
# release.yml, which also resolves dependencies fresh).
- name: Build renderer workspace
working-directory: omniphony-renderer
run: cargo build --workspace
- name: Test renderer workspace
working-directory: omniphony-renderer
run: cargo test --workspace
# ── C ABI smoke test (liborender) ──────────────────────────────────────
# Compile and run the header/link smoke test against the debug cdylib
# (debug builds skip the soname so the bare .so links directly). Guards
# the generated header, the exported symbols, and the version handshake —
# this is what mpv consumes, so it must never drift silently.
- name: C ABI smoke test (liborender)
working-directory: omniphony-renderer
run: |
cc -Wall -Werror -I orender_ffi/include orender_ffi/examples/smoke.c \
-L target/debug -lorender -o target/debug/orender_smoke
LD_LIBRARY_PATH=target/debug target/debug/orender_smoke
# ── Studio frontend build (no Tauri bundling / no sidecar) ─────────────
- name: Install Studio npm dependencies
working-directory: omniphony-studio
run: npm ci
- name: Build Studio frontend
working-directory: omniphony-studio
run: npm run build
# Translation parity is reported but never blocks a merge: incomplete
# locales fall back to English at runtime, so this is a heads-up, not a
# gate. Emits ::warning:: annotations on the PR.
- name: Check i18n parity (warn-only)
working-directory: omniphony-studio
continue-on-error: true
run: npm run i18n:check
# Dead-code gate (knip): a module with no importer fails the build.
# An orphaned ingestion module is how live-option state silently stopped
# reaching the UI for months (see docs/live-options-registry.md, "The
# incident"); unused *exports* are only warnings for now.
- name: Dead-code lint (knip)
working-directory: omniphony-studio
run: npm run lint:dead
# Options-schema contract: the renderer dumps its declared live options
# (registry rows); every option must resolve its Studio i18n keys. Hard
# gate — an option declared engine-side but invisible to the UI is the
# silent-omission class the registry exists to kill.
- name: Check options-schema ↔ Studio contract
run: |
cargo run -q -p renderer --example dump_options_schema \
--manifest-path omniphony-renderer/Cargo.toml > /tmp/options-schema.json
node omniphony-studio/scripts/check-options-schema.mjs /tmp/options-schema.json
build-macos:
# macOS arm64 compile gate. The renderer workspace pulls the CoreAudio
# output backend (cpal) and the `sys` signal/IO layer, both of which carry
# macOS-specific code paths. Build-only (no PipeWire/Tauri) — this catches
# macOS portability regressions on PRs, before the tag-triggered release
# builds (liborender / Studio / mpv) ever run on macOS.
runs-on: macos-14
steps:
- uses: actions/checkout@v5
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: Cache Cargo registry
uses: actions/cache@v5
continue-on-error: true
with:
path: |
~/.cargo/registry
~/.cargo/git
omniphony-renderer/target
key: macos-ci-cargo-${{ hashFiles('omniphony-renderer/**/Cargo.toml') }}
restore-keys: macos-ci-cargo-
- name: Build renderer workspace (macOS arm64)
working-directory: omniphony-renderer
run: cargo build --workspace