Skip to content

ci: declare the oldest toolchain that works, and hold it there - #110

Merged
rrrodzilla merged 1 commit into
mainfrom
chore/13-msrv
Jul 31, 2026
Merged

ci: declare the oldest toolchain that works, and hold it there#110
rrrodzilla merged 1 commit into
mainfrom
chore/13-msrv

Conversation

@rrrodzilla

Copy link
Copy Markdown
Contributor

Closes #13. (#11, which blocked it, is merged.)

No crate declared rust-version. Consumers got no MSRV signal, and nothing stopped an accidental bump: the next dependency update or the next if let ... && raises it silently, and the first anyone hears is a build failing somewhere else.

The floor is 1.91

Established by building on each candidate, not guessed:

Toolchain Result
1.90 Fails — Duration::from_mins / from_hours are unstable, and unstable as const fn
1.91 Builds --workspace --all-features clean

Those two constructors are what the attestation crate's DEFAULT_LEEWAY and default TTL are written in terms of; they stabilized in 1.91. Set once on [workspace.package], inherited by all seven crates.

The check

A declared MSRV that nothing verifies is a claim, not a guarantee. The new msrv job reads the version out of Cargo.toml and installs that exact toolchain, so the declaration and the check cannot drift apart — bumping one line bumps both.

It runs cargo build --workspace --all-features rather than the test suite, deliberately: the MSRV is a promise about compiling this workspace's code, and the dev-dependencies (nextest, criterion, the libp2p test harnesses) carry higher floors of their own that no consumer inherits. Testing would pin the MSRV to whatever the test tooling needs, which is a stricter and less useful number.

task msrv runs the same thing locally, reading the same line.

Injection note

Cargo.toml is repository content, and on a fork's pull request that is the contributor's content. The version is matched against a version shape (grep -oE) before it reaches $GITHUB_OUTPUT, so a crafted manifest cannot smuggle a newline and define step outputs of its own. It is consumed by with: toolchain:, never interpolated into a shell command.

Also

The README states the MSRV under Quick Start and lists task msrv in the testing table.

fmt, clippy, 1079 tests clean, plus a verified cargo +1.91 build --workspace --all-features.

No crate declared rust-version, so consumers got no MSRV signal and nothing
stopped an accidental bump: the next dependency update or the next `if let
... &&` would raise it silently, and the first anyone would hear is a build
failing somewhere else.

The floor is 1.91, established by building on each candidate rather than
guessing. 1.90 rejects Duration::from_mins and from_hours, which the
attestation crate's default leeway and TTL are written in terms of. It is set
once on workspace.package and inherited by all seven crates.

The msrv CI job reads the version out of the manifest and builds with that
exact toolchain, so the declaration and the check cannot disagree. It builds
rather than tests: the MSRV is a promise about compiling this workspace's code,
and the dev-dependencies carry higher floors of their own that no consumer
inherits. `task msrv` runs the same thing locally.

The manifest is repository content, and on a fork's pull request it is the
contributor's content, so the version is matched against a version shape before
it reaches $GITHUB_OUTPUT.

Closes #13
@rrrodzilla
rrrodzilla merged commit 0fc8d7e into main Jul 31, 2026
11 checks passed
@rrrodzilla
rrrodzilla deleted the chore/13-msrv branch July 31, 2026 21:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Declare rust-version (MSRV) across the workspace and verify it in CI

1 participant