From 0b467cca067917ce82c34c1545f7672a8f113807 Mon Sep 17 00:00:00 2001 From: ccross Date: Mon, 24 Aug 2026 16:50:45 -0400 Subject: [PATCH] fix: the published MSRV was false, and CI now verifies it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cargo.toml declared rust-version = "1.75". Measured against the resolved dependency graph, that is not stale — it is false: 346 packages, 251 declaring a rust-version 59 require > 1.75, including DIRECT dependencies: ort 1.88 image 1.88 zbus 1.87 The true floor is 1.88. The crate could not build on the version it advertised, and anyone who trusted the field got a failure deep inside a dependency rather than a clear "your toolchain is too old". Nothing checked it. This is the fifth instance in this repository of a claim in one artifact that nothing in another artifact enforces — after the release trigger (#75), the network-isolation claim (#78) and TimeoutStopSec. A new `msrv` job reads the version from Cargo.toml (so the manifest stays the single source of truth) and builds at it, refusing rather than proceeding if the field is absent. CORRECTION TO #87. That commit avoided clippy's suggested `as_chunks::<4>()` on the grounds that it is stable since 1.88 and would "raise MSRV by thirteen minor versions". `ort` already required 1.88, so the constraint being honoured did not exist. The code is still correct — indexing works on every toolchain and couples to no lint name — but the stated justification overstated the cost. Recorded here rather than quietly dropped, because that reasoning is in a merged commit message, a PR body and an ADR. Also, two CI drift fixes of the same class: - `cargo install cargo-deb` is pinned to 3.7.0. It produces the SHIPPED artifact, and an unpinned install is exactly the drift that took CI down for six days on 2026-08-24. It happened to resolve to the same version locally and in CI that day by luck, not design. - Both clippy invocations gain `--all-targets`, so the five integration tests added in #91 are actually linted in CI. They were clean locally and invisible to CI. Verified: actionlint exit 0; the MSRV extraction returns 1.88 and a manifest with no rust-version trips the refusal; fmt clean; clippy --all-targets clean; 93 tests pass, 0 failures. NOT verified locally: that the workspace builds at 1.88. This machine's toolchain is 1.95 and no 1.88 is available here. `cargo check --workspace --all-targets --locked` passes at 1.95, which is a proxy only — the new msrv job is the real check, and this PR is where it runs for the first time. Signed-off-by: ccross Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/ci.yml | 58 +++++++++++++++++++++++++++++++++++++--- Cargo.toml | 7 ++++- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c8bf8cb..a16f06f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,7 +52,10 @@ jobs: run: cargo fmt --all -- --check - name: Clippy - run: cargo clippy --workspace -- -D warnings + # --all-targets so integration tests under crates/*/tests/ are linted + # too. Without it the five contract tests added in #91 are invisible + # to CI even though they are clean locally. + run: cargo clippy --workspace --all-targets -- -D warnings - name: Build run: cargo build --release --workspace @@ -99,7 +102,11 @@ jobs: key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - name: Install cargo-deb - run: cargo install cargo-deb + # Pinned. This tool produces the SHIPPED artifact, and an unpinned + # `cargo install` is the same drift class that took CI down for six + # days on 2026-08-24 (see rust-toolchain.toml). It happened to resolve + # to the same version locally and in CI that day — by luck, not design. + run: cargo install cargo-deb --version 3.7.0 --locked - name: Build release run: cargo build --release --workspace @@ -220,4 +227,49 @@ jobs: run: cargo clippy --version - name: Clippy on current stable - run: cargo clippy --workspace -- -D warnings + run: cargo clippy --workspace --all-targets -- -D warnings + + msrv: + # Verifies the MSRV we PUBLISH is true. + # + # `Cargo.toml` declared rust-version = "1.75" until 2026-08-24. That was not + # stale, it was false: `ort` and `image` both require 1.88, and 59 packages + # in the resolved graph require more than 1.75. The crate could not build on + # the version it advertised, and anyone who trusted the field got a failure + # deep inside a dependency rather than a clear "your toolchain is too old". + # + # Nothing checked it. That is the fifth instance in this repository of a + # claim in one artifact that nothing in another artifact enforces — see also + # the release trigger (#75), the network-isolation claim (#78), and + # TimeoutStopSec. This job closes it for the MSRV. + # + # The version is read from Cargo.toml, so the manifest stays the single + # source of truth and this job cannot drift from it. + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v7 + + - name: Install system dependencies + run: sudo apt-get update && sudo apt-get install -y libpam0g-dev libdbus-1-dev + + - name: Read the declared MSRV + id: msrv + run: | + set -euo pipefail + msrv="$(grep '^rust-version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')" + # Refuse rather than hand the action an empty string it would resolve + # to something else — the same failure shape as the release trigger. + if [ -z "$msrv" ]; then + echo "::error::no rust-version found in Cargo.toml — nothing to verify" + exit 1 + fi + echo "verifying the published MSRV: ${msrv}" + echo "version=${msrv}" >> "$GITHUB_OUTPUT" + + - name: Install the declared MSRV toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ steps.msrv.outputs.version }} + + - name: Build at the declared MSRV + run: cargo check --workspace --all-targets --locked diff --git a/Cargo.toml b/Cargo.toml index 1504dfc..d0d8fd5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,12 @@ version = "0.4.0-rc.1" edition = "2021" license = "MIT" repository = "https://github.com/sovren-software/visage" -rust-version = "1.75" +# Measured 2026-08-24, not guessed: `ort` and `image` both declare 1.88, and 59 +# packages in the resolved graph require > 1.75. The previous value of 1.75 was +# not stale — it was false. The crate could not build on it, and anyone who +# trusted the field got a failure deep inside a dependency instead of a clear +# "your toolchain is too old". The `msrv` CI job now verifies this. +rust-version = "1.88" [workspace.dependencies] # Async runtime