Add a separate CI job that resolves the newest versions your manifest allows, builds, runs your tests, and is marked to continue on failure. It warns you about breakage from new dependency releases without stopping contributors from merging unrelated work.
Why a library needs this
Your lockfile tests one combination of dependencies. Your users get whatever your ranges allow on the day they install. The Cargo guide says a manifest requirement matches a range of versions, so testing every combination is impractical, and recommends testing the latest versions to catch problems for users who run cargo add or cargo install.
The same idea applies to any ecosystem. If a dependency ships a breaking change inside your allowed range, you want to hear about it from CI, not from an issue titled "broken since Tuesday".
The job, step by step
The Cargo documentation describes four steps:
- Update dependencies to the latest compatible versions. In Cargo that is
cargo update, which rewritesCargo.lock. - Build and test the updated set.
- Run it in a job marked as continue on failure, so it does not block the main pipeline.
- Set
CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS=allowso the resolver does not hold packages back because of your declared minimum toolchain version.
Here is the example from the Cargo guide:
jobs:
latest_deps:
name: Latest Dependencies
runs-on: ubuntu-latest
continue-on-error: true
env:
CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS: allow
steps:
- uses: actions/checkout@v6
- run: rustup update stable && rustup default stable
- run: cargo update --verbose
- run: cargo build --verbose
- run: cargo test --verbose
For npm or Python, the shape is the same: install without the lockfile or constraints file, then run the tests.
Options and trade-offs
The Cargo guide lists alternatives:
| Approach | Upside | Downside |
|---|---|---|
| Do not commit the lockfile | Always newest versions | Many versions untested, builds not repeatable |
| Scheduled CI job | Catches drift between pull requests | Hosted services may disable scheduled jobs on inactive repositories, and failure notices may not reach the right person |
| Update bot pull requests | Isolated or grouped, scheduled to balance CI cost | Needs someone to read them |
The guide also notes that projects at higher risk of failures on specific platforms or toolchain versions may need to test more combinations.
Making failures visible
A job that is allowed to fail is easy to ignore. Pick one way to surface it:
- Run it on pull requests and read the yellow mark when you review.
- Run it weekly and have it open an issue on failure.
- Add a badge to the contributing guide so regulars know to look.
Decide in advance who reads the result. On a volunteer project, name the person in the workflow file comment.
What this has to do with security
When a dependency fixes a vulnerability, the fix arrives in a new release. If your latest-versions job fails on that release, you have a choice between a breaking fix and a known flaw, and you learn about it early. That is much better than discovering it during an emergency.
Quick check
Should this job block merges?
No. It tests unreleased combinations, so failures may come from a dependency, not from the pull request. Mark it to continue on failure.
Does the job replace advisory scanning?
No. It finds breakage, not vulnerabilities. Keep an audit or scanner running as well.
Safeguard monitors dependencies for new advisories after merge and can open fix pull requests, which are off by default with every category on Manual. You can try the free scan.
Sources
- Cargo Book, continuous integration: https://doc.rust-lang.org/cargo/guide/continuous-integration.html
Last reviewed: 19 October 2026.