✨ feat(packaging): add monorepo with bare and meta packages#296
Merged
gaborbernat merged 10 commits intotox-dev:mainfrom Feb 24, 2026
Merged
✨ feat(packaging): add monorepo with bare and meta packages#296gaborbernat merged 10 commits intotox-dev:mainfrom
gaborbernat merged 10 commits intotox-dev:mainfrom
Conversation
dea8756 to
da6f41a
Compare
Docker users with system-installed uv were forced to download and bundle uv again when installing tox-uv, wasting bandwidth and storage in CI environments. This became particularly problematic in containerized builds where uv is pre-installed at the system level but pip install tox-uv would download another copy. The monorepo structure splits the project into tox-uv-bare (core plugin without uv dependency) and tox-uv (meta package that depends on tox-uv-bare plus uv). The uv detection logic implements a three-tier fallback: check TOX_UV_PATH environment variable first, then attempt to import bundled uv from the meta package, and finally fall back to system uv from PATH. The meta package uses a hatchling metadata hook to inject the VCS-derived version into the tox-uv-bare dependency at build time, ensuring both packages always have matching versions in published releases. A dedicated test suite verifies the build process and version injection. Both packages share the same codebase and version number, with the release workflow building both on every tag. Existing users installing tox-uv experience no change in behavior and continue to receive bundled uv. Docker users can now install tox-uv-bare to leverage their system uv installation without duplication. Fixes tox-dev#280
0ece36a to
cc820de
Compare
Docker users with system-installed uv were forced to download and bundle uv again when installing tox-uv, wasting bandwidth and storage in CI environments. This became particularly problematic in containerized builds where uv is pre-installed at the system level but pip install tox-uv would download another copy. The monorepo structure splits the project into tox-uv-bare (core plugin without uv dependency) and tox-uv (meta package that depends on tox-uv-bare plus uv). The uv detection logic implements a three-tier fallback: check TOX_UV_PATH environment variable first, then attempt to import bundled uv from the meta package, and finally fall back to system uv from PATH. The meta package uses a hatchling metadata hook to inject the VCS-derived version into the tox-uv-bare dependency at build time, ensuring both packages always have matching versions in published releases. A dedicated test suite verifies the build process and version injection. Both packages share the same codebase and version number, with the release workflow building both on every tag. Existing users installing tox-uv experience no change in behavior and continue to receive bundled uv. Docker users can now install tox-uv-bare to leverage their system uv installation without duplication. When using system uv (via tox-uv-bare or TOX_UV_PATH), the version is logged at warning level to help users understand which uv is being used. Fixes tox-dev#280
cc820de to
0800fe9
Compare
for more information, see https://pre-commit.ci
CI was failing with 99% coverage because defensive error paths in the uv discovery logic were untested. These paths handle edge cases like bundled uv installation and complete uv absence, which are impractical to test in the CI environment where system uv is always present. Added coverage pragmas for the untestable bundled uv paths and the error case when no uv is found. Added tests for exception handling in version detection (timeout and OS errors) to cover remaining testable paths. Also added the meta test environment to CI workflow to ensure meta package build and version injection tests run on every PR.
The test_uv_bundled_import_error test failed on Python 3.13 because __builtins__ is a dict in some contexts rather than a module, causing AttributeError when accessing __builtins__.__import__. Fixed by explicitly importing the builtins module and accessing __import__ from it, which works consistently across all Python versions.
for more information, see https://pre-commit.ci
Added meta test environments for Python 3.10-3.14 to match the consistency of running all test suites across supported Python versions, even though meta package tests verify build-time behavior that is independent of the Python runtime version. Used TOML inline table syntax to keep each environment definition compact on single lines rather than duplicating the full multi-line configuration, reducing verbosity while maintaining explicitness about each environment.
for more information, see https://pre-commit.ci
The type environment was failing because the meta package uses hatchling as a build dependency which is not available during type checking, and because optional imports like the uv package were being flagged as unresolved. Excluded the meta directory from type checking since it contains build-time code only, and added type ignore comments for the optional uv import and test helper functions that need to accept Any types.
The meta environment configuration was duplicated across all five Python version environments (3.10-3.14), requiring any change to be made in five places. This increased maintenance burden and risk of inconsistencies. Tox's base inheritance feature allows defining the configuration once in a base environment and having versioned environments inherit from it. This reduces the configuration from 189 lines to 52 lines while preserving identical behavior across all environments.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Docker users with system-installed
uvwere forced to download and bundleuvagain when installingtox-uv, wasting bandwidth and storage in CI environments. 🐳 This became particularly problematic in containerized builds whereuvis pre-installed at the system level butpip install tox-uvwould download another copy.The monorepo structure splits the project into
tox-uv-bare(core plugin withoutuvdependency) andtox-uv(meta package that depends ontox-uv-bareplusuv). ✨ Theuvdetection logic implements a three-tier fallback: checkTOX_UV_PATHenvironment variable first, then attempt to import bundleduvfrom the meta package, and finally fall back to systemuvfromPATH. Both packages share the same codebase and version number, with the release workflow building both on every tag.Existing users installing
tox-uvexperience no change in behavior and continue to receive bundleduv. Docker users can now installtox-uv-bareto leverage their systemuvinstallation without duplication. The fallback chain ensures graceful degradation with clear error messages whenuvis unavailable.Fixes #280