Skip to content

Merge pull request #212 from PhysShell/claude/lab-boundary-context-re… #341

Merge pull request #212 from PhysShell/claude/lab-boundary-context-re…

Merge pull request #212 from PhysShell/claude/lab-boundary-context-re… #341

Workflow file for this run

# The gate AGENTS.md already documents — format, lint, test, doc — enforced.
# Until now nothing ran `cargo clippy -D warnings` or `cargo test --workspace`
# in CI, so lint regressions landed on `main` unnoticed (14 of them in the
# cockpit alone). The wasm render is checked separately by cockpit-web-test.
#
# `fuzz/` is a nightly, non-member crate (ADR-0010), so `--workspace` never
# reaches it; the `fuzz` job below is its gate — the crate sat silently
# broken from S16 Phase 2 until Phase 3's final slice tried to compile it,
# which is the whole argument for a blocking gate in one anecdote.
name: ci
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
jobs:
check:
runs-on: ubuntu-latest
steps:
# persist-credentials: false — later steps compile and run PR-authored
# code (build scripts, tests), so don't leave the token in .git/config
# for them to read (zizmor: artipacked).
- uses: actions/checkout@v4
with:
persist-credentials: false
# rust-toolchain.toml pins the channel and pulls in rustfmt + clippy.
- name: Show toolchain
run: rustc --version && cargo clippy --version && cargo fmt --version
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ci-${{ hashFiles('Cargo.lock', '**/Cargo.toml') }}
# eframe needs a windowing/GL stack to *link* the cockpit's native target.
- name: Install native deps
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libxcb-render0-dev libxcb-shape0-dev \
libxcb-xfixes0-dev libxkbcommon-dev libssl-dev libasound2-dev
- name: Format
run: cargo fmt --all --check
- name: Lint
run: cargo clippy --workspace --all-targets -- -D warnings
- name: Test
run: cargo test --workspace
# Not yet `-D warnings`: rustdoc flags five pre-existing findings in
# griff-core (an unresolved `AtomRest` link, public docs linking to
# private items). Deny once those are cleared.
- name: Doc
run: cargo doc --no-deps --workspace
# The MSRV is a promise; build on it or it rots. It sat at 1.74 for a year
# while egui/eframe 0.34 already demanded 1.92 — nobody on 1.74 could have
# built the cockpit.
msrv:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Read the MSRV from the workspace manifest
id: msrv
run: |
v=$(grep -m1 -E '^rust-version' Cargo.toml | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?')
echo "version=$v" >> "$GITHUB_OUTPUT"
echo "workspace MSRV: $v"
- name: Install the MSRV toolchain
run: rustup toolchain install ${{ steps.msrv.outputs.version }} --profile minimal
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: msrv-${{ steps.msrv.outputs.version }}-${{ hashFiles('Cargo.lock') }}
- name: Install native deps
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libxcb-render0-dev libxcb-shape0-dev \
libxcb-xfixes0-dev libxkbcommon-dev libssl-dev libasound2-dev
- name: Build on the MSRV
run: cargo +${{ steps.msrv.outputs.version }} check --workspace --all-targets
# ADR-0010 / docs/fuzzing.md: bounded smoke fuzz plus a replay of the
# committed corpus is a *blocking* PR gate (~60 s per implemented target,
# matrixed so wall-clock stays one target's worth). libFuzzer enforces the
# no-hang / no-unbounded-alloc half of the oracle via -timeout and the
# memory limits; the asserts in each target enforce the rest.
fuzz:
runs-on: ubuntu-latest
timeout-minutes: 25
strategy:
fail-fast: false
matrix:
target:
- midi_import
- midi_roundtrip
- semantic_diff
- score_projection
- guitar_pro_import
- phrase_boundary
- generation_request
- complement_request
- structure_metrics
- gesture_request
- swang_parse
- pattern_expansion
include:
# F-003 (docs/fuzzing.md): guitarpro-0.4.2 indexes measure headers
# by an unvalidated direction index — a panic inside the upstream
# crate that no adapter-side pre-validation can reach. Quarantined
# to signature-check only, *visibly*, with exit criteria in the
# findings registry: an upstream fix or a vendored patch turns the
# smoke back on.
- target: guitar_pro_import
smoke: skip
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
# fuzz/rust-toolchain.toml pins nightly for the crate itself; the
# explicit install keeps the first `cargo +nightly` from surprising us.
- name: Install nightly
run: rustup toolchain install nightly --profile minimal -c rustfmt -c clippy
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
~/.cargo/bin
fuzz/target
key: fuzz-${{ matrix.target }}-${{ hashFiles('fuzz/Cargo.toml', 'Cargo.lock') }}
- name: Install cargo-fuzz
run: command -v cargo-fuzz || cargo install cargo-fuzz --locked
# The signatures rot first (see the job comment): a plain check under
# the nightly pin catches API drift even before the smoke runs.
- name: Signatures stay compiled
working-directory: fuzz
run: cargo check --bins
- name: Bounded smoke + corpus replay
if: matrix.smoke != 'skip'
run: |
mkdir -p fuzz/corpus/${{ matrix.target }}
cargo +nightly fuzz run ${{ matrix.target }} -- \
-max_total_time=60 -timeout=60 -rss_limit_mb=4096 -malloc_limit_mb=2048
# A finding nobody can download is a finding nobody can minimize: keep
# the crashing inputs when the smoke fails.
- name: Keep any finding
if: failure()
uses: actions/upload-artifact@v4
with:
name: fuzz-artifacts-${{ matrix.target }}
path: fuzz/artifacts/
if-no-files-found: ignore