Files
libfreemkv/.github/workflows/ci.yml
T
Matthew Jackson 4031513574 audit: module-by-module code audit fixes and test coverage
Lands the code-audit branches for aacs, css, keys, labels, udf, ifo and
dvd, bdnav/mpls/clpi, disc/bluray, extract, io, scsi, the mkv, mp4,
network and mpg muxers, the audio and video codecs, and CI. Fixes
include MKB and FMTS validation, UDF bounds, IFO fallback to the BUP,
DTS Express framing, MPEG-2 field pairing and mpg re-basing; the rest
pins existing behaviour with tests.
2026-09-29 20:45:05 -07:00

293 lines
12 KiB
YAML

name: CI
on:
push:
# dev -> qa -> main. `dev` is where work lands and is pushed to often: these
# are the FAST checks. `qa` runs these plus the expensive suite in qa.yml.
# `main` only moves at release time, to a commit already green on qa.
branches: [main, dev, qa]
pull_request:
# Rapid dev pushes supersede their own in-progress runs instead of stacking.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# Single source of truth for the MSRV: `rust-version` in Cargo.toml. Every job
# that builds AT the MSRV consumes needs.resolve-msrv.outputs.v so the floor
# cannot drift. clippy and `consumers` deliberately run on `stable`.
resolve-msrv:
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
v: ${{ steps.msrv.outputs.v }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- id: msrv
shell: bash
run: echo "v=$(grep -m1 '^rust-version' Cargo.toml | sed -E 's/.*\"([^\"]+)\".*/\1/')" >> "$GITHUB_OUTPUT"
# main may never carry a released version without a CHANGELOG.md entry. Hard-
# fails on main (and PRs to main); warns elsewhere so an in-progress branch
# whose entry isn't written yet is not blocked.
changelog:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Require a CHANGELOG entry for the crate version on main
shell: bash
run: |
set -euo pipefail
version=$(grep -m1 '^version = ' Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')
if grep -qE "^## \[${version}\]" CHANGELOG.md; then
echo "CHANGELOG.md has an entry for ${version}."
exit 0
fi
msg="CHANGELOG.md has no '## [${version}]' entry"
if [ "${GITHUB_REF_NAME:-}" = "main" ] || [ "${GITHUB_BASE_REF:-}" = "main" ]; then
echo "::error::${msg} — main requires a changelog entry for the released version."
exit 1
fi
echo "::warning::${msg} (allowed on ${GITHUB_REF_NAME:-unknown}; required before it can reach main)."
# fmt on the pinned MSRV; clippy on stable so new-lint debt is a blocking gate
# the pinned version would hide. --all-targets lints test code too.
lint:
needs: resolve-msrv
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
path: libfreemkv
- uses: freemkv/.github/.github/actions/checkout-siblings@v1
with:
checkout: freemkv-unlock
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
components: clippy
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ needs.resolve-msrv.outputs.v }}
components: rustfmt
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
workspaces: libfreemkv
- run: cargo fmt --check
working-directory: libfreemkv
- run: cargo +stable clippy --all-targets -- -D warnings
working-directory: libfreemkv
test:
needs: resolve-msrv
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
path: libfreemkv
- uses: freemkv/.github/.github/actions/checkout-siblings@v1
with:
checkout: freemkv-unlock
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ needs.resolve-msrv.outputs.v }}
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
workspaces: libfreemkv
- run: cargo test --tests
working-directory: libfreemkv
# `--tests` skips doctests; the keys compile_fail doctests enforce spec LK19.
- run: cargo test --doc
working-directory: libfreemkv
# The memory orderings in `scsi::fd_handoff` (and `halt`) compile to the same instructions
# on x86_64, so the WRONG ones pass every run; loom enumerates the executions
# the C++20 model permits and is the only regression coverage that code has.
# Its own job because RUSTFLAGS is part of the rust-cache key. Takes the sibling
# checkout even with --no-default-features: features don't exempt an optional
# path dep from manifest RESOLUTION.
loom:
needs: resolve-msrv
runs-on: ubuntu-latest
timeout-minutes: 30
env:
RUSTFLAGS: --cfg loom
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
path: libfreemkv
- uses: freemkv/.github/.github/actions/checkout-siblings@v1
with:
checkout: freemkv-unlock
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ needs.resolve-msrv.outputs.v }}
components: clippy
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
workspaces: libfreemkv
- run: cargo test --lib --no-default-features --features scsi fd_handoff
working-directory: libfreemkv
# LT3: `Halt`'s cancel Release / observe Acquire pair (stop design §2.1, SS-23).
- run: cargo test --lib --no-default-features --features scsi loom_halt
working-directory: libfreemkv
# `lint` runs clippy without --cfg loom, so this is the only place the
# model code is linted at all.
- run: cargo clippy --lib --no-default-features --features scsi --profile test -- -D warnings
working-directory: libfreemkv
deny:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
path: libfreemkv
- uses: freemkv/.github/.github/actions/checkout-siblings@v1
with:
checkout: freemkv-unlock
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
- uses: EmbarkStudios/cargo-deny-action@3c6349835b2b7b196a839186cb8b78e02f7b5f25 # v2
with:
command: check advisories bans licenses sources
manifest-path: libfreemkv/Cargo.toml
# dev is the FAST lane: the platform jobs run on qa/main only (qa.yml also
# covers macOS/Windows). `if` SKIPS (does not queue) so a never-scheduled job
# can't block the release gate.
check-macos:
needs: resolve-msrv
if: github.ref_name == 'qa' || github.ref_name == 'main'
runs-on: macos-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
path: libfreemkv
- uses: freemkv/.github/.github/actions/checkout-siblings@v1
with:
checkout: freemkv-unlock
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ needs.resolve-msrv.outputs.v }}
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
workspaces: libfreemkv
- run: cargo check
working-directory: libfreemkv
check-windows:
needs: resolve-msrv
if: github.ref_name == 'qa' || github.ref_name == 'main'
runs-on: windows-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
path: libfreemkv
- uses: freemkv/.github/.github/actions/checkout-siblings@v1
with:
checkout: freemkv-unlock
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ needs.resolve-msrv.outputs.v }}
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
workspaces: libfreemkv
# Build the tests: forces full codegen of the Windows-only SPTI transport
# (src/scsi/windows.rs), which never compiles on Linux/macOS dev hosts.
- run: cargo build --tests
working-directory: libfreemkv
# Did this change break anything downstream? libfreemkv sits below all four
# dependents; a break here is worth strictly more than anywhere else. Runs
# their suites (not just check) — a behavioural change keeps signatures but
# fails a dependent's tests, which is the shape worth catching. This caught an
# engine fixture break the moment it landed, so it stays on the dev fast lane.
consumers:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with: { path: libfreemkv }
- uses: freemkv/.github/.github/actions/checkout-siblings@v1
with:
checkout: freemkv-unlock freemkv-keysources freemkv-engine freemkv-i18n freemkv bdemu
- name: Point every dependent at THIS libfreemkv commit
shell: bash
run: |
for c in freemkv-keysources freemkv-engine freemkv bdemu; do
mkdir -p "$c/.cargo"
cat > "$c/.cargo/config.toml" <<'EOF'
[patch.crates-io]
libfreemkv = { path = "../libfreemkv" }
freemkv-keysources = { path = "../freemkv-keysources" }
freemkv-engine = { path = "../freemkv-engine" }
freemkv-i18n = { path = "../freemkv-i18n" }
EOF
done
# freemkv's app build (`--features gui`) compiles a GTK4 + libadwaita
# shell, so testing it needs these pkg-config dev headers.
- name: Install GTK4 + libadwaita development headers (for freemkv)
run: |
sudo apt-get update
sudo apt-get install -y libgtk-4-dev libadwaita-1-dev build-essential
# Dependents track the highest supported Rust — build on stable so this job
# satisfies the highest dependent floor (the library's own lower MSRV, which
# the `test` job verifies, cannot compile them).
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
workspaces: |
freemkv-keysources
freemkv-engine
freemkv
bdemu
- run: cargo test --tests
working-directory: freemkv-keysources
- run: cargo test --tests
working-directory: freemkv-engine
- run: cargo test --tests
working-directory: freemkv
- run: cargo test --tests --features gui
working-directory: freemkv
- run: cargo test --tests
working-directory: bdemu
# Coverage: non-required, informational only (codecov.yml), no job needs: it.
coverage:
needs: resolve-msrv
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
path: libfreemkv
- uses: freemkv/.github/.github/actions/checkout-siblings@v1
with:
checkout: freemkv-unlock
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ needs.resolve-msrv.outputs.v }}
components: llvm-tools-preview
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
workspaces: libfreemkv
- uses: taiki-e/install-action@72f835688cb6c15903b796f704b01e652a2b8835 # cargo-llvm-cov
- run: cargo llvm-cov --workspace --ignore-run-fail --lcov --output-path lcov.info
working-directory: libfreemkv
- uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: libfreemkv/lcov.info
slug: freemkv/libfreemkv
fail_ci_if_error: false