diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0f2248890df4..e66d4e61e7de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -526,7 +526,7 @@ jobs: path: ./target/debug/uv retention-days: 1 - build-binary-windows: + build-binary-windows-x86_64: needs: determine_changes timeout-minutes: 10 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') }} @@ -555,10 +555,83 @@ jobs: - name: "Upload binary" uses: actions/upload-artifact@v4 with: - name: uv-windows-${{ github.sha }} + name: uv-windows-x86_64-${{ github.sha }} path: ${{ env.UV_WORKSPACE }}/target/debug/uv.exe retention-days: 1 + build-binary-windows-aarch64: + needs: determine_changes + timeout-minutes: 30 + 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') }} + runs-on: + labels: github-windows-11-aarch64-4 + name: "build binary | windows aarch64" + steps: + - name: Download LLVM (aarch64) + uses: robinraju/release-downloader@v1 + with: + repository: "llvm/llvm-project" + tag: "llvmorg-19.1.5" + filename: "LLVM-19.1.5-woa64.exe" + + - name: Install LLVM (aarch64) + run: | + Start-Process -FilePath "LLVM-19.1.5-woa64.exe" -ArgumentList '/S' -NoNewWindow -Wait + + - name: Install Build Tools (aarch64) + run: | + Set-ExecutionPolicy Bypass -Scope Process -Force + [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072 + iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) + Add-Content -Path $env:GITHUB_PATH -Value "C:\ProgramData\chocolatey\bin" -Encoding utf8 + choco install visualstudio2022buildtools -y --no-progress --package-parameters "--add Microsoft.VisualStudio.Component.VC.Tools.ARM64 --add Microsoft.VisualStudio.Component.Windows11SDK.22621 --add Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Llvm.Clang --add Microsoft.VisualStudio.Component.VC.CMake.Project" + choco cache list -v + + - name: Add clang to PATH and check if clang exists + run: | + $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\Llvm\bin" + Add-Content -Path $env:GITHUB_PATH -Value "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\Llvm\bin" -Encoding utf8 + clang --version + + - name: Add cmake to PATH and check if cmake exists + run: | + $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\" + Add-Content -Path $env:GITHUB_PATH -Value "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin" -Encoding utf8 + cmake --version + + - name: Install Nightly Rust (aarch64) + run: | + Add-Content -Path $env:GITHUB_PATH -Value "$env:USERPROFILE\.cargo\bin" -Encoding utf8 + Invoke-WebRequest -Uri "https://win.rustup.rs/aarch64" -OutFile "$env:RUNNER_TEMP\rustup-init.exe" + & "$env:RUNNER_TEMP\rustup-init.exe" --default-host aarch64-pc-windows-msvc --default-toolchain nightly -y + + - name: Download Git for Windows (aarch64) + uses: robinraju/release-downloader@v1 + with: + repository: "git-for-windows/git" + tag: "v2.48.0-rc1.windows.1" + filename: "Git-2.48.0-rc1-arm64.exe" + + - name: Install Git for Windows (aarch64) + run: | + Start-Process -FilePath "Git-2.48.0-rc1-arm64.exe" -ArgumentList "/VERYSILENT" -NoNewWindow -Wait + Add-Content -Path $env:GITHUB_PATH -Value "C:\Program Files\Git\cmd" -Encoding utf8 + Add-Content -Path $env:GITHUB_PATH -Value "C:\Program Files\Git\bin" -Encoding utf8 + + - uses: actions/checkout@v4 + + - uses: Swatinem/rust-cache@v2 + + - name: "Build" + run: $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\Llvm\bin"; $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\"; cargo build --target aarch64-pc-windows-msvc + + - name: "Upload binary" + uses: actions/upload-artifact@v4 + with: + name: uv-windows-aarch64-${{ github.sha }} + path: target/aarch64-pc-windows-msvc/debug/uv.exe + retention-days: 1 + cargo-build-msrv: name: "cargo build (msrv)" needs: determine_changes @@ -749,9 +822,9 @@ jobs: run: | ./uv pip install -v anyio - integration-test-free-threaded-windows: + integration-test-free-threaded-windows-x86_64: timeout-minutes: 10 - needs: build-binary-windows + needs: build-binary-windows-x86_64 name: "integration test | free-threaded on windows" runs-on: windows-latest env: @@ -762,7 +835,55 @@ jobs: - name: "Download binary" uses: actions/download-artifact@v4 with: - name: uv-windows-${{ github.sha }} + 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 --python-preference only-managed + + - 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-free-threaded-windows-aarch64: + timeout-minutes: 10 + needs: build-binary-windows-aarch64 + name: "integration test | free-threaded on windows" + runs-on: github-windows-11-aarch64-4 + env: + # Avoid debug build stack overflows. + UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows + + steps: + - name: "Download binary" + uses: actions/download-artifact@v4 + with: + name: uv-windows-aarch64-${{ github.sha }} - name: "Install free-threaded Python via uv" run: | @@ -797,6 +918,7 @@ jobs: ./uv run python -c "" ./uv run -p 3.13t python -c "" + integration-test-pypy-linux: timeout-minutes: 10 needs: build-binary-linux @@ -861,9 +983,9 @@ jobs: run: | ./uv pip install anyio - integration-test-pypy-windows: + integration-test-pypy-windows-x86_64: timeout-minutes: 10 - needs: build-binary-windows + needs: build-binary-windows-x86_64 name: "integration test | pypy on windows" runs-on: windows-latest @@ -871,7 +993,70 @@ jobs: - name: "Download binary" uses: actions/download-artifact@v4 with: - name: uv-windows-${{ github.sha }} + 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 --python-preference only-managed + + - name: "Check for executables" + shell: python + run: | + import sys + from pathlib import Path + + def binary_exist(binary): + binaries_path = Path(".venv\\Scripts") + if (binaries_path / binary).exists(): + return True + print(f"Executable '{binary}' not found in folder '{binaries_path}'.") + + all_found = True + expected_binaries = [ + "pypy3.9.exe", + "pypy3.9w.exe", + "pypy3.exe", + "pypyw.exe", + "python.exe", + "python3.9.exe", + "python3.exe", + "pythonw.exe", + ] + for binary in expected_binaries: + if not binary_exist(binary): + all_found = False + + if not all_found: + print("One or more expected executables were not found.") + sys.exit(1) + + - name: "Check version" + run: | + & .venv\Scripts\pypy3.9.exe --version + & .venv\Scripts\pypy3.exe --version + & .venv\Scripts\python.exe --version + + - name: "Check install" + env: + # Avoid debug build stack overflows. + UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows + run: | + .\uv.exe pip install anyio + + integration-test-pypy-windows-aarch64: + timeout-minutes: 10 + needs: build-binary-windows-aarch64 + name: "integration test | pypy on windows" + runs-on: github-windows-11-aarch64-4 + + steps: + - name: "Download binary" + uses: actions/download-artifact@v4 + with: + name: uv-windows-aarch64-${{ github.sha }} - name: "Install PyPy" run: .\uv.exe python install pypy3.9 @@ -993,9 +1178,9 @@ jobs: run: | ./uv pip install anyio - integration-test-graalpy-windows: + integration-test-graalpy-windows-x86_64: timeout-minutes: 10 - needs: build-binary-windows + needs: build-binary-windows-x86_64 name: "integration test | graalpy on windows" runs-on: windows-latest @@ -1007,7 +1192,70 @@ jobs: - name: "Download binary" uses: actions/download-artifact@v4 with: - name: uv-windows-${{ github.sha }} + name: uv-windows-x86_64-${{ github.sha }} + + - name: Graalpy info + run: Get-Command graalpy + + - name: "Create a virtual environment" + run: | + $graalpy = (Get-Command graalpy).source + .\uv.exe venv -p $graalpy + + - name: "Check for executables" + shell: python + run: | + import sys + from pathlib import Path + + def binary_exist(binary): + binaries_path = Path(".venv\\Scripts") + if (binaries_path / binary).exists(): + return True + print(f"Executable '{binary}' not found in folder '{binaries_path}'.") + + all_found = True + expected_binaries = [ + "graalpy.exe", + "python.exe", + "python3.exe", + ] + for binary in expected_binaries: + if not binary_exist(binary): + all_found = False + + if not all_found: + print("One or more expected executables were not found.") + sys.exit(1) + + - name: "Check version" + run: | + & .venv\Scripts\graalpy.exe --version + & .venv\Scripts\python3.exe --version + & .venv\Scripts\python.exe --version + + - name: "Check install" + env: + # Avoid debug build stack overflows. + UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows + run: | + .\uv.exe pip install anyio + + integration-test-graalpy-windows-aarch64: + timeout-minutes: 10 + needs: build-binary-windows-aarch64 + name: "integration test | graalpy on windows" + runs-on: github-windows-11-aarch64-4 + + steps: + - uses: timfel/setup-python@fc9bcb4a04f5b1ea7d678c2ca7ea1c479a2468d7 + with: + python-version: "graalpy24.1" + + - name: "Download binary" + uses: actions/download-artifact@v4 + with: + name: uv-windows-aarch64-${{ github.sha }} - name: Graalpy info run: Get-Command graalpy @@ -1541,8 +1789,8 @@ jobs: system-test-windows-python-310: timeout-minutes: 10 - needs: build-binary-windows - name: "check system | python3.10 on windows" + needs: build-binary-windows-x86_64 + name: "check system | python3.10 on windows x86_64" runs-on: windows-latest env: # Avoid debug build stack overflows. @@ -1557,7 +1805,33 @@ jobs: - name: "Download binary" uses: actions/download-artifact@v4 with: - name: uv-windows-${{ github.sha }} + 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-python-310-aarch64: + timeout-minutes: 10 + needs: build-binary-windows-aarch64 + name: "check system | python3.10 on windows aarch64" + runs-on: github-windows-11-aarch64-4 + env: + # Avoid debug build stack overflows. + UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: "Download binary" + uses: actions/download-artifact@v4 + with: + name: uv-windows-aarch64-${{ github.sha }} - name: "Print Python path" run: echo $(which python) @@ -1567,7 +1841,7 @@ jobs: system-test-windows-x86-python-310: timeout-minutes: 10 - needs: build-binary-windows + needs: build-binary-windows-x86_64 name: "check system | python3.10 on windows x86" runs-on: windows-latest env: @@ -1584,18 +1858,45 @@ jobs: - name: "Download binary" uses: actions/download-artifact@v4 with: - name: uv-windows-${{ github.sha }} + 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-aarch64-python-310: + timeout-minutes: 10 + needs: build-binary-windows-aarch64 + name: "check system | python3.10 on windows aarch64" + runs-on: github-windows-11-aarch64-4 + env: + # Avoid debug build stack overflows. + UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows + steps: + - uses: actions/checkout@v4 - system-test-windows-python-313: + - uses: actions/setup-python@v5 + with: + python-version: "3.10" + architecture: "aarch64" + + - name: "Download binary" + uses: actions/download-artifact@v4 + with: + name: uv-windows-aarch64-${{ 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 - name: "check system | python3.13 on windows" + needs: build-binary-windows-x86_64 + name: "check system | python3.13 on windows x86_64" runs-on: windows-latest env: # Avoid debug build stack overflows. @@ -1612,7 +1913,35 @@ jobs: - name: "Download binary" uses: actions/download-artifact@v4 with: - name: uv-windows-${{ github.sha }} + 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-python-313: + timeout-minutes: 10 + needs: build-binary-windows-aarch64 + name: "check system | python3.13 on windows aarch64" + runs-on: github-windows-11-aarch64-4 + env: + # Avoid debug build stack overflows. + UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.13" + allow-prereleases: true + cache: pip + + - name: "Download binary" + uses: actions/download-artifact@v4 + with: + name: uv-windows-aarch64-${{ github.sha }} - name: "Print Python path" run: echo $(which python) @@ -1622,7 +1951,7 @@ jobs: system-test-choco: timeout-minutes: 10 - needs: build-binary-windows + needs: build-binary-windows-x86_64 name: "check system | python3.12 via chocolatey" runs-on: windows-latest env: @@ -1637,7 +1966,7 @@ jobs: - name: "Download binary" uses: actions/download-artifact@v4 with: - name: uv-windows-${{ github.sha }} + name: uv-windows-x86_64-${{ github.sha }} - name: "Print Python path" run: echo $(which python3) @@ -1645,6 +1974,32 @@ jobs: - name: "Validate global Python install" run: py -3.9 ./scripts/check_system_python.py --uv ./uv.exe + system-test-choco-aarch64: + timeout-minutes: 10 + needs: build-binary-windows-aarch64 + name: "check system | python3.12 via chocolatey" + runs-on: github-windows-11-aarch64-4 + env: + # Avoid debug build stack overflows. + UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows + steps: + - uses: actions/checkout@v4 + + - name: "Install Python" + run: choco install python3 --verbose --version=3.9.13 + + - name: "Download binary" + uses: actions/download-artifact@v4 + with: + name: uv-windows-aarch64-${{ 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 @@ -1716,7 +2071,7 @@ jobs: system-test-conda: timeout-minutes: 10 needs: - [build-binary-windows, build-binary-macos-aarch64, build-binary-linux] + [build-binary-windows-x86_64, build-binary-windows-aarch64, build-binary-macos-aarch64, build-binary-linux] name: check system | conda${{ matrix.python-version }} on ${{ matrix.os }} runs-on: ${{ matrix.runner }} strategy: @@ -1726,7 +2081,8 @@ jobs: python-version: ["3.8", "3.11"] include: - { os: "linux", target: "linux", runner: "ubuntu-latest" } - - { os: "windows", target: "windows", runner: "windows-latest" } + - { os: "windows", target: "windows-x86_64", runner: "windows-latest" } + - { os: "windows", target: "windows-aarch64", runner: "github-windows-11-aarch64-4" } - { os: "macos", target: "macos-aarch64", runner: "macos-14" } steps: - uses: actions/checkout@v4 @@ -1796,8 +2152,8 @@ jobs: system-test-windows-embedded-python-310: timeout-minutes: 10 - needs: build-binary-windows - name: "check system | embedded python3.10 on windows" + needs: build-binary-windows-x86_64 + name: "check system | embedded python3.10 on windows x86_64" runs-on: windows-latest env: # Avoid debug build stack overflows. @@ -1808,7 +2164,7 @@ jobs: - name: "Download binary" uses: actions/download-artifact@v4 with: - name: uv-windows-${{ github.sha }} + name: uv-windows-x86_64-${{ github.sha }} # Download embedded Python. - name: "Download embedded Python" @@ -1829,6 +2185,41 @@ jobs: - name: "Validate embedded Python install" run: python ./scripts/check_embedded_python.py --uv ./uv.exe + system-test-windows-embedded-python-310-aarch64: + timeout-minutes: 10 + needs: build-binary-windows-aarch64 + name: "check system | embedded python3.10 on windows aarch64" + runs-on: github-windows-11-aarch64-4 + env: + # Avoid debug build stack overflows. + UV_STACK_SIZE: 3000000 # 3 megabyte, triple the default on windows + steps: + - uses: actions/checkout@v4 + + - name: "Download binary" + uses: actions/download-artifact@v4 + with: + name: uv-windows-aarch64-${{ 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-arm64.zip -o python-3.11.8-embed-arm64.zip + + - name: "Unzip embedded Python" + run: 7z x python-3.11.8-embed-arm64.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 "${{ github.workspace }}\embedded-python" >> $env:GITHUB_PATH; echo $(which python) + + - name: "Validate embedded Python install" + run: echo "${{ github.workspace }}\embedded-python" >> $env:GITHUB_PATH; python ./scripts/check_embedded_python.py --uv ./uv.exe + benchmarks: runs-on: ubuntu-latest needs: determine_changes