Skip to content

Commit 654a8fa

Browse files
committed
Use gix manifest rust-version in all MSRV checks
This makes the `rust-version` in the manifest file for the `gix` crate the single source of truth for the MSRV. CI checks use this rather than relying on a separate copy of the MSRV. The MSRV badge still hard-codes the MSRV (in four places in its SVG code), but a recipe is added to regenerate it based on the MSRV, and a CI check is added to verify that it agrees with the MSRV. Specifically, the changes are: 1. Add an `msrv` recipe to the `justfile` that extracts the MSRV from the value of `rust-version` in the `gix` package, using `cargo metadata` and `jq`, and that formats it in the X.Y.Z form (since that form is slightly more widely usable than the X.Y form even when Z is 0). 2. Remove the hard-coded MSRV in `msrv.yml` (in `env.RUST_VERSION`) and instead have the `check-msrv` job in `msrv.yml` get it from the `gix` manifest by callig `just msrv`. This fixes the problem that it was possible to forget to update the MSRV in the workflow. 3. Replace the `ci-check-msrv` recipe in the `justfile` with a `check-rust-version` recipe taking a `rust-version` argument. Instead of implicitly using the current default toolchain and relying on that being the MSRV, this explicitly runs its `rustc` and `cargo` commands with the specified `rust-version`. The `check-msrv` CI job now calls this, passing the MSRV. The reason to have a `check-rust-version` recipe instead of a `check-msrv` recipe (or both recipes with the latter delegating to the former) is that CI usage, as well as other anticipated usage, involves performing additional operations between finding out the MSRV and attempting to build with it: - At least on CI, it is clearer to install the needed toolchains before using them, even though specifying them explicitly in `rustc` or `cargo` commands will try to install them. - More importantly, on CI and locally, the `check-rust-version` recipe is not currently expected to work with the MSRV when the committed version of `Cargo.lock` is used, because some locked dependencies may have later MSRVs. Depending on precisely what one is testing, one could temporarily remove `Cargo.lock` and regenerate it using the MSRV toolchain, or (as done on CI) temporarily downgrade the versions in `Cargo.lock`. 4. Add an `msrv-badge` recipe to the `justfile` that regenerates the MSRV badge `etc/msrv-badge.yml` based on the MSRV from the `gix` manifest, as obtained via `just msrv`. This uses a template file, added alongside the badge, where each place where the MSRV should appear has a literal placeholder `{MSRV}` instead. `just msrv-badge` copies the template, with the actual MSRV value subtituted for the placeholders, to the badge, overwriting whatever is there. 5. Add a `check-msrv-badge` job to `msrv.yml` that checks out the code, runs `just msrv-badge`, and checks if there are any changes. If so, the committed badge is out of date. 6. Add an `msrv-pass` job to `msrv.yml` that depends on the `check-msrv` and `check-msrv-badge` jobs. This is analogous to the `tests-pass` job in `ci.yml`. It is so that, if having the MSRV badge out of date should block PR auto-merge, then that can be achieved without `msrv.yml` having to contribute more than one required check to the branch protection rules. (This also temporarily adds a `check-msrv` job for `macos-15`, but that is just to verify that recent `justfile` changes are portable. It will be removed shortly.)
1 parent a8476e1 commit 654a8fa

File tree

5 files changed

+95
-23
lines changed

5 files changed

+95
-23
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ jobs:
487487
sort -m blocking-jobs.txt expected-nonblocking-jobs.txt |
488488
diff --color=always -U1000 - all-jobs.txt
489489
490-
# Dummy job to have a stable name for the "all tests pass" requirement
490+
# Dummy job to have a stable name for the "all tests pass" requirement.
491491
tests-pass:
492492
name: Tests pass
493493

@@ -504,7 +504,7 @@ jobs:
504504
- check-packetline
505505
- check-blocking
506506

507-
if: always() # always run even if dependencies fail
507+
if: always() # Always run even if dependencies fail.
508508

509509
runs-on: ubuntu-latest
510510

.github/workflows/msrv.yml

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,57 @@ jobs:
2525
os:
2626
- windows-2022
2727
- ubuntu-latest
28+
- macos-15 # FIXME(portability): Remove after testing new justfile changes.
2829

2930
runs-on: ${{ matrix.os }}
3031

31-
env:
32-
# This is dictated by `firefox` to support the `helix` editor, but now probably effectively
33-
# be controlled by `jiff`, which also aligns with `regex`.
34-
# IMPORTANT: When adjusting, change all occurrences in `etc/msrv-badge.svg` as well.
35-
RUST_VERSION: 1.75.0
32+
defaults:
33+
run:
34+
shell: bash # Use `bash` even in the Windows job.
3635

