Testing crate MSRV in CI

I would like to get advice for the following problems:

  1. Imagine a repository with one crate. Assuming that it provides the rust-version field, how would you test it in with the rust-version toolchain without manually duplicating the version in CI config? Bonus points if it shares CI steps with stable toolchain and other variables in the testing matrix.
  2. A more complex setup: now we have a repository with several crates which have potentially different MSRVs which share the same workspace. How CI job from the previous step should accommodate for this? Remove the workspace Cargo.toml?

Right now in RustCrypto we specify MSRV manually (e.g. see this config) and I would like to find a better alternative.

1 Like

Answer for #1: In my GitHub Actions workflows, I use cargo metadata plus jq to extract the MSRV when testing in "msrv mode", like so:

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os:
          - ubuntu-latest
        toolchain:
          - msrv
          - stable
          - beta
          - nightly
        include:
          - os: macos-latest
            toolchain: stable
          - os: windows-latest
            toolchain: stable
    steps:
      - name: Check out repository
        uses: actions/checkout@v4

      - name: Install Rust
        if: matrix.toolchain != 'msrv'
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: ${{ matrix.toolchain }}

      - name: Determine minimum supported Rust version
        if: matrix.toolchain == 'msrv'
        id: msrv
        run: |
          rust_version="$(cargo metadata --no-deps --format-version=1 | jq -r '.packages[0].rust_version')"
          echo "msrv=$rust_version" >> "$GITHUB_OUTPUT"

      - name: Install minimum supported Rust version
        if: matrix.toolchain == 'msrv'
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: ${{ steps.msrv.outputs.msrv }}

    # Remaining CI steps follow

I'm afraid I don't really have an answer for #2.

3 Likes

I have come to the conclusion that this isn't well supported currently. My recommendation is to use the same MSRV across the board, or to split it into multiple repos.

Especially since the oldest MSRV impacts dependency resolution for the whole workspace (due to dependency unification), meaning that when built in the workspace you might get older versions than you would otherwise have. This makes it hard to test accurately when publishing to crates.io. So it is a deficiency in cargo, not just an issue with CI.

1 Like

Great solution, I was using hardcoding.

I think jq is overkill here, a simple sed works as well (clearurls/.github/workflows/rust.yml at 2a7baff2d580ca1d31d9f93e5909637e176dc2d3 · jendrikw/clearurls · GitHub)

steps:
  - uses: actions/checkout@v4
  - id: setenv
    run: echo "rust_version=$(sed --regexp-extended --quiet 's/rust-version = "(.*)"/\1/p' Cargo.toml)" | tee -a $GITHUB_OUTPUT

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.