Release Publishing¶
This page documents the staged package-release workflow for netbox-proxbox and
its companion proxbox-api backend. The workflow deliberately separates package
index validation from final publication so failed published artifacts are never
reused.
For the broader CI job map and Docker E2E matrix, see CI and E2E Workflows.
Release State Machine¶
flowchart TD
Start([Choose target release\nX.Y.Z])
Bump[Bump package version\npyproject.toml + netbox_proxbox/__init__.py + uv.lock]
RCTag[Create release-candidate tag\nvX.Y.ZrcN]
RCCI[CI builds dist\nvalidates tag/version/lockfile]
RCUpload[Upload vX.Y.ZrcN to TestPyPI\nwithout --skip-existing]
RCValidate[Install rcN from TestPyPI\nrun package checks]
RCE2E[E2E Docker\nnetbox-proxbox rcN from TestPyPI\nproxbox-api rcN from TestPyPI]
RCFailed{Any TestPyPI\nvalidation failed?}
NextRC[Bump to vX.Y.ZrcN+1]
FinalTag[Create or dispatch final tag\nvX.Y.Z]
FinalUpload[Upload vX.Y.Z to PyPI]
FinalValidate[Install final from PyPI\nrun post-upload E2E]
FinalFailed{Post-release fix needed?}
Post[Bump to vX.Y.Z.postN\npublish .postN to PyPI]
Done([Release is green])
Start --> Bump --> RCTag --> RCCI --> RCUpload --> RCValidate --> RCE2E --> RCFailed
RCFailed -- yes --> NextRC --> RCTag
RCFailed -- no --> FinalTag --> FinalUpload --> FinalValidate --> FinalFailed
FinalFailed -- yes --> Post --> FinalTag
FinalFailed -- no --> Done
Cross-Package E2E Contract¶
The plugin does not import proxbox-api as a Python dependency. It consumes the
backend as a runtime HTTP service, so release coupling is validated in Docker
E2E rather than package metadata.
sequenceDiagram
participant Tag as Release Tag
participant WF as netbox-proxbox publish workflow
participant TP as TestPyPI
participant PY as PyPI
participant E2E as e2e-docker.yml
participant NB as NetBox container
participant API as proxbox-api container
Tag->>WF: vX.Y.ZrcN
WF->>TP: Upload netbox-proxbox package
WF->>E2E: install_source=testpypi, dependency_mode=testpypi-package
E2E->>NB: pip install netbox-proxbox==X.Y.ZrcN from TestPyPI
E2E->>API: pip install proxbox-api==configured version from TestPyPI
E2E-->>WF: Release-candidate checks pass
Tag->>WF: vX.Y.Z, vX.Y.Z.postN, or publish_target=pypi
WF->>PY: Upload netbox-proxbox package
WF->>E2E: install_source=pypi, dependency_mode=pypi-package
E2E->>NB: pip install netbox-proxbox==X.Y.Z or X.Y.Z.postN from PyPI
E2E->>API: pip install proxbox-api==configured version from PyPI
E2E-->>WF: Post-publish checks pass
Workflow Rules¶
pyproject.toml,netbox_proxbox/__init__.py,uv.lock, and the Git tag must all describe the same version.rcNtag pushes (patternv*rc*) publish to TestPyPI for release-candidate validation.- Official releases (
vX.Y.Z,vX.Y.Z.postN) are triggered only by GitHub release creation (release: published) cut from thedevelopbranch. Plain non-rc tag pushes do not trigger the publish workflow. Manual workflow dispatch withpublish_target=pypialso publishes to PyPI. - Package uploads intentionally omit
twine --skip-existing; a consumed version must move forward to the next.postNorrcN. proxbox_api_versioncan be supplied manually. If omitted, the workflow reads repository variables in this order:PROXBOX_API_TESTPYPI_VERSION/PROXBOX_API_PYPI_VERSION,PROXBOX_API_RELEASE_VERSION, then the checked-in default.
Operator Checklist¶
- Publish and validate
proxbox-apion TestPyPI first. - Publish and validate
netbox-proxboxon TestPyPI using that TestPyPIproxbox-apiversion. - Promote
proxbox-apithrough PyPI release candidates and final PyPI release. - Promote
netbox-proxboxthrough PyPI release candidates and final PyPI release using the matching PyPIproxbox-apiversion. - If any published validation fails, bump to the next
.postNorrcN; never retry the same artifact version.