Problem
The current PyPI publishing support assumes one Python package per repo — it always builds at the worktree root. Repos like myk-org/pi-config have 2 Python packages in different directories:
- Root:
myk-pi-tools (hatchling, pyproject.toml)
packages/pi-sidecar/: pi-sidecar-client (setuptools, packages/pi-sidecar/pyproject.toml)
Currently there's no way to specify subdirectories or build/publish multiple packages.
Current Behavior
- Config schema:
pypi: {token: "..."} — flat, no package paths
push_handler.py → upload_to_pypi(): on tag push, checks out tag into worktree, runs uv build --sdist at worktree root, then twine upload — only finds the root package
runner_handler.py → run_install_python_module(): PR check runs uvx pip wheel at worktree root — one package only
check_run_handler.py: registers one status check (PYTHON_MODULE_INSTALL_STR)
github_api.py: self.pypi: dict[str, str] — flat dict with just token
Proposed Solution
1. Schema change (webhook_server/config/schema.yaml)
Add optional packages list to pypi:
pypi:
token: <PYPI TOKEN>
packages: # optional — defaults to ["."] (repo root)
- "."
- "packages/pi-sidecar"
Backward compatible — if packages is absent, behaves like today (root only).
2. Config loading (webhook_server/libs/github_api.py)
Add pypi_packages property that resolves to ["."] when packages key is absent.
3. Push handler (webhook_server/libs/handlers/push_handler.py)
Loop upload_to_pypi() over each package directory:
- Build each package in its own subdirectory
- Upload each package separately
- Create issue on failure per package
4. Runner handler (webhook_server/libs/handlers/runner_handler.py)
Loop run_install_python_module() over each package dir. Option to register separate check runs per package (e.g., Python module install [myk-pi-tools]) or keep one combined check.
5. Check run handler (webhook_server/libs/handlers/check_run_handler.py)
If separate checks per package: register PYTHON_MODULE_INSTALL_STR per package name. If combined: no change needed.
Files to change
| File |
Change |
webhook_server/config/schema.yaml |
Add packages array to pypi |
examples/config.yaml |
Add example with packages |
webhook_server/libs/github_api.py |
Parse pypi.packages, add pypi_packages property |
webhook_server/libs/handlers/push_handler.py |
Loop upload_to_pypi over each package dir |
webhook_server/libs/handlers/runner_handler.py |
Loop run_install_python_module over each package dir |
| Tests |
Cover multi-package config + build/upload loop |
Backward Compatibility
Zero breaking changes — pypi: {token: "..."} without packages defaults to root-only, exactly as today.
Done
Problem
The current PyPI publishing support assumes one Python package per repo — it always builds at the worktree root. Repos like myk-org/pi-config have 2 Python packages in different directories:
myk-pi-tools(hatchling,pyproject.toml)packages/pi-sidecar/:pi-sidecar-client(setuptools,packages/pi-sidecar/pyproject.toml)Currently there's no way to specify subdirectories or build/publish multiple packages.
Current Behavior
pypi: {token: "..."}— flat, no package pathspush_handler.py→upload_to_pypi(): on tag push, checks out tag into worktree, runsuv build --sdistat worktree root, thentwine upload— only finds the root packagerunner_handler.py→run_install_python_module(): PR check runsuvx pip wheelat worktree root — one package onlycheck_run_handler.py: registers one status check (PYTHON_MODULE_INSTALL_STR)github_api.py:self.pypi: dict[str, str]— flat dict with justtokenProposed Solution
1. Schema change (
webhook_server/config/schema.yaml)Add optional
packageslist topypi:Backward compatible — if
packagesis absent, behaves like today (root only).2. Config loading (
webhook_server/libs/github_api.py)Add
pypi_packagesproperty that resolves to["."]whenpackageskey is absent.3. Push handler (
webhook_server/libs/handlers/push_handler.py)Loop
upload_to_pypi()over each package directory:4. Runner handler (
webhook_server/libs/handlers/runner_handler.py)Loop
run_install_python_module()over each package dir. Option to register separate check runs per package (e.g.,Python module install [myk-pi-tools]) or keep one combined check.5. Check run handler (
webhook_server/libs/handlers/check_run_handler.py)If separate checks per package: register
PYTHON_MODULE_INSTALL_STRper package name. If combined: no change needed.Files to change
webhook_server/config/schema.yamlpackagesarray topypiexamples/config.yamlpackageswebhook_server/libs/github_api.pypypi.packages, addpypi_packagespropertywebhook_server/libs/handlers/push_handler.pyupload_to_pypiover each package dirwebhook_server/libs/handlers/runner_handler.pyrun_install_python_moduleover each package dirBackward Compatibility
Zero breaking changes —
pypi: {token: "..."}withoutpackagesdefaults to root-only, exactly as today.Done
packagesarray underpypigithub_api.pyparsespypi.packageswith["."]defaultpush_handler.pyloopsupload_to_pypiover each package dirrunner_handler.pyloopsrun_install_python_moduleover each package direxamples/config.yamlupdated with multi-package example