3736
steps:
3837
- uses: actions/checkout@v4
3938
- uses: extractions/setup-just@v3
40-
- name: Set up ${{ env.RUST_VERSION }} (MSRV) and nightly toolchains
41-
run: rustup toolchain install ${{ env.RUST_VERSION }} nightly --profile minimal --no-self-update
42-
- name: Set ${{ env.RUST_VERSION }} (MSRV) as default
43-
run: rustup default ${{ env.RUST_VERSION }}
39+
- name: Read the MSRV
40+
run: |
41+
msrv="$(just msrv)"
42+
echo "MSRV=$msrv" >> "$GITHUB_ENV"
43+
- name: Set up MSRV and nightly toolchains
44+
run: |
45+
rustup toolchain install "$MSRV" nightly --profile minimal --no-self-update
4446
- name: Downgrade locked dependencies to lowest allowed versions
4547
run: |
4648
# TODO(msrv): Use `cargo update --minimal-versions` when `--minimal-versions` is available.
4749
cargo +nightly update -Zminimal-versions
4850
- name: Run some `cargo build` commands on `gix`
49-
run: just ci-check-msrv
51+
run: just check-rust-version "$MSRV"
52+
53+
check-msrv-badge:
54+
name: Check MSRV badge
55+
56+
runs-on: ubuntu-latest
57+
58+
steps:
59+
- uses: actions/checkout@v4
60+
- uses: extractions/setup-just@v3
61+
- name: Regenerate the MSRV badge
62+
run: just msrv-badge
63+
- name: Check for changes
64+
run: git diff --exit-code
65+
66+
# Dummy job to have a stable name for the requirement that all MSRV tests pass.
67+
msrv-pass:
68+
name: MSRV checks pass
69+
70+
needs: [ check-msrv, check-msrv-badge ]
71+
72+
if: always() # Always run even if dependencies fail.
73+
74+
runs-on: ubuntu-latest
75+
76+
steps:
77+
- name: Fail if ANY dependency has failed or cancelled
78+
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
79+
run: exit 1
80+
- name: OK
81+
run: exit 0

etc/msrv-badge.template.svg

Lines changed: 21 additions & 0 deletions
Loading

gix/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ version = "0.72.1"
99
authors = ["Sebastian Thiel <sebastian.thiel@icloud.com>"]
1010
edition = "2021"
1111
include = ["src/**/*", "LICENSE-*"]
12+
# This MSRV is dictated by `firefox` to support the `helix` editor, but is now probably
13+
# effectively controlled by `jiff`, which also aligns with `regex`.
1214
rust-version = "1.75"
1315

1416
[lib]

justfile

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,8 @@ unit-tests-flaky:
187187
# Extract cargo metadata, excluding dependencies, and query it
188188
[private]
189189
get-metadata jq-query:
190-
cargo metadata --format-version 1 | jq --exit-status --raw-output -- {{ quote(jq-query) }}
190+
cargo metadata --format-version 1 --no-deps | \
191+
jq --exit-status --raw-output -- {{ quote(jq-query) }}
191192

192193
# Get the path to the directory where debug binaries are created during builds
193194
[private]
@@ -240,16 +241,32 @@ cross-test-android: (cross-test 'armv7-linux-androideabi' '--no-default-features
240241
check-size:
241242
etc/check-package-size.sh
242243

243-
# This assumes the current default toolchain is the Minimal Supported Rust Version and checks
244-
# against it. This is run on CI in `msrv.yml`, after the MSRV toolchain is installed and set as
245-
# default, and after dependencies in `Cargo.lock` are downgraded to the latest MSRV-compatible
246-
# versions. Only if those or similar steps are done first does this work to validate the MSRV.
247-
#
248-
# Check the MSRV, *if* the toolchain is set and `Cargo.lock` is downgraded (used on CI)
249-
ci-check-msrv:
250-
rustc --version
251-
cargo build --locked -p gix
252-
cargo build --locked -p gix --no-default-features --features async-network-client,max-performance
244+
# Report the Minimum Supported Rust Version (the `rust-version` of `gix`) in X.Y.Z form
245+
msrv:
246+
set -eu; \
247+
query='.packages[] | select(.name == "gix") | .rust_version'; \
248+
value="$({{ j }} get-metadata "$query")"; \
249+
case "$value" in \
250+
*.*.*) \
251+
echo "$value" ;; \
252+
*.*) \
253+
echo "$value.0" ;; \
254+
*) \
255+
echo "No '.' in gix rust-version '$value'" >&2; \
256+
exit 1 ;; \
257+
esac
258+
259+
# Regenerate the MSRV badge SVG
260+
msrv-badge:
261+
msrv="$({{ j }} msrv)" && \
262+
sed "s/{MSRV}/$msrv/g" etc/msrv-badge.template.svg >etc/msrv-badge.svg
263+
264+
# Check if `gix` and its dependencies, as currently locked, build with `rust-version`
265+
check-rust-version rust-version:
266+
rustc +{{ rust-version }} --version
267+
cargo +{{ rust-version }} build --locked -p gix
268+
cargo +{{ rust-version }} build --locked -p gix \
269+
--no-default-features --features async-network-client,max-performance
253270

254271
# Enter a nix-shell able to build on macOS
255272
nix-shell-macos:

0 commit comments

Comments
 (0)