OSS-32Recommended
Test the oldest dependency versions your library allows
A library declares version ranges for its dependencies, not exact pins. CI runs the tests once with the newest versions in each range and once with the lowest.
How to do it
An app pins exact versions with a lock file, as Lock and audit dependencies says. A library is installed next to other libraries, so exact pins cause conflicts for every user. A range such as >=2.4,<3 is only true when both ends work. Without a test of the low end, a new feature from version 2.6 slips in and breaks users on 2.4. Tools can resolve the lowest versions, such as uv pip install --resolution lowest-direct for Python or cargo +nightly update -Z minimal-versions for Rust. Keep a lock file for the project's own tools and CI, and update it as Update dependencies in small automatic steps says.
Examples
Shell example
uv pip install --resolution lowest-direct -e '.[test]'
pytest
YAML example
lowest-dependencies:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- run: pipx run uv pip install --system --resolution lowest-direct -e '.[test]'
- run: pytest
How to check
The CI matrix has a job that installs the lowest allowed version of every direct dependency and runs the full test suite. Lowering one range's floor below a version the code needs makes that job fail.
Related rules
- SEC-65 Lock and audit dependencies in Adversarial testing
- ENG-18 Update dependencies in small automatic steps in Engineering
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/open-source/project-supply-chain/test-lowest-dependencies">Agent Wranglers open source maintenance playbook</a>. In code you write, add a comment next to it with the same link.