Skip to content

Commit 001c640

Browse files
committed
feat(xtask,ci): add check features matrix gate with dynamic CI fan-out
Adds a feature-matrix CI gate per #1123 (CI: feature matrix including `arbitrary`). The case enumeration lives in xtask so the matrix is self-documenting and locally reproducible. `cargo xtask check features` is the new subcommand. Three modes: cargo xtask check features Run every case sequentially. Mirrors what CI does in aggregate. cargo xtask check features --case <NAME> Run a single case. CI matrix workers use this; the case name doubles as the local repro command for any failure. cargo xtask check features --list [--format <FMT>] Enumerate cases. `--format github-matrix` emits a JSON include array for `strategy.matrix.include: ${{ fromJson(...) }}`. Two new CI jobs in `.github/workflows/ci.yml`: feature-matrix-setup Preflight job. Runs `cargo xtask check features --list --format github-matrix` and emits the JSON via `$GITHUB_OUTPUT`. feature-matrix [${{ matrix.case }}] Fan-out job. Consumes the preflight output via fromJson and runs `cargo xtask check features --case '${{ matrix.case }}'` per case. Both join the existing `success` job's `needs` list so branch protection keeps a single required status check. Each worker writes a one-line markdown entry to `$GITHUB_STEP_SUMMARY` so failures show in the run summary view without expanding logs. Initial case set (10): - per-crate curated invariants (ironrdp-core std/alloc, ironrdp-pdu std/arbitrary/arbitrary-alloc) - workspace powersets partitioned by layer: foundation, pdu, channels, connector-session, runtime cargo-hack pinned at 0.6.44 in xtask/src/bin_version.rs, installed via the existing `cargo xtask check install` flow. ironrdp-tls / ironrdp-client / ironrdp-mstsgu intentionally outside the initial case set. cargo-hack does not honor package.metadata.cargo-hack, so the exactly-one-of TLS-backend constraint needs `--mutually-exclusive -features`, `--at-least-one-of`, and `--exclude-no-default-features` on the invocation. The powerset also surfaces a latent bug in `extract_tls_server_public_key` that uses `x509_cert::*` unconditionally instead of gating on `rustls | native-tls`. Both are tractable but out of scope for this gate's initial landing; the regular Checks job already exercises all three crates with their default features. Closes #1123 items 1-3 of the remediation set posted in issuecomment-4464512384. Items 4-5 (the `ironrdp-web` exclusion and the cargo-hack version pin) are folded into the per-case `extra_args` and `bin_version.rs` respectively. The TLS coverage gap is the remaining item from the original five. Signed-off-by: Greg Lamberson <greg@lamco.io> Assisted-by: Claude Code (Anthropic, Opus)
1 parent 18a430a commit 001c640

6 files changed

Lines changed: 374 additions & 2 deletions

File tree

.github/workflows/ci.yml

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,61 @@ jobs:
201201
- name: Build .NET projects
202202
run: cd ./ffi/dotnet && dotnet build
203203

