Skip to content

General testing strategy of crates in CI #28

@newpavlov

Description

@newpavlov

Most of our repositories contain multiple crates which are part of the same workspace. We also have a number of inter-repository dependencies (e.g. digest depends on crypto-common). In such cases instead of using path while specifying dependency in the crate's Cargo.toml we use dependency patching (e.g. see here).

Currently we commit workspace's Cargo.lock and update it periodically using Dependabot. It allows us to isolate CI failures caused by upstream dependencies. It also reduces CI times a bit since we don't need to generate lock files from scratch. We use the same Cargo.lock for both MSRV and stable tests. MSRV tests use versions manually provided in the CI config.

Additionally, we have minimal-versions jobs which test crates separately from the repository workspace using unstable -Z minimal-versions option. Unfortunately, testing it outside of workspace means that dependency patching defined on the workspace level does not works and we have to manually disable such jobs while patching is present.

In the new releases we plan to rely on the MSRV-aware resolver meaning that we can update MSRV in patch releases, which can lead to mixed-MSRV workspaces. Considering how the MSRV-aware resolver works by default (it selects dependency versions compatible with the declared MSRV), it may be problematic.

Imagine a repo with crates A and B with MSRV equal to 1.85, now in a new version of A we want to use dependency C with MSRV 1.90. We bump MSRV of crate A accordingly, but now we have a problem: the resolver is unable to generate Cargo.lock compatible with MSRV of crate B.

Going forward, I think we should test at least 3 scenarios for all crates:

  1. Stable toolchain with latest semver-compatible dependencies (i.e. generated with cargo update --ignore-rust-version)
  2. MSRV toolchain acquired from the rust-version field with latest MSRV-compatible dependencies
  3. Nightly toolchain with minimal semver-compatible version (i.e. generated with -Z minimal-versions)

This list would require the following changes:

  • If we want to continue committing Cargo.lock we should add .cargo/config.toml to every repository with incompatible-rust-versions = "allow" to satisfy 1.
  • To satisfy 2 we would need to add extraction of the rust-version value (see this URLO thread) and to exclude the crate from the repo workspace.

Unresolved questions:

  • Should we continue to commit Cargo.lock? I don't remember many cases of upstream dependencies breaking CI, so it may not be important. We could replace it with a cron job which would test freshest upstream dependencies periodically.
  • Should we test on Nightly and/or Beta with latest semver-compatible dependencies?
  • Should we use MSRV toolchain to run tests minimal-versions jobs (i.e. use Nightly to generate lock file and switch to MSRV toolchain for cargo test)?
  • How to deal with patch issues in 2 and 3?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions