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@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/configuration/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@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0 - 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@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 with: save-if: ${{ github.ref == 'refs/heads/main' }} - name: "Check uv_build dependencies" uses: EmbarkStudios/cargo-deny-action@34899fc7ba81ca6268d5947a7a16b4649013fea1 # v2.0.11 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@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 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@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 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@ab3728c7ba6948b9b429627f4d55a68842b27f18 # v2.50.3 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@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 - name: "Install Rust toolchain" run: rustup show - uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0 - name: "Install required Python versions" run: uv python install - name: "Install cargo nextest" uses: taiki-e/install-action@ab3728c7ba6948b9b429627f4d55a68842b27f18 # v2.50.3 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: 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-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@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 - name: "Install Rust toolchain" run: rustup show - uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0 - name: "Install required Python versions" run: uv python install - name: "Install cargo nextest" uses: taiki-e/install-action@ab3728c7ba6948b9b429627f4d55a68842b27f18 # v2.50.3 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: github-windows-2025-x86_64-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@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0 - name: "Install required Python versions" run: uv python install - uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 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@ab3728c7ba6948b9b429627f4d55a68842b27f18 # v2.50.3 with: tool: cargo-nextest # Get crash dumps to debug the `exit_code: -1073741819` failures - name: Configure crash dumps if: runner.os == 'Windows' shell: powershell run: | $dumps = "$env:GITHUB_WORKSPACE\dumps" New-Item -Path $dumps -ItemType Directory -Force # https://github.com/microsoft/terminal/wiki/Troubleshooting-Tips#capture-automatically $reg = "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" New-Item -Path $reg -Force | Out-Null Set-ItemProperty -Path $reg -Name "DumpFolder" -Value $dumps Set-ItemProperty -Path $reg -Name "DumpType" -Value 2 - name: "Cargo test" id: test continue-on-error: true 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 # Get crash dumps to debug the `exit_code: -1073741819` failures (contd.) - name: Analyze crashes if: steps.test.outcome == 'failure' shell: powershell run: | $dumps = Get-ChildItem "$env:GITHUB_WORKSPACE\dumps\*.dmp" -ErrorAction SilentlyContinue if (!$dumps) { exit 0 } Write-Host "Found $($dumps.Count) crash dump(s)" # Download cdb if needed $cdb = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe" if (!(Test-Path $cdb)) { # https://github.com/microsoft/react-native-windows/blob/f1570a5ef1c4fc1e78d0a0ad5af848ab91a4061c/vnext/Scripts/Analyze-Crash.ps1#L44-L56 Invoke-WebRequest "https://go.microsoft.com/fwlink/?linkid=2173743" -OutFile "$env:TEMP\sdk.exe" Start-Process "$env:TEMP\sdk.exe" -ArgumentList "/features OptionId.WindowsDesktopDebuggers /quiet" -Wait } # Analyze each dump foreach ($dump in $dumps) { Write-Host "`n=== $($dump.Name) ===" & $cdb -z $dump -c "!analyze -v; .ecxr; k; q" 2>&1 | Select-String -Pattern "(ExceptionCode:|SYMBOL_NAME:|IMAGE_NAME:|STACK_TEXT:)" -Context 0,2 } - name: Upload crash dumps if: steps.test.outcome == 'failure' uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: crash-dumps-${{ github.run_number }} path: dumps/*.dmp if-no-files-found: ignore - name: Fail if tests failed if: steps.test.outcome == 'failure' run: exit 1 # 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@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 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@ab3728c7ba6948b9b429627f4d55a68842b27f18 # v2.50.3 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@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 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@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0 - 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@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 - 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@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 - 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@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 - 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@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 - 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@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 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@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 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@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 - 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@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 - 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@49738581fe238ad84ae7dd26f69f3960252f6994 # v0.4.0 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 < $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: github-windows-11-aarch64-4 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@505e6394dae86d6a5c7fbb6e3fb8938e3e863830 # v3.1.1 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 -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-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-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-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 -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 -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 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: github-windows-11-aarch64-4 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 # 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@505e6394dae86d6a5c7fbb6e3fb8938e3e863830 # v3.1.1 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: 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@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 - name: "Install Rust toolchain" run: rustup show - name: "Install codspeed" uses: taiki-e/install-action@ab3728c7ba6948b9b429627f4d55a68842b27f18 # v2.50.3 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 }}