Files
uv/.github/workflows/test-system.yml
T
Tomasz Kramkowski cfd048aa7a Change chocolatey system test to ensure uv uses the right python (#17533)
Fix #17524.

This adds a couple of new options to `scripts/check_system_python.py` to verify that it is running with the right interpreter version and that it would hopefully be the interpreter picked up by uv (although that isn't strictly necessary as other tests should fail in that case).

Additionally, since the path to the newly installed chocolatey python is not loaded from registry on every step, we now manually load it.

Beware, this will break `GITHUB_PATH` but this job wasn't using it at the moment.
2026-01-20 16:02:14 +00:00

748 lines
23 KiB
YAML

on:
workflow_call:
inputs:
sha:
description: "The commit SHA to use for artifact names"
required: true
type: string
permissions: {}
jobs:
system-test-debian:
timeout-minutes: 10
name: "python on debian"
runs-on: ubuntu-latest
container: debian:bookworm
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: "Install Python"
run: apt-get update && apt-get install -y python3.11 python3-pip python3.11-venv python3-debian
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-linux-musl-${{ inputs.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Print Python path"
run: echo $(which python3.11)
- name: "Validate global Python install"
run: python3.11 scripts/check_system_python.py --uv ./uv --externally-managed
- name: "Test `uv run` with system Python"
run: |
./uv run -p python3.11 -v python -c "import debian"
./uv run -p python3.11 -v --with anyio python -c "import debian"
system-test-fedora:
timeout-minutes: 10
name: "python on fedora"
runs-on: ubuntu-latest
container: fedora:44@sha256:64de49837325632232088e59c20518565a9d657095f9f3c2fa6033a42fb1412b
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: "Install Python"
run: dnf install python3 which -y && python3 -m ensurepip
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-linux-libc-${{ inputs.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Print Python path"
run: echo $(which python3)
- name: "Validate global Python install"
run: python3 scripts/check_system_python.py --uv ./uv
system-test-ubuntu:
timeout-minutes: 10
name: "python3.12 via setup-python"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.12"
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-linux-libc-${{ inputs.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Print Python path"
run: echo $(which python)
- name: "Validate global Python install"
run: python scripts/check_system_python.py --uv ./uv
# Currently failing, see https://github.com/astral-sh/uv/issues/13811
# system-test-opensuse:
# timeout-minutes: 5
# name: "python on opensuse"
# runs-on: ubuntu-latest
# container: opensuse/tumbleweed
# steps:
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# - name: "Install Python"
# run: >
# until
# zypper install -y python310 which && python3.10 -m ensurepip && mv /usr/bin/python3.10 /usr/bin/python3;
# do sleep 10;
# done
# # We retry because `zypper` can fail during remote repository updates
# # The above will not sleep forever due to the job level timeout
# - name: "Download binary"
# uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
# with:
# name: uv-linux-libc-${{ inputs.sha }}
# - name: "Prepare binary"
# run: chmod +x ./uv
# - name: "Print Python path"
# run: echo $(which python3)
# - name: "Validate global Python install"
# run: python3 scripts/check_system_python.py --uv ./uv
# Note: rockylinux is a 1-1 code compatible distro to rhel
# rockylinux mimics centos but with added maintenance stability
# and avoids issues with centos stream uptime concerns
system-test-rocky-linux:
timeout-minutes: 10
name: "python on rocky linux ${{ matrix.rocky-version }}"
runs-on: ubuntu-latest
container: rockylinux/rockylinux:${{ matrix.rocky-version }}
strategy:
fail-fast: false
matrix:
rocky-version: ["8", "9", "10"]
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: "Install Python"
if: matrix.rocky-version == '8'
run: |
for i in {1..5}; do
dnf install python39 python39-pip which -y && break || { echo "Attempt $i failed, retrying in 10 seconds..."; sleep 10; }
if [ $i -eq 5 ]; then
echo "Failed to install Python after 5 attempts"
exit 1
fi
done
- name: "Install Python"
if: matrix.rocky-version == '9'
run: |
for i in {1..5}; do
dnf install python3.9 python3.9-pip which -y && break || { echo "Attempt $i failed, retrying in 10 seconds..."; sleep 10; }
if [ $i -eq 5 ]; then
echo "Failed to install Python after 5 attempts"
exit 1
fi
done
- name: "Install Python"
if: matrix.rocky-version == '10'
run: |
dnf install python3 python3-pip which -y
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-linux-musl-${{ inputs.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Print Python path"
run: echo $(which python3)
# Needed for building Pydantic
- name: "Install build tools"
run: dnf install -y gcc
- name: "Validate global Python install"
run: python3 scripts/check_system_python.py --uv ./uv
system-test-graalpy:
timeout-minutes: 10
name: "graalpy on linux"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "graalpy24.1"
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-linux-libc-${{ inputs.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Print Python path"
run: echo $(which graalpy)
- name: "Validate global Python install"
run: graalpy scripts/check_system_python.py --uv ./uv
system-test-pypy:
timeout-minutes: 10
name: "pypy on linux"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "pypy3.9"
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-linux-libc-${{ inputs.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Print Python path"
run: echo $(which pypy)
- name: "Validate global Python install"
run: pypy scripts/check_system_python.py --uv ./uv
system-test-pyston:
timeout-minutes: 10
name: "pyston on linux"
runs-on: ubuntu-latest
container: pyston/pyston:2.3.5
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-linux-musl-${{ inputs.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Print Python path"
run: echo $(which pyston)
- name: "Validate global Python install"
run: pyston scripts/check_system_python.py --uv ./uv
system-test-alpine:
timeout-minutes: 10
name: "python on alpine"
runs-on: ubuntu-latest
container: alpine:latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: "Install Python"
run: apk add --update --no-cache python3 py3-pip
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-linux-musl-${{ inputs.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Print Python path"
run: echo $(which python3)
- name: "Validate global Python install"
run: python3 scripts/check_system_python.py --uv ./uv --externally-managed
system-test-macos-aarch64:
timeout-minutes: 10
name: "python on macos aarch64"
runs-on: macos-14 # github-macos-14-aarch64-3
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-macos-aarch64-${{ inputs.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Print Python path"
run: echo $(which python3)
- name: "Validate global Python install"
run: python3 scripts/check_system_python.py --uv ./uv --externally-managed
system-test-macos-aarch64-homebrew:
timeout-minutes: 10
name: "homebrew python on macos aarch64"
runs-on: macos-14 # github-macos-14-aarch64-3
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: "Install Python"
run: brew install python3
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-macos-aarch64-${{ inputs.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Print Python path"
run: echo $(which python3)
- name: "Validate global Python install"
run: python3 scripts/check_system_python.py --uv ./uv --externally-managed
system-test-macos-aarch64-emulated:
timeout-minutes: 10
name: "x86-64 python on macos aarch64"
runs-on: macos-14 # github-macos-14-aarch64-3
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: 3.13
architecture: x64
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-macos-aarch64-${{ inputs.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Print Python path"
run: echo $(which python3)
- name: "Validate global Python install"
run: python3 scripts/check_system_python.py --uv ./uv --externally-managed
system-test-macos-x86_64:
timeout-minutes: 10
name: "python on macos x86-64"
runs-on: macos-15-intel # github-macos-15-x86_64-4
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
# We test with GitHub's Python as a regression test for
# https://github.com/astral-sh/uv/issues/2450
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-macos-x86_64-${{ inputs.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Print Python path"
run: echo $(which python3)
- name: "Validate global Python install"
run: python3 scripts/check_system_python.py --uv ./uv --externally-managed
system-test-windows-python-310:
timeout-minutes: 10
name: "python3.10 on windows x86-64"
runs-on: windows-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.10"
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-windows-x86_64-${{ inputs.sha }}
- name: "Print Python path"
run: echo $(which python)
- name: "Validate global Python install"
run: py -3.10 ./scripts/check_system_python.py --uv ./uv.exe
system-test-windows-x86_64-python-310:
timeout-minutes: 10
name: "python3.10 on windows x86"
runs-on: windows-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.10"
architecture: "x86"
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-windows-x86_64-${{ inputs.sha }}
- name: "Print Python path"
run: echo $(which python)
- name: "Validate global Python install"
run: python ./scripts/check_system_python.py --uv ./uv.exe
system-test-windows-x86_64-python-313:
timeout-minutes: 10
name: "python3.13 on windows x86-64"
runs-on: windows-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.13"
allow-prereleases: true
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-windows-x86_64-${{ inputs.sha }}
- name: "Print Python path"
run: echo $(which python)
- name: "Validate global Python install"
run: py -3.13 ./scripts/check_system_python.py --uv ./uv.exe
system-test-windows-aarch64-x86-python-313:
timeout-minutes: 10
name: "x86-64 python3.13 on windows aarch64"
runs-on: windows-11-arm
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.13"
architecture: "x64"
allow-prereleases: true
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-windows-aarch64-${{ inputs.sha }}
- name: "Validate global Python install"
run: py -3.13 ./scripts/check_system_python.py --uv ./uv.exe
system-test-windows-aarch64-aarch64-python-313:
timeout-minutes: 10
name: "aarch64 python3.13 on windows aarch64"
runs-on: windows-11-arm
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.13"
architecture: "arm64"
allow-prereleases: true
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-windows-aarch64-${{ inputs.sha }}
- name: "Validate global Python install"
run: py -3.13-arm64 ./scripts/check_system_python.py --uv ./uv.exe
system-test-choco:
timeout-minutes: 10
name: "python3.9 via chocolatey"
runs-on: windows-latest
env:
TEST_PYTHON_VERSION: "3.9.13"
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: "Install Python"
run: choco install python3 --verbose --version=$env:TEST_PYTHON_VERSION
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-windows-x86_64-${{ inputs.sha }}
# Chocolatey updates the registry but doesn't update `GITHUB_PATH` and since figuring out what
# it added would be more work than it's worth, it's simpler to just reload the values from the
# registry.
- name: "Validate global Python install"
run: |
$env:PATH = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
python ./scripts/check_system_python.py --uv ./uv.exe --check-python-version $env:TEST_PYTHON_VERSION --check-path
system-test-pyenv:
timeout-minutes: 10
name: "python3.9 via pyenv"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: "Install pyenv"
run: |
# Install pyenv
curl https://pyenv.run | bash
# Set up environment variables for current step
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
# Install Python 3.9
pyenv install 3.9
pyenv global 3.9
# Make environment variables persist across steps
echo "PYENV_ROOT=$HOME/.pyenv" >> $GITHUB_ENV
echo "$HOME/.pyenv/bin" >> $GITHUB_PATH
echo "$HOME/.pyenv/shims" >> $GITHUB_PATH
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-linux-libc-${{ inputs.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Print Python path"
run: echo $(which python3.9)
- name: "Validate global Python install"
run: python3.9 scripts/check_system_python.py --uv ./uv
system-test-linux-313:
timeout-minutes: 10
name: "python3.13 via setup-python"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: 3.13
allow-prereleases: true
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-linux-libc-${{ inputs.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Print Python path"
run: echo $(which python3.13)
- name: "Validate global Python install"
run: python3.13 scripts/check_system_python.py --uv ./uv
system-test-conda:
timeout-minutes: 10
name: "conda${{ matrix.python-version }} on ${{ matrix.os }} ${{ matrix.arch }}"
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
os: ["linux", "windows", "macos"]
python-version: ["3.8", "3.11"]
include:
- {
os: "linux",
target: "linux-libc",
runner: "ubuntu-latest",
arch: "x86-64",
}
- {
os: "windows",
target: "windows-x86_64",
runner: "windows-latest",
arch: "x86-64",
}
- {
os: "macos",
target: "macos-aarch64",
runner: "macos-14",
arch: "aarch64",
}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- uses: conda-incubator/setup-miniconda@835234971496cad1653abb28a638a281cf32541f # v3.2.0
with:
miniconda-version: "latest"
activate-environment: uv
python-version: ${{ matrix.python-version }}
- name: Conda info
shell: bash -el {0}
run: conda info
- name: Conda list
shell: pwsh
run: conda list
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-${{ matrix.target }}-${{ inputs.sha }}
- name: "Prepare binary"
if: ${{ matrix.os != 'windows' }}
run: chmod +x ./uv
- name: "Print Python path"
shell: bash -el {0}
run: echo $(which python)
- name: "Validate global Python install"
shell: bash -el {0}
run: python ./scripts/check_system_python.py --uv ./uv
system-test-amazonlinux:
timeout-minutes: 10
name: "python on amazonlinux"
runs-on: ubuntu-latest
container: amazonlinux:2023
steps:
- name: "Install base requirements"
run: |
# Needed for `actions/checkout`
yum install tar gzip which -y
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: "Install Python"
run: yum install python3 python3-pip -y
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-linux-musl-${{ inputs.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Print Python path"
run: echo $(which python3)
- name: Install build tools
run: yum install -y gcc
- name: "Validate global Python install"
run: python3 scripts/check_system_python.py --uv ./uv
system-test-windows-embedded-python-310:
timeout-minutes: 10
name: "embedded python3.10 on windows x86-64"
runs-on: windows-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: "Download binary"
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: uv-windows-x86_64-${{ inputs.sha }}
# Download embedded Python.
- name: "Download embedded Python"
run: curl -LsSf https://www.python.org/ftp/python/3.11.8/python-3.11.8-embed-amd64.zip -o python-3.11.8-embed-amd64.zip
- name: "Unzip embedded Python"
run: 7z x python-3.11.8-embed-amd64.zip -oembedded-python
- name: "Show embedded Python contents"
run: ls embedded-python
- name: "Set PATH"
run: echo "${{ github.workspace }}\embedded-python" >> $env:GITHUB_PATH
- name: "Print Python path"
run: echo $(which python)
- name: "Validate embedded Python install"
run: python ./scripts/check_embedded_python.py --uv ./uv.exe