abstract_pypit
One-command PyPI publisher + GitHub pusher, and a server-wide staging release
loop (init / stage / release / request / runner).
Finds the next free version above whatever is on PyPI, bumps setup.py and
pyproject.toml, builds sdist + wheel, uploads to PyPI via twine, commits and
pushes to GitHub, then syncs the local install — all in one call.
Dependencies: requests, plus build and twine (so a fresh install can publish).
Install
pip install abstract_pypit
Usage
# from any package directory that has setup.py + pyproject.toml:
from pypit import runit
runit()
# or from the command line:
abstract-pypit
Staging release loop
The source of a package is a directory on the server (default
/srv/pyit/dev/<project>, symlinks resolved). Nobody edits it directly; changes
reach it only through a disposable staging dir and a host-side runner:
# once, as the user who owns the staging root (the "runner"):
abstract-pypit runner install --root /srv/vm_mgr/src --requesters vm_mgr,hugpy
abstract-pypit init abstract_utilities --root /srv/vm_mgr/src # staging dir + push.sh, then stage
# any requester:
/srv/vm_mgr/src/abstract_utilities/push.sh stage # source -> ./source -> ./live
# ... edit ./live, test there ...
/srv/vm_mgr/src/abstract_utilities/push.sh release # upload, then the source is swapped
/srv/vm_mgr/src/abstract_utilities/push.sh # status
push.sh only drops <root>/_pypit/requests/<project>.<action>.<id>.req and follows
the log (abstract-pypit request ...); the owner's systemd --user path unit runs
abstract-pypit runner run, which executes requests one at a time. No ssh, sudo or
credentials are needed to release.
release, per project:
- If the source moved on since staging (version, content or git HEAD), it PAUSES:
writes
merge-*.difffiles, 3-way merges the source intolive/(base =source/), marks conflicts<<<<<<< live / ======= / >>>>>>> source(or a<file>.CONFLICTnote; nothing wins), rebasessource/and stops. The merged live is what the next push releases; it refuses while markers or notes remain. - Otherwise, by backend (auto-detected):
- pypi: runPypit inside
live/(next free version, build, upload, commit+push without pulling, sync the local install); success = PyPI lists the version. - pkg_src: the source is
<repo>/py/<group>/<pkg>of a pkg-src-watched tree (<repo>/py/tooling/pkg_src.py); the swap is the release; success = pkg-src-watch recorded exactly the swapped tree (read-only query), else the swap is reversed.
- pypi: runPypit inside
live/moves toprod/,prod/is copied to a temp dir and content-verified, then source ->_old, temp -> source,_oldremoved; then it re-stages.
Copies are rsync -aAX --checksum, keep .git, and exclude build output. Commands:
| command | |
|---|---|
abstract-pypit init <p> [--root R] [--source S] [--editors u1,u2] [--handoff R2] [--force] |
create/rebuild the staging dir, stage |
abstract-pypit stage <p> [--force] / release <p> / status <p> |
the engine (run by the runner) |
abstract-pypit request <stage|release|status> <p> |
what push.sh calls |
abstract-pypit runner install [--root R ...] [--requesters u1,u2] / run --root R / status |
the runner |
Env: PYPIT_ROOT (default root ~/staging), PYPIT_DEV_ROOT (default
/srv/pyit/dev), PYPIT_PYPI_WAIT, PYPIT_PKG_SRC_WAIT, PYPIT_PKG_SRC_PYTHON.
Tests: python -m unittest discover -s tests (nothing is uploaded).
Credentials
PyPI: twine reads ~/.pypirc or TWINE_USERNAME / TWINE_PASSWORD env vars.
GitHub: create pypit/src/envs/.env on the machine running pypit:
GITHUB_OWNER_1=your-username
GITPASS_1=<your-github-pat>
GITHUB_OWNER_2=your-org
GITPASS_2=<org-github-pat>
SSH key at ~/.ssh/github/githubssh_nopass must be registered with GitHub.
Per-package config
Add to the package's own pyproject.toml:
[tool.pypit]
github_owner = "your-org-or-username" # which org/user owns the repo
github_push = true # set false to skip GitHub entirely
License
MIT
Metadata
Release files for abstract-pypit 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| abstract_pypit-0.1.0.tar.gz | 47.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| abstract_pypit-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 98.5 kB
Release files / abstract_pypit-0.1.0.tar.gz
| Download URL | abstract_pypit-0.1.0.tar.gz |
|---|---|
| Size | 47.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8b11eebb56b42572e0f84f2dd4cd9c700b35c269bc7acc38b03568dbcb7b427a
|
|
BLAKE2b-256 checksum How to use checksums |
f875e73493d63b6530fbb08e7f1f8968dd9eaafeaf2dd1bc75de9a1302e6ea1e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / abstract_pypit-0.1.0-py3-none-any.whl
| Download URL | abstract_pypit-0.1.0-py3-none-any.whl |
|---|---|
| Size | 51.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
28b4744d8954123009740d193d6f4f3a4363e761deccf96dd6ad3b51fb392d0b
|
|
BLAKE2b-256 checksum How to use checksums |
78262280637fd1af7c607f975ea239fe51b3b918fbf125226dd10a61632822d5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|