Skip to content

Add optional uv backend (opt-in via --use-uv / config) #100

Add optional uv backend (opt-in via --use-uv / config)

Add optional uv backend (opt-in via --use-uv / config) #100

Workflow file for this run

name: Integration Tests
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
# Single source of truth: the oldest supported Python is whatever setup.py
# declares in `python_requires`. Every job below derives its cross-version
# target from this output instead of hardcoding a version.
min-python:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.minpy.outputs.version }}
steps:
- uses: actions/checkout@v4
- name: Read minimum supported Python from setup.py
id: minpy
run: |
version=$(grep python_requires setup.py | grep -oE '[0-9]+\.[0-9]+' | head -1)
echo "Minimum supported Python: $version"
echo "version=$version" >> "$GITHUB_OUTPUT"
archlinux:
needs: min-python
runs-on: ubuntu-latest
container:
# archlinux:latest ships the newest CPython (rolling release), so this
# job exercises fades against the bleeding-edge Python. An older
# interpreter for the cross-version test is provided via uv at runtime.
image: archlinux:latest
volumes:
- ${{ github.workspace }}:/fades
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install dependencies
run: |
pacman -Suy --noconfirm python3 python-packaging uv git
- name: Simple fades run (newest Python)
run: |
cd /fades
bin/fades -v -d pytest -x pytest --version
- name: uv backend is auto-detected and used
run: |
cd /fades
# with uv on PATH, fades must pick the uv backend (assert via the verbose log)
bin/fades -v -d six -x python -c "import six" 2>&1 | grep -q "Using uv backend"
- name: pip backend still works with --no-uv
run: |
cd /fades
# fades itself must succeed (so a --no-uv crash can't silently pass the negated grep),
# and the uv-backend log line must be absent
bin/fades -v --no-uv -d six -x python -c "import six" > nouv.log 2>&1
! grep -q "Using uv backend" nouv.log
- name: --freeze works on a uv-built venv (even with --no-uv)
run: |
cd /fades
# the 'six' venv was built by uv above (no pip); freezing it must still produce a
# non-empty pinned file -- fades has to pick the freeze backend from the venv, not the
# --no-uv flag, and must not silence the freeze output
bin/fades -v --no-uv -d six --freeze=frozen.txt -x python -c "import six"
grep -q "^six==" frozen.txt
- name: Using the oldest supported Python
env:
OLDEST: ${{ needs.min-python.outputs.version }}
run: |
cd /fades
uv python install "$OLDEST"
OLD=$(uv python find "$OLDEST")
python bin/fades -v --python="$OLD" -d pytest -x pytest -v --integtest-pyversion="$OLDEST" tests/integtest.py
fedora:
needs: min-python
runs-on: ubuntu-latest
container:
image: fedora:latest
volumes:
- ${{ github.workspace }}:/fades
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install dependencies
run: |
dnf install --assumeyes python3 python3-packaging uv git
- name: Simple fades run
run: |
cd /fades
bin/fades -v -d pytest -x pytest --version
- name: uv backend is auto-detected and used
run: |
cd /fades
# with uv on PATH, fades must pick the uv backend (assert via the verbose log)
bin/fades -v -d six -x python -c "import six" 2>&1 | grep -q "Using uv backend"
- name: pip backend still works with --no-uv
run: |
cd /fades
# fades itself must succeed (so a --no-uv crash can't silently pass the negated grep),
# and the uv-backend log line must be absent
bin/fades -v --no-uv -d six -x python -c "import six" > nouv.log 2>&1
! grep -q "Using uv backend" nouv.log
- name: --freeze works on a uv-built venv (even with --no-uv)
run: |
cd /fades
# the 'six' venv was built by uv above (no pip); freezing it must still produce a
# non-empty pinned file -- fades has to pick the freeze backend from the venv, not the
# --no-uv flag, and must not silence the freeze output
bin/fades -v --no-uv -d six --freeze=frozen.txt -x python -c "import six"
grep -q "^six==" frozen.txt
- name: Using the oldest supported Python
env:
OLDEST: ${{ needs.min-python.outputs.version }}
run: |
cd /fades
uv python install "$OLDEST"
OLD=$(uv python find "$OLDEST")
python3 bin/fades -v --python="$OLD" -d pytest -x pytest -v --integtest-pyversion="$OLDEST" tests/integtest.py
native-windows:
needs: min-python
strategy:
matrix:
# just a selection otherwise it's too much
# - latest OS (left here even if it's only one to simplify upgrading later)
# - oldest (from setup.py) and newest Python
os: [windows-2025]
python-version: ["${{ needs.min-python.outputs.version }}", "3.13"]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
uses: actions/setup-python@v5
id: matrixpy
with:
python-version: ${{ matrix.python-version }}
- name: Also set up the oldest supported Python for cross-Python test
uses: actions/setup-python@v5
id: otherpy
with:
python-version: ${{ needs.min-python.outputs.version }}
- name: Install dependencies
run: |
${{ steps.matrixpy.outputs.python-path }} -m pip install -U packaging
- name: Install uv (on PATH for all following steps)
uses: astral-sh/setup-uv@v6
- name: Simple fades run
run: |
${{ steps.matrixpy.outputs.python-path }} bin/fades -v -d pytest -x pytest --version
- name: uv backend is auto-detected and used (Windows)
shell: bash
run: |
# this exercises the whole uv path on Windows: 'uv venv' + 'uv pip install --python
# <venv>\Scripts\python.exe'. If the python/python.exe resolution were wrong, uv would
# fail to find the interpreter and the install (hence this step) would fail.
which uv && uv --version
# single-quote to keep the backslashes, then turn them into forward slashes so bash
# (Git Bash) doesn't strip them out of the Windows path
PY='${{ steps.matrixpy.outputs.python-path }}'; PY="${PY//\\//}"
"$PY" bin/fades -v -d six -x python -c "import six" > uv.log 2>&1 || { cat uv.log; exit 1; }
cat uv.log
grep -q "Using uv backend" uv.log
- name: pip backend still works with --no-uv (Windows)
shell: bash
run: |
PY='${{ steps.matrixpy.outputs.python-path }}'; PY="${PY//\\//}"
"$PY" bin/fades -v --no-uv -d six -x python -c "import six" > nouv.log 2>&1
! grep -q "Using uv backend" nouv.log
- name: --freeze works on a uv-built venv (Windows)
shell: bash
run: |
PY='${{ steps.matrixpy.outputs.python-path }}'; PY="${PY//\\//}"
"$PY" bin/fades -v --no-uv -d six --freeze=frozen.txt -x python -c "import six" > freeze.log 2>&1 || { cat freeze.log; exit 1; }
cat frozen.txt
grep -q "^six==" frozen.txt
- name: Using a different Python
run: |
${{ steps.matrixpy.outputs.python-path }} bin/fades -v --python=${{ steps.otherpy.outputs.python-path }} -d pytest -x pytest -v --integtest-pyversion=${{ needs.min-python.outputs.version }} tests/integtest.py
native-generic:
needs: min-python
strategy:
matrix:
# just a selection otherwise it's too much
# - latest OSes
# - oldest (from setup.py) and newest Python
os: [ubuntu-24.04, macos-15]
python-version: ["${{ needs.min-python.outputs.version }}", "3.13"]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
uses: actions/setup-python@v5
id: matrixpy
with:
python-version: ${{ matrix.python-version }}
- name: Also set up the oldest supported Python for cross-Python test
uses: actions/setup-python@v5
id: otherpy
with:
python-version: ${{ needs.min-python.outputs.version }}
- name: Install dependencies
run: |
${{ steps.matrixpy.outputs.python-path }} -m pip install -U packaging
- name: Simple fades run
run: |
${{ steps.matrixpy.outputs.python-path }} bin/fades -v -d pytest -x pytest --version
- name: Using a different Python
run: |
${{ steps.matrixpy.outputs.python-path }} bin/fades -v --python=${{ steps.otherpy.outputs.python-path }} -d pytest -x pytest -v --integtest-pyversion=${{ needs.min-python.outputs.version }} tests/integtest.py