1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
name: CI
on:
push:
branches:
pull_request:
branches:
env:
CARGO_TERM_COLOR: always
permissions:
contents: read
pull-requests: read
jobs:
check:
name: Build, Test, Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Cache cargo registry and build
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- name: Check formatting
run: cargo fmt --all -- --check
- name: Clippy
run: cargo clippy --all-targets -- -D warnings
- name: Build (release)
run: cargo build --release
- name: Test
env:
# Opt into the gated `cargo rustc` integration test that
# codifies the PR #34 overlay-staging-path fix
# (`cargo_accepts_staged_overlay_for_dylib_build` in
# `tests/compat/overlay_determinism.rs`). The gate exists so
# RAM-limited local boxes can skip the test by default; CI
# explicitly opts in to make the test authoritative.
LIHAAF_RUN_CARGO_BUILD_TESTS: "1"
run: cargo test
- name: Self-test corpus end-to-end
# Build cargo-lihaaf and run it against the in-tree
# `tests/lihaaf/{compile_pass,compile_fail,compile_pass_suite_demo}/`
# corpus. The corpus is `[package.metadata.lihaaf]` self-
# references — lihaaf builds itself as the dylib_crate and links
# each fixture against it.
#
# `cargo lihaaf` (no `--suite`) runs every defined suite in
# declared metadata order: the implicit `default` suite over
# `compile_fail/` + `compile_pass/`, then the named
# `suite_demo` suite over `compile_pass_suite_demo/` with
# `--features suite_demo` activated. The named suite proves
# the v0.1.0-alpha.3 multi-suite capability propagates the
# feature set to BOTH the dylib build AND the per-fixture rustc
# invocation: the demo fixture references
# `lihaaf::SUITE_DEMO_MARKER` (only exposed under the feature),
# so any regression that drops feature propagation fails to
# link and CI flips red.
#
# A non-zero exit fails CI; the success path proves the full
# session pipeline (config load → toolchain capture → per-suite
# dylib build → per-suite manifest refresh → discovery → worker
# pool dispatch with §4.5 freshness checks → §3.3 aggregate
# report) works end-to-end on the current toolchain across two
# independent suites.
run: cargo run --release --bin cargo-lihaaf -- lihaaf
- name: Self-test corpus (integration_corpus)
# FIX_BEFORE_BETA Spec D: a real-adopter-shaped integration
# corpus that exercises lihaaf's negative-path verdict classes
# in CI. The corpus lives under `tests/integration_corpus/`
# (excluded from lihaaf's own package via `[package].exclude`
# in the root Cargo.toml) and uses a two-crate layout — a
# regular library `integration_corpus` (which lihaaf builds as
# the dylib_crate) plus a sibling `integration_corpus_macros`
# proc-macro crate (which lihaaf cannot build as a dylib;
# cargo rejects `[lib] proc-macro = true` with
# `--crate-type=dylib`). The macros are re-exported through
# the parent crate so fixtures use a single
# `use integration_corpus::*;` shape (the serde/serde_derive
# layout).
#
# The six fixtures cover one verdict class each:
# - uses_corpus_noop.rs → OK (no-op macro + const)
# - corpus_error_basic.rs → OK (snapshot match)
# - large_snapshot.rs → SNAPSHOT_DIFF + LARGE_SNAPSHOT
# warning (>10K-line diagnostic
# with one mutated snapshot line)
# - missing_snapshot.rs → SNAPSHOT_MISSING (no .stderr)
# - intentional_timeout.rs → TIMEOUT (macro sleeps forever)
# - intentional_oom.rs → MEMORY_EXHAUSTED (paced 16 MiB
# writes against a 128 MiB cap)
#
# The grep gates anchor on the verdict labels in
# `src/verdict.rs::Verdict::label` and on the warning line
# emitted in `src/session.rs::emit_fixture_warnings`. Any
# regression that drops one of those labels — e.g. renaming
# `MEMORY_EXHAUSTED` to `OOM`, dropping the LARGE_SNAPSHOT
# warning emit, or short-circuiting the snapshot-missing path
# — flips CI red here, even if the rest of lihaaf still builds
# and the self-test suite still passes.
#
# `|| true` after `tee` ensures the verdict-bearing lihaaf
# invocation does not fail the step (lihaaf exits non-zero
# whenever fixtures don't all pass — by design, this corpus
# has four deliberate failures); the six `grep -q` calls are
# the real assertion: four negative-verdict labels, the
# LARGE_SNAPSHOT warning, and the aggregate summary line.
run: |
cargo run --release --bin cargo-lihaaf -- lihaaf \
--manifest-path tests/integration_corpus/Cargo.toml \
--quiet 2>&1 | tee /tmp/corpus.log || true
grep -q SNAPSHOT_MISSING /tmp/corpus.log
grep -q TIMEOUT /tmp/corpus.log
grep -q MEMORY_EXHAUSTED /tmp/corpus.log
grep -q LARGE_SNAPSHOT /tmp/corpus.log
grep -q SNAPSHOT_DIFF /tmp/corpus.log
grep -qE 'lihaaf: 2 ok, 2 failed, 1 timeout, 1 memory_exhausted' /tmp/corpus.log
env:
CARGO_TERM_COLOR: always
- name: Secrets-scan self-tests
run: bash scripts/run-scan-tests.sh
docs:
name: cargo doc
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry and build
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-docs-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-docs-
- name: cargo doc (warnings as errors)
env:
RUSTDOCFLAGS: "-D warnings"
run: cargo doc --no-deps
audit:
name: cargo audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install cargo-audit
run: cargo install --locked cargo-audit
- name: Run cargo audit
run: cargo audit