Skip to content

Add the differences between pip install and uv pip install installation directories in the pip compatibility document. #18914

Add the differences between pip install and uv pip install installation directories in the pip compatibility document.

Add the differences between pip install and uv pip install installation directories in the pip compatibility document. #18914

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
env:
CARGO_INCREMENTAL: 0
CARGO_NET_RETRY: 10
CARGO_TERM_COLOR: always
RUSTUP_MAX_RETRIES: 10
PYTHON_VERSION: "3.12"
jobs:
determine_changes:
name: "Determine changes"
runs-on: ubuntu-latest
outputs:
# Flag that is raised when any code is changed
code: ${{ steps.changed.outputs.code_any_changed }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: tj-actions/changed-files@v45
id: changed
with:
files_yaml: |
code:
- "**/*"
- "!docs/**/*"
- "!mkdocs.*.yml"
- "!**/*.md"
- "!bin/**"
- "!assets/**"
# Generated markdown and JSON files are checked during test runs
- "docs/reference/cli.md"
- "docs/reference/settings.md"
- "docs/configuration/environment.md"
- "uv.schema.json"
lint:
timeout-minutes: 10
name: "lint"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: 3.12
- name: "Install Rustfmt"
run: rustup component add rustfmt
- name: "Install uv"
uses: astral-sh/setup-uv@v3
- name: "rustfmt"
run: cargo fmt --all --check
- name: "Prettier"
run: |
npx prettier --check "**/*.{json5,yaml,yml}"
npx prettier --prose-wrap always --check "**/*.md"
- name: "README check"
run: python scripts/transform_readme.py --target pypi
- name: "Python format"
run: uvx ruff format --diff .
- name: "Python lint"
run: uvx ruff check .
- name: "Python type check"
run: uvx mypy
- name: "Validate project metadata"
run: uvx --from 'validate-pyproject[all,store]' validate-pyproject pyproject.toml
- name: "Lint shell scripts"
uses: ludeeus/[email protected]
env:
# renovate: datasource=github-tags depName=koalaman/shellcheck
SHELLCHECK_VERSION: "v0.10.0"
SHELLCHECK_OPTS: --shell bash
with:
version: ${{ env.SHELLCHECK_VERSION }}
severity: style
check_together: "yes"
cargo-clippy:
timeout-minutes: 10
needs: determine_changes
if: ${{ github.repository == 'astral-sh/uv' && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
runs-on: ubuntu-latest
name: "cargo clippy | ubuntu"
steps:
- uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: "Install Rust toolchain"
run: rustup component add clippy
- name: "Clippy"
run: cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
cargo-clippy-windows:
timeout-minutes: 15
needs: determine_changes
if: ${{ github.repository == 'astral-sh/uv' && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
runs-on:
labels: "windows-latest-xlarge"
name: "cargo clippy | windows"
steps:
- uses: actions/checkout@v4
- name: Create Dev Drive using ReFS
run: ${{ github.workspace }}/.github/workflows/setup-dev-drive.ps1
# actions/checkout does not let us clone into anywhere outside ${{ github.workspace }}, so we have to copy the clone...
- name: Copy Git Repo to Dev Drive
run: |
Copy-Item -Path "${{ github.workspace }}" -Destination "${{ env.UV_WORKSPACE }}" -Recurse
- uses: Swatinem/rust-cache@v2
with:
workspaces: ${{ env.UV_WORKSPACE }}
- name: "Install Rust toolchain"
run: rustup component add clippy
- name: "Clippy"
run: cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
cargo-dev-generate-all:
timeout-minutes: 10
needs: determine_changes
if: ${{ github.repository == 'astral-sh/uv' && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
runs-on: ubuntu-latest
name: "cargo dev generate-all"
steps:
- uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: "Generate all"
run: cargo dev generate-all --mode check
cargo-shear:
timeout-minutes: 10
name: "cargo shear"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cargo-bins/cargo-binstall@main
- run: cargo binstall --no-confirm cargo-shear
- run: cargo shear
# We use the large GitHub actions runners
# For Ubuntu and Windows, this requires Organization-level configuration
# See: https://docs.github.com/en/actions/using-github-hosted-runners/about-larger-runners/about-larger-runners#about-ubuntu-and-windows-larger-runners
cargo-test-linux:
timeout-minutes: 10
needs: determine_changes
if: ${{ github.repository == 'astral-sh/uv' && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
runs-on:
labels: "depot-ubuntu-22.04-16"
name: "cargo test | ubuntu"
steps:
- uses: actions/checkout@v4
- uses: rui314/setup-mold@v1
- uses: Swatinem/rust-cache@v2
- name: "Install Rust toolchain"
run: rustup show
- uses: astral-sh/setup-uv@v3
- name: "Install required Python versions"
run: uv python install
- name: "Install cargo nextest"
uses: taiki-e/install-action@v2
with:
tool: cargo-nextest
- name: "Cargo test"
run: |
cargo nextest run \
--features python-patch \
--workspace \
--status-level skip --failure-output immediate-final --no-fail-fast -j 20 --final-status-level slow
- name: "Smoke test"
run: |
uv="./target/debug/uv"
$uv venv -v
$uv pip install ruff -v
- name: "Smoke test completion"
run: |
uv="./target/debug/uv"
uvx="./target/debug/uvx"
eval "$($uv generate-shell-completion bash)"
eval "$($uvx --generate-shell-completion bash)"
cargo-test-macos:
timeout-minutes: 10
needs: determine_changes
if: ${{ github.repository == 'astral-sh/uv' && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
runs-on:
labels: "depot-macos-latest"
name: "cargo test | macos"
steps:
- uses: actions/checkout@v4
- uses: rui314/setup-mold@v1
- uses: Swatinem/rust-cache@v2
- name: "Install Rust toolchain"
run: rustup show
- uses: astral-sh/setup-uv@v3
- name: "Install required Python versions"
run: uv python install
- name: "Install cargo nextest"
uses: taiki-e/install-action@v2
with:
tool: cargo-nextest
- name: "Cargo test"
run: |
cargo nextest run \
--features python-patch \
--workspace \
--status-level skip --failure-output immediate-final --no-fail-fast -j 12 --final-status-level slow
- name: "Smoke test"
run: |
uv="./target/debug/uv"
$uv venv -v
$uv pip install ruff -v
cargo-test-windows:
timeout-minutes: 15
needs: determine_changes
if: ${{ github.repository == 'astral-sh/uv' && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
runs-on:
labels: "windows-latest-xlarge"
name: "cargo test | windows"
steps:
- uses: actions/checkout@v4
- name: Create Dev Drive using ReFS
run: ${{ github.workspace }}/.github/workflows/setup-dev-drive.ps1
# actions/checkout does not let us clone into anywhere outside ${{ github.workspace }}, so we have to copy the clone...
- name: Copy Git Repo to Dev Drive
run: |
Copy-Item -Path "${{ github.workspace }}" -Destination "${{ env.UV_WORKSPACE }}" -Recurse
# We do not test with Python patch versions on Windows
# so we can use `setup-python` instead of our bootstrapping code
# this is much faster on the extremely slow GitHub Windows runners.
- uses: actions/setup-python@v5
with:
python-version: |
3.8
3.9
3.10
3.11
3.12
3.13
- uses: Swatinem/rust-cache@v2
with:
workspaces: ${{ env.UV_WORKSPACE }}
- name: "Install Rust toolchain"
working-directory: ${{ env.UV_WORKSPACE }}
run: rustup show
- name: "Install cargo nextest"
uses: taiki-e/install-action@v2
with:
tool: cargo-nextest
- name: "Cargo test"
working-directory: ${{ env.UV_WORKSPACE }}
env:
# Avoid permission errors during concurrent tests
# See https://github.com/astral-sh/uv/issues/6940
UV_LINK_MODE: copy
run: |
cargo nextest run --no-default-features --features python,pypi,python-managed --workspace --status-level skip --failure-output immediate-final --no-fail-fast -j 20 --final-status-level slow
- name: "Smoke test"
working-directory: ${{ env.UV_WORKSPACE }}
env:
# Avoid debug build stack overflows.
UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows
run: |
Set-Alias -Name uv -Value ./target/debug/uv
uv venv -v
uv pip install ruff -v
- name: "Smoke test completion"
working-directory: ${{ env.UV_WORKSPACE }}
shell: powershell
env:
# Avoid debug build stack overflows.
UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows
run: |
Set-Alias -Name uv -Value ./target/debug/uv
Set-Alias -Name uvx -Value ./target/debug/uvx
(& uv generate-shell-completion powershell) | Out-String | Invoke-Expression
(& uvx --generate-shell-completion powershell) | Out-String | Invoke-Expression
# Separate jobs for the nightly crate
windows-trampoline-check:
timeout-minutes: 15
needs: determine_changes
if: ${{ github.repository == 'astral-sh/uv' && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
runs-on: windows-latest-xlarge
name: "check windows trampoline | ${{ matrix.target-arch }}"
strategy:
fail-fast: false
matrix:
target-arch: ["x86_64", "i686", "aarch64"]
steps:
- uses: actions/checkout@v4
- name: Create Dev Drive using ReFS
run: ${{ github.workspace }}/.github/workflows/setup-dev-drive.ps1
# actions/checkout does not let us clone into anywhere outside ${{ github.workspace }}, so we have to copy the clone...
- name: Copy Git Repo to Dev Drive
run: |
Copy-Item -Path "${{ github.workspace }}" -Destination "${{ env.UV_WORKSPACE }}" -Recurse
- uses: Swatinem/rust-cache@v2
with:
workspaces: ${{ env.UV_WORKSPACE }}/crates/uv-trampoline
- name: "Install Rust toolchain"
working-directory: ${{ env.UV_WORKSPACE }}/crates/uv-trampoline
run: |
rustup target add ${{ matrix.target-arch }}-pc-windows-msvc
rustup component add rust-src --target ${{ matrix.target-arch }}-pc-windows-msvc
- name: "Install cargo-bloat"
uses: taiki-e/install-action@v2
with:
tool: cargo-bloat
- name: "Clippy"
working-directory: ${{ env.UV_WORKSPACE }}/crates/uv-trampoline
run: cargo clippy --all-features --locked --target x86_64-pc-windows-msvc --tests -- -D warnings
- name: "Bloat Check"
working-directory: ${{ env.UV_WORKSPACE }}/crates/uv-trampoline
run: |
$output = cargo bloat --release --target x86_64-pc-windows-msvc
$filteredOutput = $output | Select-String -Pattern 'core::fmt::write|core::fmt::getcount' -NotMatch
$containsPatterns = $filteredOutput | Select-String -Pattern 'core::fmt|std::panicking|std::backtrace_rs'
if ($containsPatterns) {
Exit 1
} else {
Exit 0
}
# Separate jobs for the nightly crate
windows-trampoline-test:
timeout-minutes: 10
needs: determine_changes
if: ${{ github.repository == 'astral-sh/uv' && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
runs-on: windows-latest
name: "test windows trampoline | ${{ matrix.target-arch }}"
strategy:
fail-fast: false
matrix:
# Note, we exclude `aarch64` because it's not supported by the GitHub runner
target-arch: ["x86_64", "i686"]
steps:
- uses: actions/checkout@v4
- name: "Install Rust toolchain"
working-directory: ${{ github.workspace }}/crates/uv-trampoline
run: |
rustup target add ${{ matrix.target-arch }}-pc-windows-msvc
rustup component add rust-src --target ${{ matrix.target-arch }}-pc-windows-msvc
- uses: Swatinem/rust-cache@v2
with:
workspaces: ${{ github.workspace }}/crates/uv-trampoline
- name: "Test committed binaries"
working-directory: ${{ github.workspace }}
run: |
rustup target add ${{ matrix.target-arch }}-pc-windows-msvc
cargo test -p uv-trampoline-builder --target ${{ matrix.target-arch }}-pc-windows-msvc
# Build and copy the new binaries
- name: "Build"
working-directory: ${{ github.workspace }}/crates/uv-trampoline
run: |
cargo build --target ${{ matrix.target-arch }}-pc-windows-msvc
cp target/${{ matrix.target-arch }}-pc-windows-msvc/debug/uv-trampoline-console.exe trampolines/uv-trampoline-${{ matrix.target-arch }}-console.exe
cp target/${{ matrix.target-arch }}-pc-windows-msvc/debug/uv-trampoline-gui.exe trampolines/uv-trampoline-${{ matrix.target-arch }}-gui.exe
- name: "Test new binaries"
working-directory: ${{ github.workspace }}
run: |
# We turn off the default "production" test feature since these are debug binaries
cargo test -p uv-trampoline-builder --target ${{ matrix.target-arch }}-pc-windows-msvc --no-default-features
typos:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: crate-ci/typos@master
docs:
timeout-minutes: 10
name: "mkdocs"
runs-on: ubuntu-latest
env:
MKDOCS_INSIDERS_SSH_KEY_EXISTS: ${{ secrets.MKDOCS_INSIDERS_SSH_KEY != '' }}
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v3
- uses: actions/setup-python@v5
- name: "Add SSH key"
if: ${{ env.MKDOCS_INSIDERS_SSH_KEY_EXISTS == 'true' }}
uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.MKDOCS_INSIDERS_SSH_KEY }}
- name: "Build docs (public)"
run: uvx --with-requirements docs/requirements.txt mkdocs build --strict -f mkdocs.public.yml
- name: "Build docs (insiders)"
if: ${{ env.MKDOCS_INSIDERS_SSH_KEY_EXISTS == 'true' }}
run: uvx --with-requirements docs/requirements.txt mkdocs build --strict -f mkdocs.insiders.yml
build-binary-linux:
timeout-minutes: 10
needs: determine_changes
if: ${{ github.repository == 'astral-sh/uv' && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
runs-on:
labels: ubuntu-latest-large
name: "build binary | linux"
steps:
- uses: actions/checkout@v4
- uses: rui314/setup-mold@v1
- name: "Setup musl"
run: |
sudo apt-get install musl-tools
rustup target add x86_64-unknown-linux-musl
- uses: Swatinem/rust-cache@v2
- name: "Build"
run: cargo build --target x86_64-unknown-linux-musl
- name: "Upload binary"
uses: actions/upload-artifact@v4
with:
name: uv-linux-${{ github.sha }}
path: ./target/x86_64-unknown-linux-musl/debug/uv
retention-days: 1
build-binary-macos-aarch64:
timeout-minutes: 10
needs: determine_changes
if: ${{ github.repository == 'astral-sh/uv' && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
runs-on:
labels: macos-14
name: "build binary | macos aarch64"
steps:
- uses: actions/checkout@v4
- uses: rui314/setup-mold@v1
- uses: Swatinem/rust-cache@v2
- name: "Build"
run: cargo build
- name: "Upload binary"
uses: actions/upload-artifact@v4
with:
name: uv-macos-aarch64-${{ github.sha }}
path: ./target/debug/uv
retention-days: 1
build-binary-macos-x86_64:
timeout-minutes: 10
needs: determine_changes
if: ${{ github.repository == 'astral-sh/uv' && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
runs-on:
labels: macos-latest-large # Intel runner on GitHub
name: "build binary | macos x86_64"
steps:
- uses: actions/checkout@v4
- uses: rui314/setup-mold@v1
- uses: Swatinem/rust-cache@v2
- name: "Build"
run: cargo build
- name: "Upload binary"
uses: actions/upload-artifact@v4
with:
name: uv-macos-x86_64-${{ github.sha }}
path: ./target/debug/uv
retention-days: 1
build-binary-windows:
needs: determine_changes
timeout-minutes: 10
if: ${{ github.repository == 'astral-sh/uv' && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
runs-on:
labels: windows-latest-large
name: "build binary | windows"
steps:
- uses: actions/checkout@v4
- name: Create Dev Drive using ReFS
run: ${{ github.workspace }}/.github/workflows/setup-dev-drive.ps1
# actions/checkout does not let us clone into anywhere outside ${{ github.workspace }}, so we have to copy the clone...
- name: Copy Git Repo to Dev Drive
run: |
Copy-Item -Path "${{ github.workspace }}" -Destination "${{ env.UV_WORKSPACE }}" -Recurse
- uses: Swatinem/rust-cache@v2
with:
workspaces: ${{ env.UV_WORKSPACE }}
- name: "Build"
working-directory: ${{ env.UV_WORKSPACE }}
run: cargo build
- name: "Upload binary"
uses: actions/upload-artifact@v4
with:
name: uv-windows-${{ github.sha }}
path: ${{ env.UV_WORKSPACE }}/target/debug/uv.exe
retention-days: 1
cargo-build-msrv:
name: "cargo build (msrv)"
needs: determine_changes
if: ${{ github.repository == 'astral-sh/uv' && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
runs-on:
labels: ubuntu-latest-large
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: SebRollen/[email protected]
id: msrv
with:
file: "Cargo.toml"
field: "workspace.package.rust-version"
- name: "Install Rust toolchain"
run: rustup default ${{ steps.msrv.outputs.value }}
- name: "Install mold"
uses: rui314/setup-mold@v1
- uses: Swatinem/rust-cache@v2
- run: cargo +${{ steps.msrv.outputs.value }} build
- run: ./target/debug/uv --version
build-binary-freebsd:
needs: determine_changes
timeout-minutes: 10
if: ${{ github.repository == 'astral-sh/uv' && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
runs-on:
labels: ubuntu-latest
name: "build binary | freebsd"
steps:
- uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2
- name: "Cross build"
run: |
# Install cross from `freebsd-firecracker`
wget -q -O cross https://github.com/acj/freebsd-firecracker/releases/download/v0.0.10/cross
chmod +x cross
mv cross /usr/local/bin/cross
cross build --target x86_64-unknown-freebsd
- name: Test in Firecracker VM
uses: acj/[email protected]
with:
verbose: false
pre-run: |
# The exclude `*` prevents examination of directories so we need to
# include each parent directory of the binary
include_path="$(mktemp)"
cat <<EOF > $include_path
target
target/x86_64-unknown-freebsd
target/x86_64-unknown-freebsd/debug
target/x86_64-unknown-freebsd/debug/uv
EOF
rsync -r -e "ssh" \
--relative \
--copy-links \
--include-from "$include_path" \
--exclude "*" \
. firecracker:
run-in-vm: |
cp target/x86_64-unknown-freebsd/debug/uv uv
chmod +x uv
./uv --version
ecosystem-test:
timeout-minutes: 10
needs: build-binary-linux
name: "ecosystem test | ${{ matrix.repo }}"
runs-on: ubuntu-latest
strategy:
matrix:
include:
- repo: "prefecthq/prefect"
command: "uv pip install -e '.[dev]'"
python: "3.9"
- repo: "pallets/flask"
command: "uv pip install -r requirements/dev.txt"
python: "3.12"
fail-fast: false
steps:
- uses: actions/checkout@v4
with:
repository: ${{ matrix.repo }}
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Test"
run: |
./uv venv
./${{ matrix.command }}
integration-test-conda:
timeout-minutes: 10
needs: build-binary-linux
name: "integration test | conda on ubuntu"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: conda-incubator/setup-miniconda@v3
with:
miniconda-version: latest
activate-environment: uv
python-version: "3.12"
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: Conda info
shell: bash -el {0}
run: conda info
- name: "Install a package"
shell: bash -el {0}
run: |
echo "$CONDA_PREFIX"
./uv pip install anyio
integration-test-free-threaded-linux:
timeout-minutes: 5
needs: build-binary-linux
name: "integration test | free-threaded on linux"
runs-on: ubuntu-latest
steps:
- name: "install python3.13-nogil"
run: |
sudo add-apt-repository ppa:deadsnakes
sudo apt-get update
sudo apt-get install python3.13-nogil
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Create a virtual environment"
run: |
./uv venv -p 3.13t --python-preference only-system
- name: "Check version"
run: |
.venv/bin/python --version
- name: "Check is free-threaded"
run: |
.venv/bin/python -c "import sys; exit(1) if sys._is_gil_enabled() else exit(0)"
- name: "Check install"
run: |
./uv pip install -v anyio
- name: "Install free-threaded Python via uv"
run: |
./uv python install -v 3.13t
./uv venv -p 3.13t --python-preference only-managed
- name: "Check version"
run: |
.venv/bin/python --version
- name: "Check is free-threaded"
run: |
.venv/bin/python -c "import sys; exit(1) if sys._is_gil_enabled() else exit(0)"
- name: "Check install"
run: |
./uv pip install -v anyio
integration-test-free-threaded-windows:
timeout-minutes: 10
needs: build-binary-windows
name: "integration test | free-threaded on windows"
runs-on: windows-latest
env:
# Avoid debug build stack overflows.
UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows
steps:
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-windows-${{ github.sha }}
- name: "Install free-threaded Python via uv"
run: |
./uv python install -v 3.13t
- name: "Create a virtual environment"
run: |
./uv venv -p 3.13t --python-preference only-managed
- name: "Check version"
run: |
.venv/Scripts/python --version
- name: "Check is free-threaded"
run: |
.venv/Scripts/python -c "import sys; exit(1) if sys._is_gil_enabled() else exit(0)"
- name: "Check install"
run: |
./uv pip install -v anyio
- name: "Check uv run"
run: |
./uv run python -c ""
./uv run -p 3.13t python -c ""
integration-test-pypy-linux:
timeout-minutes: 10
needs: build-binary-linux
name: "integration test | pypy on ubuntu"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Install PyPy"
run: ./uv python install -v pypy3.9
- name: "Create a virtual environment"
run: |
./uv venv -p pypy3.9 --python-preference only-managed
- name: "Check for executables"
run: |
check_in_bin() {
local executable_name=$1
local bin_path=".venv/bin"
if [[ -x "$bin_path/$executable_name" ]]; then
return 0
else
echo "Executable '$executable_name' not found in folder '$bin_path'."
return 1
fi
}
executables=("pypy" "pypy3" "python")
all_found=true
for executable_name in "${executables[@]}"; do
check_in_bin "$executable_name" "$folder_path"
result=$?
if [[ $result -ne 0 ]]; then
all_found=false
fi
done
if ! $all_found; then
echo "One or more expected executables were not found."
exit 1
fi
- name: "Check version"
run: |
.venv/bin/pypy --version
.venv/bin/pypy3 --version
.venv/bin/python --version
- name: "Check install"
run: |
./uv pip install anyio
integration-test-pypy-windows:
timeout-minutes: 10
needs: build-binary-windows
name: "integration test | pypy on windows"
runs-on: windows-latest
steps:
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-windows-${{ github.sha }}
- name: "Install PyPy"
run: .\uv.exe python install pypy3.9
- name: "Create a virtual environment"
run: |
.\uv.exe venv -p pypy3.9 --python-preference only-managed
- name: "Check for executables"
shell: python
run: |
import sys
from pathlib import Path
def binary_exist(binary):
binaries_path = Path(".venv\\Scripts")
if (binaries_path / binary).exists():
return True
print(f"Executable '{binary}' not found in folder '{binaries_path}'.")
all_found = True
expected_binaries = [
"pypy3.9.exe",
"pypy3.9w.exe",
"pypy3.exe",
"pypyw.exe",
"python.exe",
"python3.9.exe",
"python3.exe",
"pythonw.exe",
]
for binary in expected_binaries:
if not binary_exist(binary):
all_found = False
if not all_found:
print("One or more expected executables were not found.")
sys.exit(1)
- name: "Check version"
run: |
& .venv\Scripts\pypy3.9.exe --version
& .venv\Scripts\pypy3.exe --version
& .venv\Scripts\python.exe --version
- name: "Check install"
env:
# Avoid debug build stack overflows.
UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows
run: |
.\uv.exe pip install anyio
integration-test-graalpy-linux:
timeout-minutes: 10
needs: build-binary-linux
name: "integration test | graalpy on ubuntu"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "graalpy24.1"
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: Graalpy info
run: |
which graalpy
- name: "Create a virtual environment"
run: |
./uv venv -p $(which graalpy)
- name: "Check for executables"
run: |
check_in_bin() {
local executable_name=$1
local bin_path=".venv/bin"
if [[ -x "$bin_path/$executable_name" ]]; then
return 0
else
echo "Executable '$executable_name' not found in folder '$bin_path'."
return 1
fi
}
executables=("graalpy" "python3" "python")
all_found=true
for executable_name in "${executables[@]}"; do
check_in_bin "$executable_name" "$folder_path"
result=$?
if [[ $result -ne 0 ]]; then
all_found=false
fi
done
if ! $all_found; then
echo "One or more expected executables were not found."
exit 1
fi
- name: "Check version"
run: |
.venv/bin/graalpy --version
.venv/bin/python3 --version
.venv/bin/python --version
- name: "Check install"
run: |
./uv pip install anyio
integration-test-graalpy-windows:
timeout-minutes: 10
needs: build-binary-windows
name: "integration test | graalpy on windows"
runs-on: windows-latest
steps:
- uses: timfel/setup-python@fc9bcb4a04f5b1ea7d678c2ca7ea1c479a2468d7
with:
python-version: "graalpy24.1"
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-windows-${{ github.sha }}
- name: Graalpy info
run: Get-Command graalpy
- name: "Create a virtual environment"
run: |
$graalpy = (Get-Command graalpy).source
.\uv.exe venv -p $graalpy
- name: "Check for executables"
shell: python
run: |
import sys
from pathlib import Path
def binary_exist(binary):
binaries_path = Path(".venv\\Scripts")
if (binaries_path / binary).exists():
return True
print(f"Executable '{binary}' not found in folder '{binaries_path}'.")
all_found = True
expected_binaries = [
"graalpy.exe",
"python.exe",
"python3.exe",
]
for binary in expected_binaries:
if not binary_exist(binary):
all_found = False
if not all_found:
print("One or more expected executables were not found.")
sys.exit(1)
- name: "Check version"
run: |
& .venv\Scripts\graalpy.exe --version
& .venv\Scripts\python3.exe --version
& .venv\Scripts\python.exe --version
- name: "Check install"
env:
# Avoid debug build stack overflows.
UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows
run: |
.\uv.exe pip install anyio
integration-test-github-actions:
timeout-minutes: 10
needs: build-binary-linux
name: "integration test | github actions"
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v5
with:
python-version: "3.12.7"
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Install a package without system opt-in"
run: |
./uv pip install anyio && exit 1 || echo "Failed as expected"
- name: "Install a package with system opt-in"
run: |
./uv pip install anyio --system
- name: Configure uv to use the system Python by default
run: echo "UV_SYSTEM_PYTHON=1" >> $GITHUB_ENV
- name: "Install a package with system opt-in via the environment"
run: |
./uv pip install anyio --reinstall
- name: "Create a project"
run: |
# Use Python 3.11 as the minimum required version
./uv init --python 3.11
./uv add anyio
- name: "Sync to the system Python"
run: ./uv sync -v --python 3.12
env:
UV_PROJECT_ENVIRONMENT: "/opt/hostedtoolcache/Python/3.12.7/x64"
- name: "Attempt to sync to the system Python with an incompatible version"
run: |
./uv sync -v --python 3.11 && { echo "ci: Error; should not succeed"; exit 1; } || { echo "ci: Ok; expected failure"; exit 0; }
env:
UV_PROJECT_ENVIRONMENT: "/opt/hostedtoolcache/Python/3.12.7/x64"
- name: "Attempt to sync to a non-Python environment directory"
run: |
mkdir -p /home/runner/example
touch /home/runner/example/some-file
./uv sync -v && { echo "ci: Error; should not succeed"; exit 1; } || { echo "ci: Ok; expected failure"; exit 0; }
env:
UV_PROJECT_ENVIRONMENT: "/home/runner/example"
integration-test-publish-changed:
timeout-minutes: 10
needs: build-binary-linux
name: "integration test | determine publish changes"
runs-on: ubuntu-latest
outputs:
# Flag that is raised when any code is changed
code: ${{ steps.changed.outputs.code_any_changed }}
# Only the main repository is a trusted publisher
if: github.repository == 'astral-sh/uv'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Only publish a new release if the publishing code changed
- uses: tj-actions/changed-files@v45
id: changed
with:
files_yaml: |
code:
- "crates/uv-publish/**/*"
- "scripts/publish/**/*"
- ".github/workflows/ci.yml"
integration-test-publish:
timeout-minutes: 10
needs: integration-test-publish-changed
name: "integration test | uv publish"
runs-on: ubuntu-latest
if: ${{ github.repository == 'astral-sh/uv' && github.event.pull_request.head.repo.fork != true && (needs.integration-test-publish-changed.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
environment: uv-test-publish
env:
# No dbus in GitHub Actions
PYTHON_KEYRING_BACKEND: keyrings.alt.file.PlaintextKeyring
PYTHON_VERSION: 3.12
permissions:
# For trusted publishing
id-token: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "${{ env.PYTHON_VERSION }}"
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Add password to keyring"
run: |
# `keyrings.alt` contains the plaintext keyring
./uv tool install --with keyrings.alt "keyring<25.4.0" # TODO(konsti): Remove upper bound once fix is released
echo $UV_TEST_PUBLISH_KEYRING | keyring set https://test.pypi.org/legacy/?astral-test-keyring __token__
env:
UV_TEST_PUBLISH_KEYRING: ${{ secrets.UV_TEST_PUBLISH_KEYRING }}
- name: "Publish test packages"
# `-p 3.12` prefers the python we just installed over the one locked in `.python_version`.
run: ./uv run -p ${{ env.PYTHON_VERSION }} scripts/publish/test_publish.py --uv ./uv all
env:
RUST_LOG: uv=debug,uv_publish=trace
UV_TEST_PUBLISH_TOKEN: ${{ secrets.UV_TEST_PUBLISH_TOKEN }}
UV_TEST_PUBLISH_PASSWORD: ${{ secrets.UV_TEST_PUBLISH_PASSWORD }}
UV_TEST_PUBLISH_GITLAB_PAT: ${{ secrets.UV_TEST_PUBLISH_GITLAB_PAT }}
UV_TEST_PUBLISH_CODEBERG_TOKEN: ${{ secrets.UV_TEST_PUBLISH_CODEBERG_TOKEN }}
UV_TEST_PUBLISH_CLOUDSMITH_TOKEN: ${{ secrets.UV_TEST_PUBLISH_CLOUDSMITH_TOKEN }}
UV_TEST_PUBLISH_PYTHON_VERSION: ${{ env.PYTHON_VERSION }}
cache-test-ubuntu:
timeout-minutes: 10
needs: build-binary-linux
name: "check cache | ubuntu"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Download binary for last version"
run: curl -LsSf "https://github.com/astral-sh/uv/releases/latest/download/uv-x86_64-unknown-linux-gnu.tar.gz" | tar -xvz
- name: "Check cache compatibility"
run: python scripts/check_cache_compat.py --uv-current ./uv --uv-previous ./uv-x86_64-unknown-linux-gnu/uv
cache-test-macos-aarch64:
timeout-minutes: 10
needs: build-binary-macos-aarch64
name: "check cache | macos aarch64"
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-macos-aarch64-${{ github.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
- name: "Download binary for last version"
run: curl -LsSf "https://github.com/astral-sh/uv/releases/latest/download/uv-aarch64-apple-darwin.tar.gz" | tar -xvz
- name: "Check cache compatibility"
run: python scripts/check_cache_compat.py --uv-current ./uv --uv-previous ./uv-aarch64-apple-darwin/uv
system-test-debian:
timeout-minutes: 10
needs: build-binary-linux
name: "check system | python on debian"
runs-on: ubuntu-latest
container: debian:bookworm
steps:
- uses: actions/checkout@v4
- name: "Install Python"
run: apt-get update && apt-get install -y python3.11 python3-pip python3.11-venv
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.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
system-test-fedora:
timeout-minutes: 10
needs: build-binary-linux
name: "check system | python on fedora"
runs-on: ubuntu-latest
container: fedora:42
steps:
- uses: actions/checkout@v4
- name: "Install Python"
run: dnf install python3 which -y && python3 -m ensurepip
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.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
needs: build-binary-linux
name: "check system | python on ubuntu"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.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
system-test-opensuse:
timeout-minutes: 5
needs: build-binary-linux
name: "check system | python on opensuse"
runs-on: ubuntu-latest
container: opensuse/tumbleweed
steps:
- uses: actions/checkout@v4
- 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@v4
with:
name: uv-linux-${{ github.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
needs: build-binary-linux
name: "check system | python on rocky linux ${{ matrix.rocky-version }}"
runs-on: ubuntu-latest
container: rockylinux:${{ matrix.rocky-version }}
strategy:
fail-fast: false
matrix:
rocky-version: ["8", "9"]
steps:
- uses: actions/checkout@v4
- name: "Install Python"
if: matrix.rocky-version == '8'
run: |
dnf install python39 python39-pip which -y
- name: "Install Python"
if: matrix.rocky-version == '9'
run: |
dnf install python3.9 python3.9-pip which -y
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.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-pypy:
timeout-minutes: 10
needs: build-binary-linux
name: "check system | pypy on ubuntu"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "pypy3.9"
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.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
needs: build-binary-linux
name: "check system | pyston"
runs-on: ubuntu-latest
container: pyston/pyston:2.3.5
steps:
- uses: actions/checkout@v4
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.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
needs: build-binary-linux
name: "check system | alpine"
runs-on: ubuntu-latest
container: alpine:latest
steps:
- uses: actions/checkout@v4
- name: "Install Python"
run: apk add --update --no-cache python3 py3-pip
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.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
needs: build-binary-macos-aarch64
name: "check system | python on macos aarch64"
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-macos-aarch64-${{ github.sha }}
- name: "Prepare binary"
run: chmod +x ./uv
# This should be the macOS system Python
# We'd like to test with Homebrew but this Python takes precedence in system Python discovery
- 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
needs: build-binary-macos-aarch64
name: "check system | homebrew python on macos aarch64"
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- name: "Install Python"
run: brew install python3
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-macos-aarch64-${{ github.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
needs: build-binary-macos-x86_64
name: "check system | python on macos x86_64"
runs-on: macos-13
steps:
- uses: actions/checkout@v4
# We test with GitHub's Python as a regression test for
# https://github.com/astral-sh/uv/issues/2450
- uses: actions/setup-python@v5
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-macos-x86_64-${{ github.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-windows-python-310:
timeout-minutes: 10
needs: build-binary-windows
name: "check system | python3.10 on windows"
runs-on: windows-latest
env:
# Avoid debug build stack overflows.
UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-windows-${{ github.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-python-310:
timeout-minutes: 10
needs: build-binary-windows
name: "check system | python3.10 on windows x86"
runs-on: windows-latest
env:
# Avoid debug build stack overflows.
UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.10"
architecture: "x86"
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-windows-${{ github.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-python-313:
timeout-minutes: 10
needs: build-binary-windows
name: "check system | python3.13 on windows"
runs-on: windows-latest
env:
# Avoid debug build stack overflows.
UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.13"
allow-prereleases: true
cache: pip
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-windows-${{ github.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-choco:
timeout-minutes: 10
needs: build-binary-windows
name: "check system | python3.12 via chocolatey"
runs-on: windows-latest
env:
# Avoid debug build stack overflows.
UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows
steps:
- uses: actions/checkout@v4
- name: "Install Python"
run: choco install python3 --verbose --version=3.9.13
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-windows-${{ github.sha }}
- name: "Print Python path"
run: echo $(which python3)
- name: "Validate global Python install"
run: py -3.9 ./scripts/check_system_python.py --uv ./uv.exe
system-test-pyenv:
timeout-minutes: 10
needs: build-binary-linux
name: "check system | python3.9 via pyenv"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- 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@v4
with:
name: uv-linux-${{ github.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
needs: build-binary-linux
name: "check system | python3.13"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: 3.13
allow-prereleases: true
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.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
needs:
[build-binary-windows, build-binary-macos-aarch64, build-binary-linux]
name: check system | conda${{ matrix.python-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
os: ["linux", "windows", "macos"]
python-version: ["3.8", "3.11"]
include:
- { os: "linux", target: "linux", runner: "ubuntu-latest" }
- { os: "windows", target: "windows", runner: "windows-latest" }
- { os: "macos", target: "macos-aarch64", runner: "macos-14" }
steps:
- uses: actions/checkout@v4
- uses: conda-incubator/setup-miniconda@v3
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@v4
with:
name: uv-${{ matrix.target }}-${{ github.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}
env:
# Avoid debug build stack overflows.
UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows
run: python ./scripts/check_system_python.py --uv ./uv
system-test-amazonlinux:
timeout-minutes: 10
needs: build-binary-linux
name: "check system | 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@v4
- name: "Install Python"
run: yum install python3 python3-pip -y
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-linux-${{ github.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-windows-embedded-python-310:
timeout-minutes: 10
needs: build-binary-windows
name: "check system | embedded python3.10 on windows"
runs-on: windows-latest
env:
# Avoid debug build stack overflows.
UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows
steps:
- uses: actions/checkout@v4
- name: "Download binary"
uses: actions/download-artifact@v4
with:
name: uv-windows-${{ github.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
benchmarks:
runs-on: ubuntu-latest
needs: determine_changes
if: ${{ github.repository == 'astral-sh/uv' && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
timeout-minutes: 20
steps:
- name: "Checkout Branch"
uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2
- name: "Install Rust toolchain"
run: rustup show
- name: "Install codspeed"
uses: taiki-e/install-action@v2
with:
tool: cargo-codspeed
- name: "Install requirements and prime cache"
run: |
sudo apt-get update
sudo apt-get install -y libsasl2-dev libldap2-dev libkrb5-dev
cargo run --bin uv -- venv --cache-dir .cache
cargo run --bin uv -- pip compile scripts/requirements/jupyter.in --universal --exclude-newer 2024-08-08 --cache-dir .cache
cargo run --bin uv -- pip compile scripts/requirements/airflow.in --universal --exclude-newer 2024-08-08 --cache-dir .cache
- name: "Build benchmarks"
run: cargo codspeed build --profile profiling --features codspeed -p uv-bench
- name: "Run benchmarks"
uses: CodSpeedHQ/action@v3
with:
run: cargo codspeed run
token: ${{ secrets.CODSPEED_TOKEN }}