Files
freemkv-unlock/.github/workflows/ci.yml
T
Matthew Jackson dd73c5d3a1 ci: add non-required Codecov coverage job
Add an additive, non-required coverage job to CI that runs cargo
llvm-cov and uploads lcov to Codecov (tokenless, fail_ci_if_error
false). Mirrors the test job's environment and pinned 1.90.0 toolchain;
--locked is omitted to match this crate's gitignored-lockfile policy.
Adds codecov.yml (informational, comment off) and a README badge.
2026-08-25 18:54:57 -07:00

149 lines
6.5 KiB
YAML

name: CI
on:
push:
# dev -> qa -> main. `dev` is where work lands and is meant to be pushed
# to often: these are the FAST checks, so a mistake surfaces in minutes.
# `qa` is the release candidate — it runs these too, plus the expensive
# suite in qa.yml. `main` only ever moves at release time, to a tagged
# commit that was already green on qa.
branches: [main, dev, qa]
pull_request:
# freemkv-unlock is the BASE of the whole ecosystem: libfreemkv path-deps it,
# bdemu path-deps it with the `emulation` feature, and every other crate pulls
# it in transitively. It has no freemkv dependencies of its own, so no sibling
# checkout is needed here — but it is also the crate whose breakage takes all
# seven others down with it, which is why it gets the full OS matrix rather
# than a token Linux run.
#
# Cargo.lock is gitignored (library convention), so `--locked` is deliberately
# NOT used: with no committed lockfile it fails rather than resolves.
jobs:
# CI owns the changelog: main may never carry a released version without a
# CHANGELOG.md entry for it. The release orchestrator dates an existing
# `## [X.Y.Z]` heading — it does NOT invent one — so a version bump that
# forgot its changelog entry must fail here rather than ship a blank release.
# Hard-fails on main (and PRs targeting main); warns elsewhere so an
# in-progress dev/qa branch whose entry isn't written yet is not blocked.
changelog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@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)."
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@1.90.0
with:
components: clippy, rustfmt
- uses: Swatinem/rust-cache@v2
with:
shared-key: freemkv-unlock-ci
- run: cargo fmt --check
# --all-targets so the test code is linted too, not just the library.
- run: cargo clippy --all-targets -- -D warnings
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@1.90.0
- uses: Swatinem/rust-cache@v2
with:
shared-key: freemkv-unlock-ci
- run: cargo test --tests
# `emulation` is off by default and is the face bdemu builds against. A
# feature nothing compiles is a feature that breaks at release time.
- run: cargo test --tests --features emulation
# Coverage is additive and NON-REQUIRED: it uploads to Codecov but never
# gates a merge (fail_ci_if_error is false, and it is not wired into any
# release gate). It mirrors the `test` job's environment — same pinned
# toolchain, ubuntu-latest, no `if:` so it runs on every branch and PR just
# as `test` does. `--locked` is intentionally omitted to match this crate's
# policy (Cargo.lock is gitignored; --locked would fail without it).
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@1.90.0
with:
components: llvm-tools-preview
- uses: Swatinem/rust-cache@v2
with:
shared-key: freemkv-unlock-coverage
- uses: taiki-e/install-action@cargo-llvm-cov
- run: cargo llvm-cov --workspace --lcov --output-path lcov.info
- uses: codecov/codecov-action@v5
with:
files: lcov.info
slug: freemkv/freemkv-unlock
fail_ci_if_error: false
# The crate ships on macOS and Windows through its consumers, so it has to
# compile there. Build the tests (not just `cargo check`) — that forces
# codegen and catches errors in test-only code, which `check` skips.
check-macos:
# dev is the FAST lane: this job still runs, but on the release-candidate
# branches rather than on every push to dev. Nothing is deleted and no
# platform stops being checked before a release -- qa.yml independently
# covers macOS and Windows, and the jobs unique to this file (the Intel
# macOS build, the Windows release build) run here on qa and main. A push
# to dev is meant to be cheap and frequent; waiting on three runner pools
# to agree is what a release candidate is for.
#
# `if` SKIPS the job (it does not queue). A queued job would be far worse
# than a slow one: release.sh's CI gate refuses while any run for the
# commit is still in progress, so a never-scheduled job blocks releases
# silently -- see the note on real-media in qa.yml.
if: github.ref_name == 'qa' || github.ref_name == 'main'
runs-on: macos-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@1.90.0
- uses: Swatinem/rust-cache@v2
with:
shared-key: freemkv-unlock-ci
- run: cargo build --tests --all-features
check-windows:
# dev is the FAST lane: this job still runs, but on the release-candidate
# branches rather than on every push to dev. Nothing is deleted and no
# platform stops being checked before a release -- qa.yml independently
# covers macOS and Windows, and the jobs unique to this file (the Intel
# macOS build, the Windows release build) run here on qa and main. A push
# to dev is meant to be cheap and frequent; waiting on three runner pools
# to agree is what a release candidate is for.
#
# `if` SKIPS the job (it does not queue). A queued job would be far worse
# than a slow one: release.sh's CI gate refuses while any run for the
# commit is still in progress, so a never-scheduled job blocks releases
# silently -- see the note on real-media in qa.yml.
if: github.ref_name == 'qa' || github.ref_name == 'main'
runs-on: windows-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@1.90.0
- uses: Swatinem/rust-cache@v2
with:
shared-key: freemkv-unlock-ci
- run: cargo build --tests --all-features