7 phases shipped: ETF codec, EPMD client, v6 handshake (MD5 cookie),
data channel (4-byte framing), gen_call protocol, TLS dist
(inet_tls_dist), unfeed integration. Maps + cross-stack validation
through wallet.unsandbox.com's test pyramid.
122 tests across unit / handshake / channel / node / tls / etf-maps.
Tag this commit with vX.Y.Z and push the tag — CI's pypi-twine stage
takes over from there.
pyproject.toml gains the metadata PyPI expects:
- Real author name + email
- Keywords (erlang, elixir, distribution, gen_server, ...)
- Classifiers (status, license, Python versions, topic)
- Project URLs (Homepage / Repository / Bug Tracker)
- readme content-type = text/markdown so PyPI renders our README
- build + twine added to the [dev] extra
.gitlab-ci.yml mirrors ago's two-stage pattern:
- test stage on every push (venv + pip install -e .[dev] + pytest)
- pypi-twine stage only on tags: python -m build, twine check,
twine upload. Credentials come from GitLab CI variables
TWINE_USERNAME (typically __token__) and TWINE_PASSWORD.
Makefile gains build / dist-check / publish-test / publish targets so
the release flow is also runnable locally if a dry run is needed.
Release flow:
1. Bump version in pyproject.toml
2. Commit + push
3. git tag -a vX.Y.Z -m 'release vX.Y.Z' && git push --tags
4. CI's pypi-twine stage picks up the tag and uploads
README.md adds an Install section + Quick start (plain dist + TLS dist)
so PyPI's project page shows usable copy on first visit. dist/ artifacts
build cleanly and both pass twine check.