A minimal build backend for uv: uv_build (#11446)

uv itself is a large package with many dependencies and lots of
features. To build a package using the uv build backend, you shouldn't
have to download and install the entirety of uv. For platform where we
don't provide wheels, it should be possible and fast to compile the uv
build backend. To that end, we're introducing a python package that
contains a trimmed down version of uv that only contains the build
backend, with a minimal dependency tree in rust.

The `uv_build` package is publish from CI just like uv itself. It is
part of the workspace, but has much less dependencies for its own
binary. We're using cargo deny to enforce that the network stack is not
part of the dependencies. A new build profile ensure we're getting the
minimum possible binary size for a rust binary.

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
This commit is contained in:
konsti
2025-03-06 20:27:20 +01:00
committed by GitHub
parent d4a805544f
commit bf4c7afe8b
26 changed files with 842 additions and 96 deletions

View File

@@ -19,6 +19,8 @@ on:
- pyproject.toml
- Cargo.toml
- .cargo/config.toml
- crates/uv-build/Cargo.toml
- crates/uv-build/pyproject.toml
# Toolchain or dependency versions
- Cargo.lock
- rust-toolchain.toml
@@ -47,6 +49,8 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
# uv
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
- name: "Build sdist"
@@ -65,9 +69,26 @@ jobs:
- name: "Upload sdist"
uses: actions/upload-artifact@v4
with:
name: wheels-sdist
name: wheels_uv-sdist
path: dist
# uv-build
- name: "Build sdist uv-build"
uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out crates/uv-build/dist -m crates/uv-build/Cargo.toml
- name: "Test sdist uv-build"
run: |
pip install crates/uv-build/dist/${{ env.PACKAGE_NAME }}_build-*.tar.gz --force-reinstall
${{ env.MODULE_NAME }}-build --help
python -m ${{ env.MODULE_NAME }}_build --help
- name: "Upload sdist uv-build"
uses: actions/upload-artifact@v4
with:
name: wheels_uv_build-sdist
path: crates/uv-build/dist
macos-x86_64:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
runs-on: macos-14
@@ -79,6 +100,8 @@ jobs:
architecture: x64
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
# uv
- name: "Build wheels - x86_64"
uses: PyO3/maturin-action@v1
with:
@@ -108,6 +131,18 @@ jobs:
*.tar.gz
*.sha256
# uv-build
- name: "Build wheels uv-build - x86_64"
uses: PyO3/maturin-action@v1
with:
target: x86_64
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml
- name: "Upload wheels uv-build"
uses: actions/upload-artifact@v4
with:
name: wheels_uv_build-macos-x86_64
path: crates/uv-build/dist
macos-aarch64:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
runs-on: macos-14
@@ -119,6 +154,8 @@ jobs:
architecture: arm64
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
# uv
- name: "Build wheels - aarch64"
uses: PyO3/maturin-action@v1
with:
@@ -154,6 +191,23 @@ jobs:
*.tar.gz
*.sha256
# uv-build
- name: "Build wheels uv-build - aarch64"
uses: PyO3/maturin-action@v1
with:
target: aarch64
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml
- name: "Test wheel - aarch64"
run: |
pip install ${{ env.PACKAGE_NAME }}_build --no-index --find-links crates/uv-build/dist --force-reinstall
${{ env.MODULE_NAME }}-build --help
python -m ${{ env.MODULE_NAME }}_build --help
- name: "Upload wheels uv-build"
uses: actions/upload-artifact@v4
with:
name: wheels_uv_build-aarch64-apple-darwin
path: crates/uv-build/dist
windows:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
runs-on: github-windows-2022-x86_64-8
@@ -174,6 +228,8 @@ jobs:
architecture: ${{ matrix.platform.arch }}
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
# uv
- name: "Build wheels"
uses: PyO3/maturin-action@v1
with:
@@ -190,7 +246,7 @@ jobs:
- name: "Upload wheels"
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.platform.target }}
name: wheels_uv-${{ matrix.platform.target }}
path: dist
- name: "Archive binary"
shell: bash
@@ -207,6 +263,25 @@ jobs:
*.zip
*.sha256
# uv-build
- name: "Build wheels uv-build"
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml
- name: "Test wheel uv-build"
if: ${{ !startsWith(matrix.platform.target, 'aarch64') }}
shell: bash
run: |
pip install ${{ env.PACKAGE_NAME }}_build --no-index --find-links crates/uv-build/dist --force-reinstall
${{ env.MODULE_NAME }}-build --help
python -m ${{ env.MODULE_NAME }}_build --help
- name: "Upload wheels uv-build"
uses: actions/upload-artifact@v4
with:
name: wheels_uv_build-${{ matrix.platform.target }}
path: crates/uv-build/dist
linux:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
runs-on: depot-ubuntu-latest-4
@@ -223,6 +298,8 @@ jobs:
architecture: x64
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
# uv
- name: "Build wheels"
# Use patch for https://github.com/PyO3/maturin-action/issues/331
uses: PyO3/maturin-action@711bb9fcefaea0b45a7d625ee2c265fd9fe7f3e5
@@ -255,13 +332,11 @@ jobs:
- name: "Upload wheels"
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.target }}
name: wheels_uv-${{ matrix.target }}
path: dist
- name: "Archive binary"
shell: bash
run: |
set -euo pipefail
TARGET=${{ matrix.target }}
ARCHIVE_NAME=uv-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
@@ -279,9 +354,29 @@ jobs:
*.tar.gz
*.sha256
# uv-build
- name: "Build wheels uv-build"
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
manylinux: auto
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml
- name: "Test wheel uv-build"
if: ${{ startsWith(matrix.target, 'x86_64') }}
run: |
pip install ${{ env.PACKAGE_NAME }}_build --no-index --find-links crates/uv-build/dist --force-reinstall
${{ env.MODULE_NAME }}-build --help
python -m ${{ env.MODULE_NAME }}_build --help
- name: "Upload wheels uv-build"
uses: actions/upload-artifact@v4
with:
name: wheels_uv_build-${{ matrix.target }}
path: crates/uv-build/dist
linux-arm:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
matrix:
platform:
@@ -302,6 +397,8 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
# uv
- name: "Build wheels"
uses: PyO3/maturin-action@v1
with:
@@ -329,13 +426,11 @@ jobs:
- name: "Upload wheels"
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.platform.target }}
name: wheels_uv-${{ matrix.platform.target }}
path: dist
- name: "Archive binary"
shell: bash
run: |
set -euo pipefail
TARGET=${{ matrix.platform.target }}
ARCHIVE_NAME=uv-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
@@ -353,9 +448,40 @@ jobs:
*.tar.gz
*.sha256
# uv-build
- name: "Build wheels uv-build"
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
# On `aarch64`, use `manylinux: 2_28`; otherwise, use `manylinux: auto`.
manylinux: ${{ matrix.platform.arch == 'aarch64' && '2_28' || 'auto' }}
docker-options: ${{ matrix.platform.maturin_docker_options }}
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml
- uses: uraimo/run-on-arch-action@v2
name: "Test wheel uv-build"
with:
arch: ${{ matrix.platform.arch == 'arm' && 'armv6' || matrix.platform.arch }}
distro: ${{ matrix.platform.arch == 'arm' && 'bullseye' || 'ubuntu20.04' }}
githubToken: ${{ github.token }}
install: |
apt-get update
apt-get install -y --no-install-recommends python3 python3-pip python-is-python3
pip3 install -U pip
run: |
pip install ${{ env.PACKAGE_NAME }}_build --no-index --find-links crates/uv-build/dist --force-reinstall
${{ env.MODULE_NAME }}-build --help
# TODO(konsti): Enable this test on all platforms, currently `find_uv_bin` is failing to discover uv here.
# python -m ${{ env.MODULE_NAME }}_build --help
- name: "Upload wheels uv-build"
uses: actions/upload-artifact@v4
with:
name: wheels_uv_build-${{ matrix.platform.target }}
path: crates/uv-build/dist
# Like `linux-arm`.
linux-s390x:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
timeout-minutes: 30
runs-on: depot-ubuntu-latest-4
strategy:
matrix:
@@ -370,6 +496,8 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
# uv
- name: "Build wheels"
uses: PyO3/maturin-action@v1
with:
@@ -397,13 +525,11 @@ jobs:
- name: "Upload wheels"
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.platform.target }}
name: wheels_uv-${{ matrix.platform.target }}
path: dist
- name: "Archive binary"
shell: bash
run: |
set -euo pipefail
TARGET=${{ matrix.platform.target }}
ARCHIVE_NAME=uv-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
@@ -421,6 +547,36 @@ jobs:
*.tar.gz
*.sha256
# uv-build
- name: "Build wheels uv-build"
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
manylinux: auto
docker-options: ${{ matrix.platform.maturin_docker_options }}
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml
- uses: uraimo/run-on-arch-action@v2
if: matrix.platform.arch != 'ppc64'
name: "Test wheel uv-build"
with:
arch: ${{ matrix.platform.arch }}
distro: ubuntu20.04
githubToken: ${{ github.token }}
install: |
apt-get update
apt-get install -y --no-install-recommends python3 python3-pip python-is-python3
pip3 install -U pip
run: |
pip install ${{ env.PACKAGE_NAME }}-build --no-index --find-links crates/uv-build/dist --force-reinstall
${{ env.MODULE_NAME }}-build --help
# TODO(konsti): Enable this test on all platforms, currently `find_uv_bin` is failing to discover uv here.
# python -m ${{ env.MODULE_NAME }}-build --help
- name: "Upload wheels uv-build"
uses: actions/upload-artifact@v4
with:
name: wheels_uv_build-${{ matrix.platform.target }}
path: crates/uv-build/dist
# Like `linux-arm`, but install the `gcc-powerpc64-linux-gnu` package.
linux-powerpc:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
@@ -444,6 +600,8 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
# uv
- name: "Build wheels"
uses: PyO3/maturin-action@v1
with:
@@ -479,13 +637,11 @@ jobs:
- name: "Upload wheels"
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.platform.target }}
name: wheels_uv-${{ matrix.platform.target }}
path: dist
- name: "Archive binary"
shell: bash
run: |
set -euo pipefail
TARGET=${{ matrix.platform.target }}
ARCHIVE_NAME=uv-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
@@ -503,6 +659,28 @@ jobs:
*.tar.gz
*.sha256
# uv-build
- name: "Build wheels uv-build"
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
manylinux: auto
docker-options: ${{ matrix.platform.maturin_docker_options }}
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml
before-script-linux: |
if command -v yum &> /dev/null; then
yum update -y
yum -y install epel-release
yum repolist
yum install -y gcc-powerpc64-linux-gnu
fi
# TODO(charlie): Re-enable testing for PPC wheels.
- name: "Upload wheels uv-build"
uses: actions/upload-artifact@v4
with:
name: wheels_uv_build-${{ matrix.platform.target }}
path: crates/uv-build/dist
musllinux:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
runs-on: ubuntu-latest
@@ -519,6 +697,8 @@ jobs:
architecture: x64
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
# uv
- name: "Build wheels"
uses: PyO3/maturin-action@v1
with:
@@ -537,17 +717,17 @@ jobs:
.venv/bin/pip install --upgrade pip
.venv/bin/pip install ${{ env.PACKAGE_NAME }} --no-index --find-links dist/ --force-reinstall
.venv/bin/${{ env.MODULE_NAME }} --help
# TODO(konsti): Enable this test on all platforms, currently `find_uv_bin` is failing to discover uv here.
# .venv/bin/python -m ${{ env.MODULE_NAME }} --help
.venv/bin/uvx --help
- name: "Upload wheels"
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.target }}
name: wheels_uv-${{ matrix.target }}
path: dist
- name: "Archive binary"
shell: bash
run: |
set -euo pipefail
TARGET=${{ matrix.target }}
ARCHIVE_NAME=uv-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
@@ -565,6 +745,32 @@ jobs:
*.tar.gz
*.sha256
# uv-build
- name: "Build wheels uv-build"
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
manylinux: musllinux_1_1
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml
- name: "Test wheel uv-build"
if: matrix.target == 'x86_64-unknown-linux-musl'
uses: addnab/docker-run-action@v3
with:
image: alpine:3.12
options: -v ${{ github.workspace }}:/io -w /io
run: |
apk add python3
python3 -m venv .venv
.venv/bin/pip install --upgrade pip
.venv/bin/pip install ${{ env.PACKAGE_NAME }}-build --no-index --find-links crates/uv-build/dist --force-reinstall
.venv/bin/${{ env.MODULE_NAME }}-build --help
.venv/bin/python -m ${{ env.MODULE_NAME }}_build --help
- name: "Upload wheels uv-build"
uses: actions/upload-artifact@v4
with:
name: wheels_uv_build-${{ matrix.target }}
path: crates/uv-build/dist
musllinux-cross:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
runs-on: ubuntu-latest
@@ -585,6 +791,8 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
# uv
- name: "Build wheels"
uses: PyO3/maturin-action@v1
with:
@@ -605,6 +813,8 @@ jobs:
python -m venv .venv
.venv/bin/pip install ${{ env.PACKAGE_NAME }} --no-index --find-links dist/ --force-reinstall
.venv/bin/${{ env.MODULE_NAME }} --help
# TODO(konsti): Enable this test on all platforms, currently `find_uv_bin` is failing to discover uv here.
# .venv/bin/python -m ${{ env.MODULE_NAME }} --help
.venv/bin/uvx --help
- uses: uraimo/run-on-arch-action@v2
name: "Test wheel (manylinux)"
@@ -626,13 +836,11 @@ jobs:
- name: "Upload wheels"
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.platform.target }}
name: wheels_uv-${{ matrix.platform.target }}
path: dist
- name: "Archive binary"
shell: bash
run: |
set -euo pipefail
TARGET=${{ matrix.platform.target }}
ARCHIVE_NAME=uv-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
@@ -650,3 +858,48 @@ jobs:
path: |
*.tar.gz
*.sha256
# uv-build
- name: "Build wheels"
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
manylinux: musllinux_1_1
args: --profile minimal-size --locked ${{ matrix.platform.arch == 'aarch64' && '--compatibility 2_17' || ''}} --out crates/uv-build/dist -m crates/uv-build/Cargo.toml
docker-options: ${{ matrix.platform.maturin_docker_options }}
rust-toolchain: ${{ matrix.platform.toolchain || null }}
- uses: uraimo/run-on-arch-action@v2
name: "Test wheel"
with:
arch: ${{ matrix.platform.arch }}
distro: alpine_latest
githubToken: ${{ github.token }}
install: |
apk add python3
run: |
python -m venv .venv
.venv/bin/pip install ${{ env.PACKAGE_NAME }}-build --no-index --find-links crates/uv-build/dist --force-reinstall
.venv/bin/${{ env.MODULE_NAME }}-build --help
# TODO(konsti): Enable this test on all platforms, currently `find_uv_bin` is failing to discover uv here.
# .venv/bin/python -m ${{ env.MODULE_NAME }}_build --help
- uses: uraimo/run-on-arch-action@v2
name: "Test wheel (manylinux)"
if: matrix.platform.arch == 'aarch64'
with:
arch: aarch64
distro: ubuntu20.04
githubToken: ${{ github.token }}
install: |
apt-get update
apt-get install -y --no-install-recommends python3 python3-pip python-is-python3
pip3 install -U pip
run: |
pip install ${{ env.PACKAGE_NAME }}-build --no-index --find-links crates/uv-build/dist --force-reinstall
${{ env.MODULE_NAME }}-build --help
# TODO(konsti): Enable this test on all platforms, currently `find_uv_bin` is failing to discover uv here.
# python -m ${{ env.MODULE_NAME }}_build --help
- name: "Upload wheels"
uses: actions/upload-artifact@v4
with:
name: wheels_uv_build-${{ matrix.platform.target }}
path: crates/uv-build/dist

