epiphany/.github/workflows/ci.yml

208 lines
8.0 KiB
YAML

name: CI
# The QUICKSTART requires Agent F's conformance suite to run in CI "from the day
# Agent A lands" — it is the architecture's tripwire. This workflow runs the
# whole workspace's checks plus the testkit's conformance suite on every push and
# pull request.
on:
push:
branches: [main, master]
pull_request:
schedule:
# Nightly soak at 04:17 UTC.
- cron: "17 4 * * *"
env:
CARGO_TERM_COLOR: always
RUSTFLAGS: -D warnings
# Every blocking job pins an exact toolchain. With `-D warnings` and a
# floating `stable`, a Rust release turns this gate red with no repo change —
# which is exactly how it first failed, eight days after 1.97.1 added
# `float_literal_f32_fallback`. Worse, the developer machine cannot install
# arbitrary toolchains, so such a failure is unreproducible locally and the
# local gate stops meaning anything. Pinned here to the version developed
# against; bump it deliberately, as its own commit, with the lints it
# introduces fixed in that commit. The nightly soak floats on `stable` and is
# the drift detector.
PINNED_STABLE: "1.95.0"
jobs:
# Style and lint policy runs on exactly ONE toolchain, the pinned stable.
#
# It used to run on the MSRV toolchain as well, and that is not a stricter
# gate — it is a different one. Two clippy versions have two lint sets, and
# they can disagree in opposite directions: clippy 1.85 demands
# `.and_then(seg_pos)` where 1.95 is silent, while 1.97 rejects a bare `2.0`
# that 1.95 accepts. Satisfying the union is not a quality bar, it is a
# coincidence, and no developer can reproduce it locally without installing
# every toolchain in the matrix. Lints here; the MSRV job proves the floor
# compiles and passes its tests, which is the only thing an MSRV can mean.
lint:
name: fmt / clippy / doc (pinned stable)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust (pinned stable)
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.PINNED_STABLE }}
components: rustfmt, clippy
- name: Install GUI build dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev \
libxkbcommon-dev libssl-dev
- name: Cache cargo
uses: Swatinem/rust-cache@v2
- name: Formatting
run: cargo fmt --all -- --check
# The whole workspace, GUI crate included: on the pinned stable there is
# no toolchain reason to split it out.
- name: Clippy (all targets)
run: cargo clippy --workspace --all-targets -- -D warnings
# Deny rustdoc warnings (broken/private intra-doc links, etc.). `RUSTFLAGS`
# does not cover rustdoc, so `RUSTDOCFLAGS` is set explicitly.
- name: Doc warnings (workspace)
env:
RUSTDOCFLAGS: -D warnings
run: cargo doc --workspace --no-deps
# The floor, and only the floor: does the code this repository claims to
# support on 1.85 actually build and pass its tests there? No lints — see the
# `lint` job's comment.
check:
name: MSRV build + test (1.85)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust (pinned MSRV)
uses: dtolnay/rust-toolchain@stable
with:
toolchain: "1.85"
- name: Cache cargo
uses: Swatinem/rust-cache@v2
# The demo GUI crate (eframe/resvg) pulls `image`, which declares 1.88, so
# it cannot build at the floor and is excluded here. It is linted in
# `lint` and tested in `editor-gui`, both on the pinned stable.
- name: Test (workspace)
run: cargo test --workspace --exclude epiphany-editor-gui --all-targets
- name: Doc tests
run: cargo test --workspace --exclude epiphany-editor-gui --doc
# The demo GUI crate's tests, kept as their own job so a GUI break is its own
# attributable signal rather than a regression buried in the core crates. Its
# eframe/resvg tree pulls `image`, which declares 1.88 — three releases above
# the workspace floor — so it cannot run in the MSRV job. Linting for this
# crate lives in `lint` with the rest of the workspace.
editor-gui:
name: editor GUI tests (pinned stable)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust (pinned stable)
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.PINNED_STABLE }}
- name: Install GUI build dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev \
libxkbcommon-dev libssl-dev
- name: Cache cargo
uses: Swatinem/rust-cache@v2
- name: Test (GUI)
run: cargo test -p epiphany-editor-gui
conformance:
name: conformance suite (testkit)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.PINNED_STABLE }}
- name: Cache cargo
uses: Swatinem/rust-cache@v2
# The full conformance suite at scale 1: Agent A's 1,000,000-iteration
# determinism gate, the round-trip corpus, the crash-recovery and
# manifest-selection gates, convergence / reduction-determinism /
# equivocation against the real epiphany-ops, and the layout round-trip.
- name: Run conformance suite
run: cargo run --release -p epiphany-testkit --example conformance_suite 1
# The Chapter 10 performance-budget gates (Phase 2 worklist F1), in
# release with reduced sampling (EPIPHANY_BENCH_QUICK): the 1K and 10K
# reduction points and both bundle budgets must pass; known-pending
# points are documented xfails inside the benches ("F surfaces, K
# fixes"). The heaviest (50K) reduction point runs only in the nightly
# soak below.
- name: Performance budget gates (quick)
env:
EPIPHANY_BENCH_QUICK: "1"
run: cargo bench -p epiphany-testkit
# Track A, Agent H's merge gate (Phase 2). A discrete job so a spelling /
# decomposition pre-pass regression is attributable to H, not buried in the
# workspace test run. Asserts H's PHASE2_QUICKSTART acceptance criterion: the
# representative-corpus eligibility taxonomy (F3) and the pre-pass harness (F4 —
# determinism, spelling correctness, decomposition reconstruction, RespellPitch
# precedence, non-vacuity). The same gate also runs inside the conformance
# suite's stage [7b]; this job isolates it for fast, attributable feedback.
prepass-harness:
name: Agent H pre-pass gate (testkit)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.PINNED_STABLE }}
- name: Cache cargo
uses: Swatinem/rust-cache@v2
- name: H spelling + decomposition merge gate
run: cargo test -p epiphany-testkit --test prepass
# A longer soak, scheduled nightly, exploring a wider seed space at scale.
# This job deliberately floats on `stable` while every blocking job is pinned:
# it is where toolchain drift surfaces, on a schedule, instead of in a push
# that has nothing to do with it. A red soak against a green push means Rust
# moved, not that the change did.
soak:
name: conformance soak (nightly)
if: github.event_name == 'schedule'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Run conformance soak
run: cargo run --release -p epiphany-testkit --example conformance_suite 10
# The full budget-gate run, including the minute-scale 50K reduction
# point (a documented xfail until the O(n²) reducer fix lands).
- name: Performance budget gates (full)
run: cargo bench -p epiphany-testkit