204+
feature-matrix-setup:
205+
name: feature matrix setup
206+
needs: [formatting]
207+
runs-on: ubuntu-latest
208+
outputs:
209+
feature-matrix: ${{ steps.setup-matrix.outputs.feature-matrix }}
210+
211+
steps:
212+
- uses: actions/checkout@v6
213+
214+
- name: Rust cache
215+
uses: Swatinem/rust-cache@v2.7.3
216+
217+
- name: Setup matrix
218+
id: setup-matrix
219+
run: |
220+
MATRIX="$(cargo xtask check features --list --format github-matrix)"
221+
echo "feature-matrix=$MATRIX" >> "$GITHUB_OUTPUT"
222+
223+
feature-matrix:
224+
name: feature matrix [${{ matrix.case }}]
225+
needs: [formatting, feature-matrix-setup]
226+
runs-on: ubuntu-latest
227+
strategy:
228+
fail-fast: false
229+
matrix:
230+
include: ${{ fromJson(needs.feature-matrix-setup.outputs.feature-matrix) }}
231+
232+
steps:
233+
- uses: actions/checkout@v6
234+
235+
- name: Install devel packages
236+
run: |
237+
sudo apt-get update -qq
238+
sudo apt-get -y install libasound2-dev
239+
240+
- name: Rust cache
241+
uses: Swatinem/rust-cache@v2.7.3
242+
243+
- name: Binary cache
244+
uses: actions/cache@v5
245+
with:
246+
path: ./.cargo/local_root/bin
247+
key: ${{ runner.os }}-bin-${{ github.job }}-${{ hashFiles('xtask/src/bin_version.rs') }}
248+
249+
- name: Prepare
250+
run: cargo xtask check install -v
251+
252+
- name: Run feature-matrix case
253+
run: cargo xtask check features --case '${{ matrix.case }}' -v
254+
204255
success:
205256
name: Success
206257
if: ${{ always() }}
207-
needs: [formatting, typos, checks, fuzz, web, ffi]
258+
needs: [formatting, typos, checks, fuzz, web, ffi, feature-matrix-setup, feature-matrix]
208259
runs-on: ubuntu-latest
209260

210261
steps:

xtask/src/bin_version.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use crate::bin_install::CargoPackage;
55

66
pub const CARGO_FUZZ: CargoPackage = CargoPackage::new("cargo-fuzz", "0.12.0");
7+
pub const CARGO_HACK: CargoPackage = CargoPackage::new("cargo-hack", "0.6.44");
78
pub const CARGO_LLVM_COV: CargoPackage = CargoPackage::new("cargo-llvm-cov", "0.6.16");
89
pub const GRCOV: CargoPackage = CargoPackage::new("grcov", "0.8.20");
910
pub const WASM_PACK: CargoPackage = CargoPackage::new("wasm-pack", "0.13.1");

xtask/src/check.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ pub fn typos(sh: &Shell) -> anyhow::Result<()> {
4545
}
4646

4747
pub fn install(sh: &Shell) -> anyhow::Result<()> {
48-
let _s = Section::new("TYPOS-CLI-INSTALL");
48+
let _s = Section::new("CHECK-INSTALL");
4949

5050
cargo_install(sh, &TYPOS_CLI)?;
51+
cargo_install(sh, &CARGO_HACK)?;
5152

5253
Ok(())
5354
}

xtask/src/cli.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ TASKS:
1515
check locks Check for dirty or staged lock files not yet committed
1616
check tests [--no-run] Compile tests and, unless specified otherwise, run them
1717
check typos Check for typos in the codebase
18+
check features Run every feature-matrix case sequentially
19+
check features --case <NAME>
20+
Run a single feature-matrix case
21+
check features --list [--format <FMT>]
22+
List feature-matrix cases (fmt: human (default) | github-matrix)
1823
check install Install all requirements for check tasks
1924
ci Run all checks required on CI
2025
clean Clean workspace
@@ -62,6 +67,11 @@ pub enum Action {
6267
no_run: bool,
6368
},
6469
CheckTypos,
70+
CheckFeatures {
71+
case: Option<String>,
72+
list: bool,
73+
format: Option<String>,
74+
},
6575
CheckInstall,
6676
Ci,
6777
Clean,
@@ -116,6 +126,11 @@ pub fn parse_args() -> anyhow::Result<Args> {
116126
no_run: args.contains("--no-run"),
117127
},
118128
Some("typos") => Action::CheckTypos,
129+
Some("features") => Action::CheckFeatures {
130+
case: args.opt_value_from_str("--case")?,
131+
list: args.contains("--list"),
132+
format: args.opt_value_from_str("--format")?,
133+
},
119134
Some("install") => Action::CheckInstall,
120135
Some(unknown) => anyhow::bail!("unknown check action: {unknown}"),
121136
None => Action::ShowHelp,

0 commit comments

Comments
 (0)