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.2
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.2.tar.gz | 49.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| abstract_pypit-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 102.1 kB
Release files / abstract_pypit-0.1.2.tar.gz
| Download URL | abstract_pypit-0.1.2.tar.gz |
|---|---|
| Size | 49.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9c697b33c47d3a7750a73d29199ce68fd3053e8680776416ddf4bb962807f4e3
|
|
BLAKE2b-256 checksum How to use checksums |
3219d20a80df05917e36793a07f3fc1e7dc71c85cc34588a7dc331ce8ccd1391
|
| 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.2-py3-none-any.whl
| Download URL | abstract_pypit-0.1.2-py3-none-any.whl |
|---|---|
| Size | 52.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0510156bca79fdb272346fcb3da1b22072cd9a28c11a1838b8683935421f9d9c
|
|
BLAKE2b-256 checksum How to use checksums |
877422ec42afe93c78b892b354363d49a94c3d46013595eecebcae1bbcf25a44
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|