mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 13:25:00 +00:00
2514 lines
87 KiB
YAML
2514 lines
87 KiB
YAML
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
|
|
PYTHON_VERSION: "3.12"
|
|
RUSTUP_MAX_RETRIES: 10
|
|
RUST_BACKTRACE: 1
|
|
|
|
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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: "Determine changed files"
|
|
id: changed
|
|
shell: bash
|
|
run: |
|
|
CHANGED_FILES=$(git diff --name-only ${{ github.event.pull_request.base.sha || 'origin/main' }}...HEAD)
|
|
|
|
CODE_CHANGED=false
|
|
|
|
while IFS= read -r file; do
|
|
# Generated markdown and JSON files are checked during test runs.
|
|
if [[ "${file}" =~ ^docs/ && ! "${file}" =~ ^docs/reference/(cli|settings).md && ! "${file}" =~ ^docs/reference/environment.md ]]; then
|
|
echo "Skipping ${file} (matches docs/ pattern)"
|
|
continue
|
|
fi
|
|
if [[ "${file}" =~ ^mkdocs.*\.yml$ ]]; then
|
|
echo "Skipping ${file} (matches mkdocs*.yml pattern)"
|
|
continue
|
|
fi
|
|
if [[ "${file}" =~ \.md$ ]]; then
|
|
echo "Skipping ${file} (matches *.md pattern)"
|
|
continue
|
|
fi
|
|
if [[ "${file}" =~ ^bin/ ]]; then
|
|
echo "Skipping ${file} (matches bin/ pattern)"
|
|
continue
|
|
fi
|
|
if [[ "${file}" =~ ^assets/ ]]; then
|
|
echo "Skipping ${file} (matches assets/ pattern)"
|
|
continue
|
|
fi
|
|
|
|
echo "Detected code change in: ${file}"
|
|
CODE_CHANGED=true
|
|
break
|
|
|
|
done <<< "${CHANGED_FILES}"
|
|
echo "code_any_changed=${CODE_CHANGED}" >> "${GITHUB_OUTPUT}"
|
|
lint:
|
|
timeout-minutes: 10
|
|
name: "lint"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
with:
|
|
python-version: 3.12
|
|
|
|
- name: "Install Rustfmt"
|
|
run: rustup component add rustfmt
|
|
|
|
- name: "Install uv"
|
|
uses: astral-sh/setup-uv@bd01e18f51369d5a26f1651c3cb451d3417e3bba # v6.3.1
|
|
|
|
- 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/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # 2.0.0
|
|
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: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
runs-on: ubuntu-latest
|
|
name: "cargo clippy | ubuntu"
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- name: "Check uv_build dependencies"
|
|
uses: EmbarkStudios/cargo-deny-action@30f817c6f72275c6d54dc744fbca09ebc958599f # v2.0.12
|
|
with:
|
|
command: check bans
|
|
manifest-path: crates/uv-build/Cargo.toml
|
|
- 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: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
runs-on: windows-latest
|
|
name: "cargo clippy | windows"
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: Setup Dev Drive
|
|
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@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
with:
|
|
workspaces: ${{ env.UV_WORKSPACE }}
|
|
|
|
- name: "Install Rust toolchain"
|
|
run: rustup component add clippy
|
|
|
|
- name: "Clippy"
|
|
working-directory: ${{ env.UV_WORKSPACE }}
|
|
run: cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
|
|
|
|
cargo-dev-generate-all:
|
|
timeout-minutes: 10
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
runs-on: ubuntu-latest
|
|
name: "cargo dev generate-all"
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- name: "Install cargo shear"
|
|
uses: taiki-e/install-action@7b20dfd705618832f20d29066e34aa2f2f6194c2 # v2.52.8
|
|
with:
|
|
tool: 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: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
runs-on: depot-ubuntu-22.04-16
|
|
name: "cargo test | ubuntu"
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: rui314/setup-mold@v1
|
|
|
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
|
|
- uses: astral-sh/setup-uv@bd01e18f51369d5a26f1651c3cb451d3417e3bba # v6.3.1
|
|
- name: "Install required Python versions"
|
|
run: uv python install
|
|
|
|
- name: "Install cargo nextest"
|
|
uses: taiki-e/install-action@7b20dfd705618832f20d29066e34aa2f2f6194c2 # v2.52.8
|
|
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
|
|
|
|
cargo-test-macos:
|
|
timeout-minutes: 15
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
runs-on: macos-latest-xlarge # github-macos-14-aarch64-6
|
|
name: "cargo test | macos"
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: rui314/setup-mold@v1
|
|
|
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
|
|
- uses: astral-sh/setup-uv@bd01e18f51369d5a26f1651c3cb451d3417e3bba # v6.3.1
|
|
- name: "Install required Python versions"
|
|
run: uv python install
|
|
|
|
- name: "Install cargo nextest"
|
|
uses: taiki-e/install-action@7b20dfd705618832f20d29066e34aa2f2f6194c2 # v2.52.8
|
|
with:
|
|
tool: cargo-nextest
|
|
|
|
- name: "Cargo test"
|
|
run: |
|
|
cargo nextest run \
|
|
--no-default-features \
|
|
--features python,python-managed,pypi,git,performance,crates-io \
|
|
--workspace \
|
|
--status-level skip --failure-output immediate-final --no-fail-fast -j 12 --final-status-level slow
|
|
|
|
cargo-test-windows:
|
|
timeout-minutes: 15
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
runs-on: depot-windows-2022-16
|
|
name: "cargo test | windows"
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: Setup Dev Drive
|
|
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: astral-sh/setup-uv@bd01e18f51369d5a26f1651c3cb451d3417e3bba # v6.3.1
|
|
- name: "Install required Python versions"
|
|
run: uv python install
|
|
|
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
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@7b20dfd705618832f20d29066e34aa2f2f6194c2 # v2.52.8
|
|
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
|
|
shell: bash
|
|
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
|
|
|
|
# Separate jobs for the nightly crate
|
|
windows-trampoline-check:
|
|
timeout-minutes: 15
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
runs-on: windows-latest
|
|
name: "check windows trampoline | ${{ matrix.target-arch }}"
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
target-arch: ["x86_64", "i686", "aarch64"]
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: Setup Dev Drive
|
|
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@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
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@7b20dfd705618832f20d29066e34aa2f2f6194c2 # v2.52.8
|
|
with:
|
|
tool: cargo-bloat
|
|
|
|
- name: "rustfmt"
|
|
working-directory: ${{ env.UV_WORKSPACE }}/crates/uv-trampoline
|
|
run: cargo fmt --all --check
|
|
|
|
- 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: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- name: Setup Dev Drive
|
|
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@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
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: "Test committed binaries"
|
|
working-directory: ${{ env.UV_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: ${{ env.UV_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: ${{ env.UV_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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
with:
|
|
fetch-depth: 0
|
|
- uses: astral-sh/setup-uv@bd01e18f51369d5a26f1651c3cb451d3417e3bba # v6.3.1
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
- name: "Add SSH key"
|
|
if: ${{ env.MKDOCS_INSIDERS_SSH_KEY_EXISTS == 'true' }}
|
|
uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
|
|
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-libc:
|
|
timeout-minutes: 10
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
runs-on: github-ubuntu-24.04-x86_64-8
|
|
name: "build binary | linux libc"
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: rui314/setup-mold@v1
|
|
|
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
|
|
- name: "Build"
|
|
run: cargo build
|
|
|
|
- name: "Upload binary"
|
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
with:
|
|
name: uv-linux-libc-${{ github.sha }}
|
|
path: |
|
|
./target/debug/uv
|
|
./target/debug/uvx
|
|
retention-days: 1
|
|
|
|
build-binary-linux-musl:
|
|
timeout-minutes: 10
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
runs-on: github-ubuntu-24.04-x86_64-8
|
|
name: "build binary | linux musl"
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- 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@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
|
|
- name: "Build"
|
|
run: cargo build --target x86_64-unknown-linux-musl --bin uv --bin uvx
|
|
|
|
- name: "Upload binary"
|
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
with:
|
|
name: uv-linux-musl-${{ github.sha }}
|
|
path: |
|
|
./target/x86_64-unknown-linux-musl/debug/uv
|
|
./target/x86_64-unknown-linux-musl/debug/uvx
|
|
retention-days: 1
|
|
|
|
build-binary-macos-aarch64:
|
|
timeout-minutes: 10
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
runs-on: macos-14 # github-macos-14-aarch64-3
|
|
name: "build binary | macos aarch64"
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: rui314/setup-mold@v1
|
|
|
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
- name: "Build"
|
|
run: cargo build --bin uv --bin uvx
|
|
|
|
- name: "Upload binary"
|
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
with:
|
|
name: uv-macos-aarch64-${{ github.sha }}
|
|
path: |
|
|
./target/debug/uv
|
|
./target/debug/uvx
|
|
retention-days: 1
|
|
|
|
build-binary-macos-x86_64:
|
|
timeout-minutes: 10
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
runs-on: macos-latest-large # github-macos-14-x86_64-12
|
|
name: "build binary | macos x86_64"
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: rui314/setup-mold@v1
|
|
|
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
- name: "Build"
|
|
run: cargo build --bin uv --bin uvx
|
|
|
|
- name: "Upload binary"
|
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
with:
|
|
name: uv-macos-x86_64-${{ github.sha }}
|
|
path: |
|
|
./target/debug/uv
|
|
./target/debug/uvx
|
|
retention-days: 1
|
|
|
|
build-binary-windows-x86_64:
|
|
needs: determine_changes
|
|
timeout-minutes: 10
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
runs-on: windows-latest
|
|
name: "build binary | windows x86_64"
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: Setup Dev Drive
|
|
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@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
with:
|
|
workspaces: ${{ env.UV_WORKSPACE }}
|
|
|
|
- name: "Build"
|
|
working-directory: ${{ env.UV_WORKSPACE }}
|
|
run: cargo build --bin uv --bin uvx
|
|
|
|
- name: "Upload binary"
|
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
with:
|
|
name: uv-windows-x86_64-${{ github.sha }}
|
|
path: |
|
|
${{ env.UV_WORKSPACE }}/target/debug/uv.exe
|
|
${{ env.UV_WORKSPACE }}/target/debug/uvx.exe
|
|
retention-days: 1
|
|
|
|
build-binary-windows-aarch64:
|
|
needs: determine_changes
|
|
timeout-minutes: 25
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
runs-on:
|
|
labels: windows-latest
|
|
name: "build binary | windows aarch64"
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- 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@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
with:
|
|
workspaces: ${{ env.UV_WORKSPACE }}
|
|
|
|
- name: "Install cross target"
|
|
run: rustup target add aarch64-pc-windows-msvc
|
|
|
|
- name: "Build"
|
|
working-directory: ${{ env.UV_WORKSPACE }}
|
|
run: cargo build --target aarch64-pc-windows-msvc
|
|
|
|
- name: "Upload binary"
|
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
with:
|
|
name: uv-windows-aarch64-${{ github.sha }}
|
|
path: |
|
|
${{ env.UV_WORKSPACE }}/target/aarch64-pc-windows-msvc/debug/uv.exe
|
|
${{ env.UV_WORKSPACE }}/target/aarch64-pc-windows-msvc/debug/uvx.exe
|
|
retention-days: 1
|
|
|
|
cargo-build-msrv:
|
|
name: "cargo build (msrv)"
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
runs-on: github-ubuntu-24.04-x86_64-8
|
|
timeout-minutes: 10
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- uses: SebRollen/toml-action@b1b3628f55fc3a28208d4203ada8b737e9687876 # v1.2.0
|
|
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@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
- run: cargo +${{ steps.msrv.outputs.value }} build
|
|
- run: ./target/debug/uv --version
|
|
|
|
build-binary-freebsd:
|
|
needs: determine_changes
|
|
timeout-minutes: 10
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
runs-on: ubuntu-latest
|
|
name: "build binary | freebsd"
|
|
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
- 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/freebsd-firecracker-action@136ca0bce2adade21e526ceb07db643ad23dd2dd # v0.5.1
|
|
with:
|
|
verbose: false
|
|
checkout: 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: |
|
|
mv target/x86_64-unknown-freebsd/debug/uv uv
|
|
chmod +x uv
|
|
./uv --version
|
|
|
|
ecosystem-test:
|
|
timeout-minutes: 10
|
|
needs: build-binary-linux-libc
|
|
name: "ecosystem test | ${{ matrix.repo }}"
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
include:
|
|
- repo: "prefecthq/prefect"
|
|
ref: "7f25bbdf45fc81cca6dc23fb6a7377d436b70c83"
|
|
commands:
|
|
- "uv venv"
|
|
- "uv pip install -e '.[dev]'"
|
|
python: "3.9"
|
|
- repo: "pallets/flask"
|
|
ref: "b78b5a210bde49e7e04b62a2a4f453ca10e0048c"
|
|
commands:
|
|
- "uv venv"
|
|
- "uv pip install -r requirements/dev.txt"
|
|
python: "3.12"
|
|
- repo: "pydantic/pydantic-core"
|
|
ref: "d03bf4a01ca3b378cc8590bd481f307e82115bc6"
|
|
commands:
|
|
- "uv sync --group all"
|
|
- "uv lock --upgrade"
|
|
python: "3.12"
|
|
fail-fast: false
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
with:
|
|
repository: ${{ matrix.repo }}
|
|
ref: ${{ matrix.ref }}
|
|
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
with:
|
|
python-version: ${{ matrix.python }}
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-libc-${{ github.sha }}
|
|
|
|
- name: "Prepare binary"
|
|
run: chmod +x ./uv
|
|
|
|
- name: "Test"
|
|
run: |
|
|
echo '${{ toJSON(matrix.commands) }}' | jq -r '.[]' | while read cmd; do
|
|
echo "+ $cmd" >&2
|
|
if [[ $cmd == uv* ]]; then
|
|
./$cmd
|
|
else
|
|
$cmd
|
|
fi
|
|
done
|
|
|
|
smoke-test-linux:
|
|
timeout-minutes: 10
|
|
needs: build-binary-linux-libc
|
|
name: "smoke test | linux"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-libc-${{ github.sha }}
|
|
|
|
- name: "Prepare binary"
|
|
run: |
|
|
chmod +x ./uv
|
|
chmod +x ./uvx
|
|
|
|
- name: "Smoke test"
|
|
run: |
|
|
./uv run scripts/smoke-test
|
|
|
|
- name: "Test shell completions"
|
|
run: |
|
|
eval "$(./uv generate-shell-completion bash)"
|
|
eval "$(./uvx --generate-shell-completion bash)"
|
|
|
|
smoke-test-linux-musl:
|
|
timeout-minutes: 10
|
|
needs: build-binary-linux-musl
|
|
name: "check system | alpine"
|
|
runs-on: ubuntu-latest
|
|
container: alpine:latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-musl-${{ github.sha }}
|
|
|
|
- name: "Prepare binary"
|
|
run: |
|
|
chmod +x ./uv
|
|
chmod +x ./uvx
|
|
|
|
- name: "Smoke test"
|
|
run: |
|
|
./uv run scripts/smoke-test
|
|
|
|
smoke-test-macos:
|
|
timeout-minutes: 10
|
|
needs: build-binary-macos-x86_64
|
|
name: "smoke test | macos"
|
|
runs-on: macos-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-macos-x86_64-${{ github.sha }}
|
|
|
|
- name: "Prepare binary"
|
|
run: |
|
|
chmod +x ./uv
|
|
chmod +x ./uvx
|
|
|
|
- name: "Smoke test"
|
|
run: |
|
|
./uv run scripts/smoke-test
|
|
|
|
- name: "Test shell completions"
|
|
run: |
|
|
eval "$(./uv generate-shell-completion bash)"
|
|
eval "$(./uvx --generate-shell-completion bash)"
|
|
|
|
smoke-test-windows-x86_64:
|
|
timeout-minutes: 10
|
|
needs: build-binary-windows-x86_64
|
|
name: "smoke test | windows x86_64"
|
|
runs-on: windows-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-windows-x86_64-${{ github.sha }}
|
|
|
|
- name: "Smoke test"
|
|
working-directory: ${{ env.UV_WORKSPACE }}
|
|
run: |
|
|
./uv run scripts/smoke-test
|
|
|
|
- name: "Test uv shell completions"
|
|
working-directory: ${{ env.UV_WORKSPACE }}
|
|
run: |
|
|
(& ./uv generate-shell-completion powershell) | Out-String | Invoke-Expression
|
|
|
|
- name: "Test uvx shell completions"
|
|
working-directory: ${{ env.UV_WORKSPACE }}
|
|
run: |
|
|
(& ./uvx --generate-shell-completion powershell) | Out-String | Invoke-Expression
|
|
|
|
smoke-test-windows-aarch64:
|
|
timeout-minutes: 10
|
|
needs: build-binary-windows-aarch64
|
|
name: "smoke test | windows aarch64"
|
|
runs-on: windows-11-arm
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-windows-aarch64-${{ github.sha }}
|
|
|
|
- name: "Smoke test"
|
|
working-directory: ${{ env.UV_WORKSPACE }}
|
|
run: |
|
|
./uv run scripts/smoke-test
|
|
|
|
- name: "Test uv shell completions"
|
|
working-directory: ${{ env.UV_WORKSPACE }}
|
|
run: |
|
|
(& ./uv generate-shell-completion powershell) | Out-String | Invoke-Expression
|
|
|
|
- name: "Test uvx shell completions"
|
|
working-directory: ${{ env.UV_WORKSPACE }}
|
|
run: |
|
|
(& ./uvx --generate-shell-completion powershell) | Out-String | Invoke-Expression
|
|
|
|
integration-test-conda:
|
|
timeout-minutes: 10
|
|
needs: build-binary-linux-libc
|
|
name: "integration test | conda on ubuntu"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- uses: conda-incubator/setup-miniconda@835234971496cad1653abb28a638a281cf32541f # v3.2.0
|
|
with:
|
|
miniconda-version: latest
|
|
activate-environment: uv
|
|
python-version: "3.12"
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-libc-${{ 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-deadsnakes-39-linux:
|
|
timeout-minutes: 15
|
|
needs: build-binary-linux-libc
|
|
name: "integration test | deadsnakes python3.9 on ubuntu"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: "Install python3.9"
|
|
run: |
|
|
for i in {1..5}; do
|
|
sudo add-apt-repository ppa:deadsnakes && break || { echo "Attempt $i failed, retrying in 10 seconds..."; sleep 10; }
|
|
if [ $i -eq 5 ]; then
|
|
echo "Failed to add repository after 5 attempts"
|
|
exit 1
|
|
fi
|
|
done
|
|
sudo apt-get update
|
|
sudo apt-get install python3.9
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-libc-${{ github.sha }}
|
|
|
|
- name: "Prepare binary"
|
|
run: chmod +x ./uv
|
|
|
|
- name: "Check missing distutils"
|
|
run: |
|
|
./uv venv -p 3.9 --python-preference only-system -v 2>&1 | tee log.txt || true
|
|
# We should report that distutils is missing
|
|
grep 'Python installation is missing `distutils`' log.txt
|
|
|
|
- name: "Install distutils"
|
|
run: |
|
|
sudo apt-get install python3.9-distutils
|
|
|
|
- name: "Create a virtualenv"
|
|
run: |
|
|
./uv venv -p 3.9 --python-preference only-system -v
|
|
|
|
- name: "Check version"
|
|
run: |
|
|
.venv/bin/python --version
|
|
|
|
- name: "Check install"
|
|
run: |
|
|
./uv pip install -v anyio
|
|
|
|
integration-test-free-threaded-windows-x86_64:
|
|
timeout-minutes: 10
|
|
needs: build-binary-windows-x86_64
|
|
name: "integration test | free-threaded on windows"
|
|
runs-on: windows-latest
|
|
|
|
steps:
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-windows-x86_64-${{ github.sha }}
|
|
|
|
- name: "Install free-threaded Python via uv"
|
|
run: |
|
|
./uv python install -v 3.13t
|
|
|
|
- name: "Create a virtual environment (stdlib)"
|
|
run: |
|
|
& (./uv python find 3.13t) -m venv .venv
|
|
|
|
- name: "Check version (stdlib)"
|
|
run: |
|
|
.venv/Scripts/python --version
|
|
|
|
- name: "Create a virtual environment (uv)"
|
|
run: |
|
|
./uv venv -c -p 3.13t --managed-python
|
|
|
|
- name: "Check version (uv)"
|
|
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-windows-aarch64-implicit:
|
|
timeout-minutes: 10
|
|
needs: build-binary-windows-aarch64
|
|
name: "integration test | aarch64 windows implicit"
|
|
runs-on: windows-11-arm
|
|
|
|
steps:
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-windows-aarch64-${{ github.sha }}
|
|
|
|
- name: "Install Python via uv (implicitly select x64)"
|
|
run: |
|
|
./uv python install -v 3.13
|
|
|
|
- name: "Create a virtual environment (stdlib)"
|
|
run: |
|
|
& (./uv python find 3.13) -m venv .venv
|
|
|
|
- name: "Check version (stdlib)"
|
|
run: |
|
|
.venv/Scripts/python --version
|
|
|
|
- name: "Create a virtual environment (uv)"
|
|
run: |
|
|
./uv venv -c -p 3.13 --managed-python
|
|
|
|
- name: "Check version (uv)"
|
|
run: |
|
|
.venv/Scripts/python --version
|
|
|
|
- name: "Check is x64"
|
|
run: |
|
|
.venv/Scripts/python -c "import sys; exit(1) if 'AMD64' not in sys.version 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.13 python -c ""
|
|
|
|
integration-test-windows-aarch64-explicit:
|
|
timeout-minutes: 10
|
|
needs: build-binary-windows-aarch64
|
|
name: "integration test | aarch64 windows explicit"
|
|
runs-on: windows-11-arm
|
|
|
|
steps:
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-windows-aarch64-${{ github.sha }}
|
|
|
|
- name: "Install Python via uv (explicitly select aarch64)"
|
|
run: |
|
|
./uv python install -v cpython-3.13-windows-aarch64-none
|
|
|
|
- name: "Create a virtual environment (stdlib)"
|
|
run: |
|
|
& (./uv python find 3.13) -m venv .venv
|
|
|
|
- name: "Check version (stdlib)"
|
|
run: |
|
|
.venv/Scripts/python --version
|
|
|
|
- name: "Create a virtual environment (uv)"
|
|
run: |
|
|
./uv venv -c -p 3.13 --managed-python
|
|
|
|
- name: "Check version (uv)"
|
|
run: |
|
|
.venv/Scripts/python --version
|
|
|
|
- name: "Check is NOT x64"
|
|
run: |
|
|
.venv/Scripts/python -c "import sys; exit(1) if 'AMD64' in sys.version 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.13 python -c ""
|
|
|
|
integration-test-pypy-linux:
|
|
timeout-minutes: 10
|
|
needs: build-binary-linux-libc
|
|
name: "integration test | pypy on ubuntu"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-libc-${{ 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 --managed-python
|
|
|
|
- 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-x86_64:
|
|
timeout-minutes: 10
|
|
needs: build-binary-windows-x86_64
|
|
name: "integration test | pypy on windows"
|
|
runs-on: windows-latest
|
|
|
|
steps:
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-windows-x86_64-${{ github.sha }}
|
|
|
|
- name: "Install PyPy"
|
|
run: .\uv.exe python install pypy3.9
|
|
|
|
- name: "Create a virtual environment"
|
|
run: |
|
|
.\uv.exe venv -p pypy3.9 --managed-python
|
|
|
|
- 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"
|
|
run: |
|
|
.\uv.exe pip install anyio
|
|
|
|
integration-test-graalpy-linux:
|
|
timeout-minutes: 10
|
|
needs: build-binary-linux-libc
|
|
name: "integration test | graalpy on ubuntu"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-libc-${{ github.sha }}
|
|
|
|
- name: "Prepare binary"
|
|
run: chmod +x ./uv
|
|
|
|
- name: "Install GraalPy"
|
|
run: ./uv python install -v graalpy
|
|
|
|
- name: "Create a virtual environment"
|
|
run: |
|
|
./uv venv -p graalpy --managed-python
|
|
|
|
- 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-x86_64:
|
|
timeout-minutes: 10
|
|
needs: build-binary-windows-x86_64
|
|
name: "integration test | graalpy on windows"
|
|
runs-on: windows-latest
|
|
|
|
steps:
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-windows-x86_64-${{ github.sha }}
|
|
|
|
- name: "Install GraalPy"
|
|
run: .\uv.exe python install graalpy
|
|
|
|
- name: "Create a virtual environment"
|
|
run: |
|
|
.\uv.exe venv -p graalpy --managed-python
|
|
|
|
- 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"
|
|
run: |
|
|
.\uv.exe pip install anyio
|
|
|
|
integration-test-pyodide-linux:
|
|
timeout-minutes: 10
|
|
needs: build-binary-linux-libc
|
|
name: "integration test | pyodide on ubuntu"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-libc-${{ github.sha }}
|
|
|
|
- name: "Prepare binary"
|
|
run: chmod +x ./uv
|
|
|
|
- name: "Create a native virtual environment"
|
|
run: |
|
|
./uv venv venv-native -p 3.12
|
|
# We use features added in 0.30.3 but there is no known breakage in
|
|
# newer versions.
|
|
./uv pip install -p venv-native/bin/python pyodide-build==0.30.3 pip
|
|
|
|
- name: "Install pyodide interpreter"
|
|
run: |
|
|
source ./venv-native/bin/activate
|
|
pyodide xbuildenv install 0.27.5
|
|
PYODIDE_PYTHON=$(pyodide config get interpreter)
|
|
PYODIDE_INDEX=$(pyodide config get package_index)
|
|
echo "PYODIDE_PYTHON=$PYODIDE_PYTHON" >> $GITHUB_ENV
|
|
echo "PYODIDE_INDEX=$PYODIDE_INDEX" >> $GITHUB_ENV
|
|
|
|
- name: "Create pyodide virtual environment"
|
|
run: |
|
|
./uv venv -p $PYODIDE_PYTHON venv-pyodide
|
|
source ./venv-pyodide/bin/activate
|
|
./uv pip install --extra-index-url=$PYODIDE_INDEX --no-build numpy
|
|
python -c 'import numpy'
|
|
|
|
integration-test-github-actions:
|
|
timeout-minutes: 10
|
|
needs: build-binary-linux-libc
|
|
name: "integration test | github actions"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
with:
|
|
python-version: "3.12.7"
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-libc-${{ 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-github-actions-freethreaded:
|
|
timeout-minutes: 10
|
|
needs: build-binary-linux-libc
|
|
name: "integration test | free-threaded python on github actions"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
with:
|
|
python-version: "3.13t"
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-libc-${{ 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 but without free-threaded opt-in"
|
|
run: |
|
|
./uv pip install anyio --system --python 3.13 || echo "Failed as expected"
|
|
# (we need to request 3.13 or we'll discover 3.12 on the system)
|
|
|
|
- name: "Install a package with system and free-threaded opt-in"
|
|
run: |
|
|
./uv pip install anyio --system --python 3.13t
|
|
|
|
- name: "Create a virtual environment"
|
|
run: |
|
|
./uv venv -p 3.13t --python-preference only-system
|
|
|
|
- name: "Check is free-threaded"
|
|
run: |
|
|
.venv/bin/python -c "import sys; exit(1) if sys._is_gil_enabled() else exit(0)"
|
|
|
|
integration-test-publish-changed:
|
|
timeout-minutes: 10
|
|
needs: build-binary-linux-libc
|
|
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' && !contains(github.event.pull_request.labels.*.name, 'no-test')
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
# Only publish a new release if the publishing code changed
|
|
- name: "Determine changed files"
|
|
id: changed
|
|
shell: bash
|
|
run: |
|
|
CHANGED_FILES=$(git diff --name-only ${{ github.event.pull_request.base.sha || 'origin/main' }}...HEAD)
|
|
|
|
CODE_CHANGED=false
|
|
|
|
while IFS= read -r file; do
|
|
if [[ "${file}" =~ ^crates/uv-publish/ || "${file}" =~ ^scripts/publish/ || "${file}" == ".github/workflows/ci.yml" ]]; then
|
|
echo "Detected code change in: ${file}"
|
|
CODE_CHANGED=true
|
|
break
|
|
fi
|
|
|
|
echo "Skipping ${file} (not in watched paths)"
|
|
continue
|
|
|
|
done <<< "${CHANGED_FILES}"
|
|
echo "code_any_changed=${CODE_CHANGED}" >> "${GITHUB_OUTPUT}"
|
|
|
|
integration-test-registries:
|
|
timeout-minutes: 10
|
|
needs: build-binary-linux-libc
|
|
name: "integration test | registries"
|
|
runs-on: ubuntu-latest
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && github.event.pull_request.head.repo.fork != true }}
|
|
environment: uv-test-registries
|
|
env:
|
|
PYTHON_VERSION: 3.12
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
with:
|
|
python-version: "${{ env.PYTHON_VERSION }}"
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-libc-${{ github.sha }}
|
|
|
|
- name: "Prepare binary"
|
|
run: chmod +x ./uv
|
|
|
|
- name: "Configure AWS credentials"
|
|
uses: aws-actions/configure-aws-credentials@3d8cba388a057b13744d61818a337e40a119b1a7
|
|
with:
|
|
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
aws-region: us-east-1
|
|
|
|
- name: "Get AWS CodeArtifact token"
|
|
run: |
|
|
UV_TEST_AWS_TOKEN=$(aws codeartifact get-authorization-token \
|
|
--domain tests \
|
|
--domain-owner ${{ secrets.AWS_ACCOUNT_ID }} \
|
|
--region us-east-1 \
|
|
--query authorizationToken \
|
|
--output text)
|
|
echo "::add-mask::$UV_TEST_AWS_TOKEN"
|
|
echo "UV_TEST_AWS_TOKEN=$UV_TEST_AWS_TOKEN" >> $GITHUB_ENV
|
|
|
|
- name: "Authenticate with GCP"
|
|
id: "auth"
|
|
uses: "google-github-actions/auth@0920706a19e9d22c3d0da43d1db5939c6ad837a8"
|
|
with:
|
|
credentials_json: "${{ secrets.GCP_SERVICE_ACCOUNT_KEY }}"
|
|
|
|
- name: "Set up GCP SDK"
|
|
uses: "google-github-actions/setup-gcloud@a8b58010a5b2a061afd605f50e88629c9ec7536b"
|
|
|
|
- name: "Get GCP Artifact Registry token"
|
|
id: get_token
|
|
run: |
|
|
UV_TEST_GCP_TOKEN=$(gcloud auth print-access-token)
|
|
echo "::add-mask::$UV_TEST_GCP_TOKEN"
|
|
echo "UV_TEST_GCP_TOKEN=$UV_TEST_GCP_TOKEN" >> $GITHUB_ENV
|
|
|
|
- name: "Run registry tests"
|
|
run: ./uv run -p ${{ env.PYTHON_VERSION }} scripts/registries-test.py --uv ./uv --color always --all
|
|
env:
|
|
RUST_LOG: uv=debug
|
|
# UV_TEST_ARTIFACTORY_TOKEN: ${{ secrets.UV_TEST_ARTIFACTORY_TOKEN }}
|
|
# UV_TEST_ARTIFACTORY_URL: ${{ secrets.UV_TEST_ARTIFACTORY_URL }}
|
|
# UV_TEST_ARTIFACTORY_USERNAME: ${{ secrets.UV_TEST_ARTIFACTORY_USERNAME }}
|
|
UV_TEST_AWS_URL: ${{ secrets.UV_TEST_AWS_URL }}
|
|
UV_TEST_AWS_USERNAME: aws
|
|
UV_TEST_AZURE_TOKEN: ${{ secrets.UV_TEST_AZURE_TOKEN }}
|
|
UV_TEST_AZURE_URL: ${{ secrets.UV_TEST_AZURE_URL }}
|
|
UV_TEST_AZURE_USERNAME: dummy
|
|
UV_TEST_CLOUDSMITH_TOKEN: ${{ secrets.UV_TEST_CLOUDSMITH_TOKEN }}
|
|
UV_TEST_CLOUDSMITH_URL: ${{ secrets.UV_TEST_CLOUDSMITH_URL }}
|
|
UV_TEST_CLOUDSMITH_USERNAME: ${{ secrets.UV_TEST_CLOUDSMITH_USERNAME }}
|
|
UV_TEST_GCP_URL: ${{ secrets.UV_TEST_GCP_URL }}
|
|
UV_TEST_GCP_USERNAME: oauth2accesstoken
|
|
UV_TEST_GEMFURY_TOKEN: ${{ secrets.UV_TEST_GEMFURY_TOKEN }}
|
|
UV_TEST_GEMFURY_URL: ${{ secrets.UV_TEST_GEMFURY_URL }}
|
|
UV_TEST_GEMFURY_USERNAME: ${{ secrets.UV_TEST_GEMFURY_USERNAME }}
|
|
UV_TEST_GITLAB_TOKEN: ${{ secrets.UV_TEST_GITLAB_TOKEN }}
|
|
UV_TEST_GITLAB_URL: ${{ secrets.UV_TEST_GITLAB_URL }}
|
|
UV_TEST_GITLAB_USERNAME: token
|
|
|
|
integration-test-publish:
|
|
timeout-minutes: 20
|
|
needs: integration-test-publish-changed
|
|
name: "integration test | uv publish"
|
|
runs-on: ubuntu-latest
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
with:
|
|
python-version: "${{ env.PYTHON_VERSION }}"
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-libc-${{ github.sha }}
|
|
|
|
- name: "Prepare binary"
|
|
run: chmod +x ./uv
|
|
|
|
- name: "Build astral-test-pypa-gh-action"
|
|
run: |
|
|
# Build a yet unused version of `astral-test-pypa-gh-action`
|
|
mkdir astral-test-pypa-gh-action
|
|
cd astral-test-pypa-gh-action
|
|
../uv init --package
|
|
# Get the latest patch version
|
|
patch_version=$(curl https://test.pypi.org/simple/astral-test-pypa-gh-action/?format=application/vnd.pypi.simple.v1+json | jq --raw-output '.files[-1].filename' | sed 's/astral_test_pypa_gh_action-0\.1\.\([0-9]\+\)\.tar\.gz/\1/')
|
|
# Set the current version to one higher (which should be unused)
|
|
sed -i "s/0.1.0/0.1.$((patch_version + 1))/g" pyproject.toml
|
|
../uv build
|
|
|
|
- name: "Publish astral-test-pypa-gh-action"
|
|
uses: pypa/gh-action-pypi-publish@db8f07d3871a0a180efa06b95d467625c19d5d5f # release/v1
|
|
with:
|
|
# With this GitHub action, we can't do as rigid checks as with our custom Python script, so we publish more
|
|
# leniently
|
|
skip-existing: "true"
|
|
verbose: "true"
|
|
repository-url: "https://test.pypi.org/legacy/"
|
|
packages-dir: "astral-test-pypa-gh-action/dist"
|
|
|
|
- name: "Add password to keyring"
|
|
run: |
|
|
# `keyrings.alt` contains the plaintext keyring
|
|
./uv tool install --with keyrings.alt keyring
|
|
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 }}
|
|
|
|
integration-uv-build-backend:
|
|
timeout-minutes: 10
|
|
needs: build-binary-linux-libc
|
|
name: "integration test | uv_build"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
with:
|
|
python-version: "${{ env.PYTHON_VERSION }}"
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-libc-${{ github.sha }}
|
|
|
|
- name: "Prepare binary"
|
|
run: |
|
|
chmod +x ./uv
|
|
chmod +x ./uvx
|
|
|
|
- name: "Test uv_build package"
|
|
run: |
|
|
# Build the Python package, which is not covered by uv's integration tests since they can't depend on having
|
|
# a Python package (only the binary itself is built before running Rust's tests)
|
|
./uv build -v crates/uv-build
|
|
|
|
# Test the main path (`build_wheel`) through pip
|
|
./uv venv -v --seed
|
|
./uv run --no-project python -m pip install -v scripts/packages/built-by-uv --find-links crates/uv-build/dist --no-index --no-deps
|
|
./uv run --no-project python -c "from built_by_uv import greet; print(greet())"
|
|
|
|
# Test both `build_wheel` and `build_sdist` through uv
|
|
./uv venv -c -v
|
|
./uv build -v --force-pep517 scripts/packages/built-by-uv --find-links crates/uv-build/dist --offline
|
|
./uv pip install -v scripts/packages/built-by-uv/dist/*.tar.gz --find-links crates/uv-build/dist --offline --no-deps
|
|
./uv run --no-project python -c "from built_by_uv import greet; print(greet())"
|
|
|
|
# Test both `build_wheel` and `build_sdist` through the official `build`
|
|
rm -rf scripts/packages/built-by-uv/dist/
|
|
./uv venv -c -v
|
|
./uv pip install build
|
|
# Add the uv binary to PATH for `build` to find
|
|
PATH="$(pwd):$PATH" UV_OFFLINE=1 UV_FIND_LINKS=crates/uv-build/dist ./uv run --no-project python -m build -v --installer uv scripts/packages/built-by-uv
|
|
./uv pip install -v scripts/packages/built-by-uv/dist/*.tar.gz --find-links crates/uv-build/dist --offline --no-deps
|
|
./uv run --no-project python -c "from built_by_uv import greet; print(greet())"
|
|
|
|
cache-test-ubuntu:
|
|
timeout-minutes: 10
|
|
needs: build-binary-linux-libc
|
|
name: "check cache | ubuntu"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
with:
|
|
python-version: "3.12"
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-libc-${{ 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 # github-macos-14-aarch64-3
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
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-musl
|
|
name: "check system | python on debian"
|
|
runs-on: ubuntu-latest
|
|
container: debian:bookworm
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- 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@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-musl-${{ 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-libc
|
|
name: "check system | python on fedora"
|
|
runs-on: ubuntu-latest
|
|
container: fedora:43
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- 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-${{ 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-libc
|
|
name: "check system | python on ubuntu"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
with:
|
|
python-version: "3.12"
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-libc-${{ 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
|
|
|
|
# Currently failing, see https://github.com/astral-sh/uv/issues/13811
|
|
# system-test-opensuse:
|
|
# timeout-minutes: 5
|
|
# needs: build-binary-linux-libc
|
|
# name: "check system | 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-${{ 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-musl
|
|
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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- 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@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-musl-${{ 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-graalpy:
|
|
timeout-minutes: 10
|
|
needs: build-binary-linux-libc
|
|
name: "check system | graalpy on ubuntu"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
with:
|
|
python-version: "graalpy24.1"
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-libc-${{ github.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
|
|
needs: build-binary-linux-libc
|
|
name: "check system | pypy on ubuntu"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
with:
|
|
python-version: "pypy3.9"
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-libc-${{ 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-musl
|
|
name: "check system | pyston"
|
|
runs-on: ubuntu-latest
|
|
container: pyston/pyston:2.3.5
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-linux-musl-${{ 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-musl
|
|
name: "check system | alpine"
|
|
runs-on: ubuntu-latest
|
|
container: alpine:latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- 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-${{ 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 # github-macos-14-aarch64-3
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
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 # github-macos-14-aarch64-3
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: "Install Python"
|
|
run: brew install python3
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
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 # github-macos-13-x86_64-4
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
# We test with GitHub's Python as a regression test for
|
|
# https://github.com/astral-sh/uv/issues/2450
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
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-x86_64
|
|
name: "check system | python3.10 on windows x86-64"
|
|
runs-on: windows-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
with:
|
|
python-version: "3.10"
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-windows-x86_64-${{ 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_64-python-310:
|
|
timeout-minutes: 10
|
|
needs: build-binary-windows-x86_64
|
|
name: "check system | python3.10 on windows x86"
|
|
runs-on: windows-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.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-${{ 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-x86_64-python-313:
|
|
timeout-minutes: 10
|
|
needs: build-binary-windows-x86_64
|
|
name: "check system | python3.13 on windows x86-64"
|
|
runs-on: windows-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.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-${{ 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-windows-aarch64-x86-python-313:
|
|
timeout-minutes: 10
|
|
needs: build-binary-windows-aarch64
|
|
name: "check system | x86-64 python3.13 on windows aarch64"
|
|
runs-on: windows-11-arm
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.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-${{ github.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
|
|
needs: build-binary-windows-aarch64
|
|
name: "check system | aarch64 python3.13 on windows aarch64"
|
|
runs-on: windows-11-arm
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.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-${{ github.sha }}
|
|
|
|
- name: "Validate global Python install"
|
|
run: py -3.13 ./scripts/check_system_python.py --uv ./uv.exe
|
|
|
|
# Test our PEP 514 integration that installs Python into the Windows registry.
|
|
system-test-windows-registry:
|
|
timeout-minutes: 10
|
|
needs: build-binary-windows-x86_64
|
|
name: "check system | windows registry"
|
|
runs-on: windows-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-windows-x86_64-${{ github.sha }}
|
|
|
|
# NB: Run this last, we are modifying the registry
|
|
- name: "Test PEP 514 registration"
|
|
run: python ./scripts/check_registry.py --uv ./uv.exe
|
|
|
|
system-test-choco:
|
|
timeout-minutes: 10
|
|
needs: build-binary-windows-x86_64
|
|
name: "check system | python3.12 via chocolatey"
|
|
runs-on: windows-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: "Install Python"
|
|
run: choco install python3 --verbose --version=3.9.13
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-windows-x86_64-${{ 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-libc
|
|
name: "check system | python3.9 via pyenv"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- 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-${{ 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-libc
|
|
name: "check system | python3.13"
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.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-${{ 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-x86_64,
|
|
build-binary-macos-aarch64,
|
|
build-binary-linux-libc,
|
|
]
|
|
name: check system | 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- 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 }}-${{ 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}
|
|
run: python ./scripts/check_system_python.py --uv ./uv
|
|
|
|
system-test-amazonlinux:
|
|
timeout-minutes: 10
|
|
needs: build-binary-linux-musl
|
|
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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
- 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-${{ 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-x86_64
|
|
name: "check system | embedded python3.10 on windows x86-64"
|
|
runs-on: windows-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: "Download binary"
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: uv-windows-x86_64-${{ 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-walltime:
|
|
name: "benchmarks | walltime aarch64 linux"
|
|
runs-on: codspeed-macro
|
|
needs: determine_changes
|
|
if: ${{ github.repository == 'astral-sh/uv' && !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
timeout-minutes: 20
|
|
steps:
|
|
- name: "Checkout Branch"
|
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
|
|
- name: "Install codspeed"
|
|
uses: taiki-e/install-action@7b20dfd705618832f20d29066e34aa2f2f6194c2 # v2.52.8
|
|
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@0010eb0ca6e89b80c88e8edaaa07cfe5f3e6664d # v3.5.0
|
|
with:
|
|
run: cargo codspeed run
|
|
token: ${{ secrets.CODSPEED_TOKEN }}
|
|
|
|
benchmarks-instrumented:
|
|
name: "benchmarks | instrumented"
|
|
runs-on: ubuntu-latest
|
|
needs: determine_changes
|
|
if: ${{ github.repository == 'astral-sh/uv' && !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
timeout-minutes: 20
|
|
steps:
|
|
- name: "Checkout Branch"
|
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
|
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
|
|
- name: "Install codspeed"
|
|
uses: taiki-e/install-action@7b20dfd705618832f20d29066e34aa2f2f6194c2 # v2.52.8
|
|
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@0010eb0ca6e89b80c88e8edaaa07cfe5f3e6664d # v3.5.0
|
|
with:
|
|
run: cargo codspeed run
|
|
token: ${{ secrets.CODSPEED_TOKEN }}
|