View File

@@ -107,6 +107,11 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: "Check uv_build dependencies"
uses: EmbarkStudios/cargo-deny-action@v1
with:
command: check bans
manifest-path: crates/uv-build/Cargo.toml
- name: "Install Rust toolchain"
run: rustup component add clippy
- name: "Clippy"

View File

@@ -12,8 +12,8 @@ on:
type: string
jobs:
pypi-publish:
name: Upload to PyPI
pypi-publish-uv:
name: Upload uv to PyPI
runs-on: ubuntu-latest
environment:
name: release
@@ -25,8 +25,27 @@ jobs:
uses: astral-sh/setup-uv@v5
- uses: actions/download-artifact@v4
with:
pattern: wheels-*
path: wheels
pattern: wheels_uv-*
path: wheels_uv
merge-multiple: true
- name: Publish to PyPi
run: uv publish -v wheels/*
run: uv publish -v wheels_uv/*
pypi-publish-uv-build:
name: Upload uv-build to PyPI
runs-on: ubuntu-latest
environment:
name: release
permissions:
# For PyPI's trusted publishing.
id-token: write
steps:
- name: "Install uv"
uses: astral-sh/setup-uv@v5
- uses: actions/download-artifact@v4
with:
pattern: wheels_uv_build-*
path: wheels_uv_build
merge-multiple: true
- name: Publish to PyPi
run: uv publish -v wheels_uv_build/*