Add optional uv backend (opt-in via --use-uv / config) #100
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |