PyBuilder is a build automation tool for Python, written in pure Python. It uses
dependency-based programming with a plugin mechanism for build lifecycles similar
to Maven and Gradle. This is a fork (origin = arcivanov/pybuilder,
upstream = pybuilder/pybuilder).
build.py— PyBuilder build descriptor (likepom.xmlorbuild.gradle)src/main/python/pybuilder/— main source codesrc/unittest/python/— unit tests (*_tests.py)src/integrationtest/python/— integration tests (*_tests.py)setup.py— pip install bootstrap (runs PyBuilder internally, do not run manually)pyproject.toml— PEP 517 build backend pointing topybuilder.pep517target/— build output directory (gitignored)
PyBuilder builds itself (bootstrap). All build commands use pyb:
# Full build (analyze + publish)
pyb
# Run unit tests only
pyb run_unit_tests
# Run integration tests only
pyb run_integration_tests
# Clean build
pyb clean package
# Verbose output
pyb -v
# Debug verbose output (includes all debug logging)
pyb -vX
# Dump project configuration as JSON (no build, runs initializers only)
pyb -i
# JSON goes to stdout, log messages go to stderr
pyb -i 2>/dev/null | jq .project.name
pyb -i -E ci -P verbose=true 2>/dev/null | jq .The build script (build.py) bootstraps by inserting src/main/python into
sys.path so PyBuilder can build itself.
PyBuilder manages isolated venvs during builds:
.pybuilder/plugins/{version}/— plugin dependencies (committed to.gitignore)target/venv/build/{version}/— build + runtime deps (unit tests run here)target/venv/test/{version}/— runtime deps only (integration tests run here)
Unit tests use subprocess remoting: a child process is spawned with the build
venv's Python, sys.path is remapped to use the build venv's site-packages,
and tests execute via RPC. Integration tests run each file as a standalone
subprocess with PYTHONPATH pointing to target/dist/ (the built distribution).
target/reports/unittest— unit test console outputtarget/reports/unittest.json— structured unit test results (JSON)target/reports/integrationtests/{name}— per-integration-test stdouttarget/reports/integrationtests/{name}.err— per-integration-test stderrtarget/reports/*_coverage*— coverage reports (JSON, XML, HTML)target/logs/install_dependencies/— pip install logs
- Required: Python >= 3.10
- Supported: CPython 3.10, 3.11, 3.12, 3.13, 3.14
- Experimental: CPython 3.15-dev, free-threaded 3.14t/3.13t, PyPy 3.10/3.11
GitHub Actions workflow at .github/workflows/pybuilder.yml:
build-primary: Ubuntu, all supported Python versions, with/without venvbuild-secondary: Windows + macOS, all supported Python versionsbuild-experimental: dev/free-threaded/PyPy builds (allowed to fail)- Deployment happens from
masterbranch on Python 3.13 Linux only
PyBuilder vendors its dependencies into src/main/python/pybuilder/_vendor/
via the python.vendorize plugin. Do not modify vendored code directly.
- Max line length: 130 characters (flake8)
- flake8 is enforced and breaks the build
- Extend ignore: E303, F401, F824
- Apache License 2.0 header on source files
The version in build.py is always X.Y.Z.dev on master. Do not change it
manually to cut a release. Instead, append [release] (or [release X.Y.Z] for
a specific version) to the first line of the commit message and PR title. The
CI detects this tag and handles version finalization, tagging, and PyPI upload
automatically. After the release, CI bumps the version to the next .dev.
Example commit message first line:
Release 0.13.19 [release]
This is a fork. PRs go from origin (arcivanov) to upstream (pybuilder).
Always pull from upstream before branching. Never push directly to master.
The project website is in the pybuilder/pybuilder.github.io GitHub repo
(branch source). Changes to PyBuilder code must be accompanied by
corresponding documentation updates.
- Release notes — add entry under the next version in
articles/_release-notes/v0.13.x.md(section### New Features) - Manual — add or update the relevant section in
documentation/manual.md - Tutorial — if the feature is user-facing and discoverable, add a brief
section or example to
documentation/tutorial.md - Coding agents — update
documentation/coding-agents.md(both the "Quick Reference for Agents" section and the example CLAUDE.md) if the feature affects how agents interact with builds (e.g. new CLI flags, new build commands, new output formats) - Dedicated page (optional) — for substantial features, create a new page
under
documentation/and add it todocumentation/index.md - Blog post — create
articles/_posts/YYYY-MM-DD-slug.mdwith front matterlayout: post,author: arcivanov,categories: news
- Release notes — add entry under
### Bugs Fixedinarticles/_release-notes/v0.13.x.md - Manual/tutorial — update only if the fix changes documented behavior or corrects a misleading example
- Release notes — add entry under
### New Features(if user-visible) or### Bugs Fixed(if correcting behavior) - Plugin reference — update property tables in
documentation/plugins.md - Manual — update if the property affects a workflow described there
- Release notes — add entry under
### Vendorized Dependency Upgrades
| File | Purpose |
|---|---|
articles/_release-notes/v0.13.x.md |
Release notes (add new version at top) |
articles/_posts/YYYY-MM-DD-*.md |
Blog posts / announcements |
documentation/manual.md |
Usage manual (CLI, properties, venvs, testing) |
documentation/tutorial.md |
Getting started tutorial |
documentation/plugins.md |
Plugin reference with property tables |
documentation/coding-agents.md |
Agent instruction guidance and examples |
documentation/index.md |
Documentation hub (add links for new pages) |