Lazy monorepo wheel builder — only rebuilds what changed.
Project description
lazy-wheels
CI release workflow for your multi-package uv monorepo that only rebuilds changed packages.
Why lazy-wheels?
Managing versions across multiple packages in a monorepo is painful. lazy-wheels makes it simple: you own major.minor, CI owns patch. When you're ready for a breaking change or new feature in any package, bump the major or minor version yourself (e.g. uv version --project packages/your-project --bump minor). For everything else, CI automatically increments patch versions after each release.
lazy-wheels always keeps your main branch one patch version ahead of the latest release (i.e. main represents unreleased changes). This means HEAD is always releasable, version numbers are always increasing, and you never have to think about patch versions again. Change detection uses per-package git tags, so only packages with actual changes (or dependencies on changed packages) get rebuilt.
Installation
pip install lazy-wheels
Or with uv:
uv add --group dev lazy-wheels
Or scaffold just once with uvx:
uvx lazy-wheels init
Usage
Initialize
Scaffold the GitHub Actions workflow into your repo:
lazy-wheels init
This creates .github/workflows/release.yml configured for your uv workspace.
Requirements:
- A git repository
- A
pyproject.tomlwith[tool.uv.workspace]members defined
Triggering a Release
Option 1: GitHub CLI
gh workflow run release.yml
gh workflow run release.yml -f release=r1
gh workflow run release.yml -f force_rebuild_all=true
Option 2: lazy-wheels CLI
Just wraps the gh commands into a more compact CLI.
lazy-wheels release
lazy-wheels release -r r1
lazy-wheels release --force-all
Option 3: GitHub.com
You can also manually launch the release workflow in the github.com UI.
Workflow Inputs
| Input | Description |
|---|---|
release |
Release tag (e.g., r1, r2). Auto-generates if not provided. |
force_rebuild_all |
Rebuild all packages regardless of changes. |
How It Works
- Discover — Scans
[tool.uv.workspace]members to find all packages and their dependencies - Detect changes — Compares each package against its last release tag (
{pkg}/v{version}) - Propagate dirtiness — Marks dependents of changed packages as dirty (transitive rebuild)
- Fetch unchanged — Downloads wheels for unchanged packages from previous GitHub releases
- Build changed — Runs
uv buildonly on packages that need rebuilding - Tag — Creates per-package version tags (e.g.,
my-pkg/v1.2.3) - Bump versions — Increments patch version in each built package's
pyproject.toml - Publish — Creates a GitHub Release with all wheels (changed + unchanged)
- Push — Commits version bumps and pushes tags
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lazy_wheels-0.1.9.tar.gz.
File metadata
- Download URL: lazy_wheels-0.1.9.tar.gz
- Upload date:
- Size: 19.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b3b0a6343855e67e3861b1ff5fab046e6559ac859768ef61696e4ff095a1ba5
|
|
| MD5 |
4aef803c570725e64a9c7043eb631db1
|
|
| BLAKE2b-256 |
19ae80cc512083857882df7276e41b1081d5d2f69b019280f2ed29800cc17c42
|
Provenance
The following attestation bundles were made for lazy_wheels-0.1.9.tar.gz:
Publisher:
publish.yml on tylerpayne/lazy-wheels
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lazy_wheels-0.1.9.tar.gz -
Subject digest:
6b3b0a6343855e67e3861b1ff5fab046e6559ac859768ef61696e4ff095a1ba5 - Sigstore transparency entry: 951441159
- Sigstore integration time:
-
Permalink:
tylerpayne/lazy-wheels@939ab19673e049ae6ce751e3f16442a1ea7a0ccc -
Branch / Tag:
refs/heads/main - Owner: https://github.com/tylerpayne
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@939ab19673e049ae6ce751e3f16442a1ea7a0ccc -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file lazy_wheels-0.1.9-py3-none-any.whl.
File metadata
- Download URL: lazy_wheels-0.1.9-py3-none-any.whl
- Upload date:
- Size: 17.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
98c77177014cc2727c62c94382c9ad7fbb437f25b9f51830e52a23dda19d2170
|
|
| MD5 |
3037a03274c7c89e8a5a503a7fc1386e
|
|
| BLAKE2b-256 |
b48e7a7e4b63daacdc5c3d1a890c117af72dba5e293669f3fe20c19a278538d1
|
Provenance
The following attestation bundles were made for lazy_wheels-0.1.9-py3-none-any.whl:
Publisher:
publish.yml on tylerpayne/lazy-wheels
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lazy_wheels-0.1.9-py3-none-any.whl -
Subject digest:
98c77177014cc2727c62c94382c9ad7fbb437f25b9f51830e52a23dda19d2170 - Sigstore transparency entry: 951441218
- Sigstore integration time:
-
Permalink:
tylerpayne/lazy-wheels@939ab19673e049ae6ce751e3f16442a1ea7a0ccc -
Branch / Tag:
refs/heads/main - Owner: https://github.com/tylerpayne
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@939ab19673e049ae6ce751e3f16442a1ea7a0ccc -
Trigger Event:
workflow_dispatch
-
Statement type: