Recommended CI¶
A floor is only honest if you test it. Recommended resolutions to run in CI:
- Minimum versions:
uv sync --upgrade --resolution lowest-directthen run tests — every direct dependency is installed at exactly its lower bound, proving the floors actually work. - Latest versions:
uv sync --upgrade— proves you're compatible with current releases. - Locked (your day-to-day resolution):
uv sync --frozen.
Example matrix¶
strategy:
matrix:
python-version: ['3.12', '3.13', '3.14']
os: [ubuntu-latest]
resolution: [locked, lowest-direct, highest]
include:
- os: macos-latest
python-version: '3.14'
resolution: highest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
env:
RESOLUTION: ${{ matrix.resolution }}
run: |
case "$RESOLUTION" in
locked) uv sync --group dev --frozen ;;
lowest-direct) uv sync --group dev --upgrade --resolution lowest-direct ;;
highest) uv sync --group dev --upgrade ;;
esac
- name: Run tests
run: uv run --no-sync pytest
Notes:
--upgradeforces re-resolution instead of reusinguv.lock; the re-lock happens only in the runner's ephemeral checkout.uv run --no-syncstops the test step from silently syncing back to the lockfile resolution.--resolution lowest-directalso floors your dev dependency group — a feature: it validates those floors too.- Resolution behaviour is OS-independent, so running
lowest-directon a single OS is usually enough (this repository runs it on ubuntu only).