Repository navigation
feat(libretro): add rustysnes-libretro core crate (v1.2.0) #275
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| tags: ["v*"] | |
| pull_request: | |
| permissions: | |
| contents: read | |
| # Cancel a superseded run (a new push to the same PR/branch) instead of letting stale, already- | |
| # obsolete runs burn minutes to completion — the single biggest per-PR cost lever besides scoping | |
| # the full battery to tags (below). | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # Fast gate: every PR event (opened/synchronize/...) and every push to `main`. Formatting + | |
| # lint only (Linux) — the full test suite, the 3-OS matrix, the doc build, and the no_std build | |
| # are reserved for release-tag pushes (`full-test` / `no_std` below) so PR/push CI stays quick. | |
| # NOTE: a bare push to a feature branch with no open PR does NOT trigger this (the `push` | |
| # trigger above is scoped to `branches: [main]` + tag pushes) — every commit on a PR branch | |
| # still runs it via the `pull_request` `synchronize` event, so this is a non-issue in practice | |
| # for this project's branch-then-PR workflow, but don't rely on push-to-feature-branch CI. | |
| # The tradeoff: a broken PR is only caught by the full battery at the next tag, not on every | |
| # merge — accepted deliberately to keep iteration fast; the human-run pre-merge verification | |
| # gate (AGENTS.md) already covers the same ground per-PR before this even runs. | |
| lint: | |
| if: ${{ !startsWith(github.ref, 'refs/tags/v') }} | |
| env: | |
| CARGO_NET_RETRY: "10" | |
| CARGO_HTTP_MULTIPLEXING: "false" | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| # fmt/clippy only ever check the HOST target here (no `--target` is ever passed to either | |
| # command in this job) — installing the wasm32/thumbv7em cross targets bought nothing but | |
| # setup time on every single PR push. Only `no_std` (which actually cross-compiles) needs | |
| # thumbv7em-none-eabihf; nothing in ci.yml builds for wasm32 (that's `pages.yml`'s job). | |
| - uses: dtolnay/rust-toolchain@1.96 | |
| with: | |
| components: rustfmt, clippy | |
| - uses: Swatinem/rust-cache@v2 | |
| # The egui/winit frontend links against X11/Wayland/ALSA on Linux (see CONTRIBUTING.md). | |
| - name: Install Linux frontend system deps | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libxkbcommon-dev libwayland-dev libasound2-dev \ | |
| libudev-dev libx11-dev libxcursor-dev libxrandr-dev libxi-dev | |
| - run: cargo fmt --all --check | |
| - run: cargo clippy --workspace --all-targets -- -D warnings | |
| # Explicit flags-off byte-identical gate (`v0.8.0` T-81-004): `default` is currently | |
| # exactly `["wasm-winit", "help-tui"]`, so this is redundant with the line above TODAY — | |
| # its value is as a named regression guard. If a future change ever folds `debug-hooks`/ | |
| # `scripting`/`cheats`/`emu-thread` into `default` without updating this line too, this still | |
| # locks a true flags-off build/lint as its own explicit, protected CI step, independent of | |
| # whatever `default` becomes. | |
| - run: cargo clippy --workspace --all-targets --no-default-features --features wasm-winit,help-tui -- -D warnings | |
| # Per-feature-combo clippy (`v0.8.0` T-81-004, extended `v0.9.0` T-82-004) — each Phase 8 | |
| # `rustysnes-frontend` flag individually, then combined; NEVER `--all-features` (the | |
| # workspace-wide rule — `wasm-winit`/`wasm-canvas` are mutually exclusive, so an | |
| # all-features build doesn't even make sense). | |
| - run: cargo clippy -p rustysnes-frontend --all-targets --features debug-hooks -- -D warnings | |
| - run: cargo clippy -p rustysnes-frontend --all-targets --features scripting -- -D warnings | |
| - run: cargo clippy -p rustysnes-frontend --all-targets --features cheats -- -D warnings | |
| - run: cargo clippy -p rustysnes-frontend --all-targets --features netplay -- -D warnings | |
| - run: cargo clippy -p rustysnes-frontend --all-targets --features retroachievements -- -D warnings | |
| # `full` (`v1.0.0`, `cargo full-build`/`full-run`) IS this same combo (plus the no-op | |
| # `hd-pack` placeholder) — testing it directly instead of re-listing the flags keeps this | |
| # step and `full`'s own Cargo.toml definition from silently drifting apart. | |
| - run: cargo clippy -p rustysnes-frontend --all-targets --features full -- -D warnings | |
| # `rustysnes-libretro` (`v1.2.0`): already covered by the `--workspace` clippy line above (a | |
| # regular workspace member, no non-default features to combo over), but clippy doesn't | |
| # necessarily exercise the FFI-crate-specific bit that matters most for a `cdylib`/ | |
| # `staticlib`: does it actually LINK. A build-only step (not `cargo test` -- this crate has | |
| # no tests of its own; its logic lives in and is tested by `rustysnes-core`) is cheap and | |
| # catches a broken libretro C-ABI export/link before it reaches a release artifact. | |
| - run: cargo build -p rustysnes-libretro | |
| # Cheap locally (~4s) so it belongs on every PR, not just tag pushes -- catches broken | |
| # intra-doc links and rustdoc-specific warnings clippy's own lints don't cover. | |
| - run: RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps | |
| # Full gate: release-tag pushes ONLY (`v*`). The complete verification battery — the 3-OS | |
| # matrix, both test invocations, and the doc-warnings gate. | |
| full-test: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| env: | |
| CARGO_NET_RETRY: "10" | |
| CARGO_HTTP_MULTIPLEXING: "false" | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| # Same rationale as `lint`: neither fmt nor clippy nor `cargo test` cross-compiles here, so | |
| # no extra targets are installed. | |
| - uses: dtolnay/rust-toolchain@1.96 | |
| with: | |
| components: rustfmt, clippy | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| key: full-test-${{ matrix.os }} | |
| - name: Install Linux frontend system deps | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libxkbcommon-dev libwayland-dev libasound2-dev \ | |
| libudev-dev libx11-dev libxcursor-dev libxrandr-dev libxi-dev | |
| # Formatting is platform-independent (pure source-text parsing) — one leg is enough. | |
| - run: cargo fmt --all --check | |
| if: runner.os == 'Linux' | |
| - run: cargo clippy --workspace --all-targets -- -D warnings | |
| - run: cargo test --workspace | |
| - run: cargo test --workspace --features test-roms | |
| # Exhaustive behavioral coverage (not just clippy) of every Phase 8 flag together, ahead of | |
| # a tagged release (`v0.8.0` T-81-004, extended `v0.9.0` T-82-004). Linux-only, matching | |
| # `lint`'s per-combo clippy: `scripting` vendors and compiles Lua 5.4 via `mlua`'s C source, | |
| # and `retroachievements` vendors and compiles `rcheevos` via `cc` -- both real | |
| # cross-platform build surface `lint` never exercises (Linux only, host target) — verifying | |
| # that specifically on macOS/Windows here too is out of this ticket's scope (it's a genuine | |
| # question of its own, not "is the byte-identical-off gate wired up"). | |
| - run: cargo test -p rustysnes-frontend --features full | |
| if: runner.os == 'Linux' | |
| - run: RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps | |
| if: runner.os == 'Linux' | |
| # Release-tag pushes ONLY — see `lint` above for why this doesn't run on every PR/push. | |
| no_std: | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| env: | |
| CARGO_NET_RETRY: "10" | |
| CARGO_HTTP_MULTIPLEXING: "false" | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@1.96 | |
| with: | |
| targets: thumbv7em-none-eabihf | |
| - uses: Swatinem/rust-cache@v2 | |
| - run: cargo build -p rustysnes-core --target thumbv7em-none-eabihf --no-default-features | |
| # Release-tag pushes ONLY (`v1.0.0`): a release-mode Criterion build + run is too costly for | |
| # every PR push, and the frame-time gate is an absolute ceiling that only needs to hold at | |
| # release, not on every iteration — see `lint` above for the same rationale applied to | |
| # `full-test`/`no_std`. Ported from RustyNES's own `bench` job | |
| # (`scripts/bench_regression_check.sh` + `docs/performance.md`). | |
| bench: | |
| name: frame-time regression gate | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| env: | |
| CARGO_NET_RETRY: "10" | |
| CARGO_HTTP_MULTIPLEXING: "false" | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@1.96 | |
| - uses: Swatinem/rust-cache@v2 | |
| # The `rustysnes-core` `headless_frame` bench is chip-stack-only (no wgpu/winit/egui), so | |
| # no Linux frontend system deps are needed here (unlike `lint`/`full-test`). | |
| - run: ./scripts/bench_regression_check.sh |