From c3a3b1014e09ffd0b98ce25ebb6bdb673d2bd22f Mon Sep 17 00:00:00 2001 From: mehmetkr-31 Date: Sat, 8 Aug 2026 18:29:45 +0300 Subject: [PATCH] ci: add per-crate feature matrix check with cargo-hack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both existing Rust checks run workspace-scoped, so cargo unifies features across members and each crate's feature set is only ever validated in combination — never in the configuration a downstream consumer or `cargo publish` would build. Two shipped bugs came from that blind spot (#233, #236), and neither existing job reports them: cargo check --workspace --all-features # 0 errors cargo check --workspace --no-default-features # 0 errors cargo-hack decomposes `--workspace` into per-package runs (`cargo check --manifest-path crates//Cargo.toml ...`), which is the whole mechanism — adding flags to the workspace-scoped jobs catches nothing. `arc-signer` gets its own invocation. Its `compile_error!("At least one signing provider feature must be enabled")` guard is correct code, but cargo-hack counts the bare `--no-default-features` run as a failure. `--exclude-no-default-features` drops exactly that one configuration and still checks each of the crate's five features individually, rather than exempting the crate wholesale. Closes #240 Co-Authored-By: Claude Opus 5 --- .github/workflows/ci.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b655f8fa..77abde3a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,6 +67,39 @@ jobs: - name: Run clippy run: cargo clippy --all-targets --all-features -- -D warnings + # Workspace-scoped checks unify features across members, so a crate's own + # feature set is only ever validated in combination. cargo-hack decomposes + # --workspace into per-package runs, which is what catches features that + # build only because another member supplied the missing dependency. + rust-feature-matrix: + name: Rust Feature Matrix + needs: rust-lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + + - name: Install system dependencies + run: sudo apt-get update && sudo apt-get install -y --no-install-recommends libclang-dev zlib1g-dev + + - name: Install Rust toolchain + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + cache-shared-key: rust-feature-matrix + + - name: Install cargo-hack + uses: taiki-e/install-action@v2 + with: + tool: cargo-hack + + - name: Check each feature per crate + run: cargo hack check --each-feature --workspace --exclude arc-signer --locked + + # arc-signer is checked separately: its `compile_error!` guard rejects the + # empty provider set by design, so only the bare --no-default-features run + # is dropped. Every individual feature of the crate is still checked. + - name: Check each feature for arc-signer + run: cargo hack check --each-feature --exclude-no-default-features -p arc-signer --locked + rust-test: name: Rust Unit Tests needs: rust-lint