-
-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Separate project maturity phase from PEP 440 pre-release — fix pip install without --pre
Problem
GTT uses PHASE = "alpha" in version.py and src/ghtraf/_version.py to signal that the project is in early development. This is a project maturity label — it hasn't changed since the project's creation and won't change until the overall project matures.
However, get_pip_version() maps this to PEP 440's a0 suffix:
# src/ghtraf/_version.py (current)
PHASE = "alpha"
def get_pip_version():
phase_map = {"alpha": "a0", "beta": "b0"}
base += phase_map.get(PHASE, PHASE) # → "0.3.1a0"PEP 440 pre-release versions (a, b, rc) are excluded from default pip resolution. When a user runs:
pip install github-traffic-trackerpip will skip all aN versions unless:
- The user passes
--pre, or - No stable version exists at all (fallback behavior)
Right now this works by accident — 0.2.8a0 is the only version on PyPI, so pip falls back to it. But the moment we publish any stable-numbered version, every alpha release becomes invisible to standard pip install. And if someone pins >=0.2.8, pip will skip 0.3.0a0 through 0.9.9a0 entirely.
This is a semantic collision: we're using "alpha" to mean project maturity (informational, long-lived) but PyPI interprets it as release lifecycle (functional, per-version, hides from resolution).
Proposed solution
Port the three-field version model already proven in TeeClip:
# Before (current GTT):
PHASE = "alpha" # Does double duty: display AND pip
# After (TeeClip model):
PHASE = None # Per-release lifecycle: None, "alpha", "beta", "rc1"
PRE_RELEASE_NUM = 0 # PEP 440 pre-release counter (a1, b2)
PROJECT_PHASE = "alpha" # Project-wide maturity: "prealpha", "alpha", "beta", "stable"PHASE controls PyPI behavior. When None, the pip version is stable-numbered (0.3.1). When set to "alpha" for a specific release, pip gets 0.3.1a1 — a genuine pre-release for testing.
PROJECT_PHASE is display-only. Shows in ghtraf --version as ALPHA 0.3.1. Never touches pip resolution. Changes once when the project reaches beta or stable.
PRE_RELEASE_NUM allows publishing multiple pre-releases of the same version (0.5.0a1, 0.5.0a2, 0.5.0a3).
TeeClip already has this working on PyPI: versions 0.1.1 (stable), 0.2.2a1 (pre-release), and 0.2.2 (stable) all coexist. pip install teeclip correctly resolves to 0.2.2.
Implementation approach
Phase 1: Version field addition
Update version.py (source of truth):
MAJOR = 0
MINOR = 3
PATCH = 1
PHASE = None # Per-release: None (stable on PyPI), "alpha", "beta", "rc1"
PRE_RELEASE_NUM = 0 # PEP 440 number: a1, b2, rc3
PROJECT_PHASE = "alpha" # Project-wide: "prealpha", "alpha", "beta", "stable"Mirror changes to src/ghtraf/_version.py with new functions:
def get_display_version():
"""Human-friendly: 'ALPHA 0.3.1' or 'BETA 0.5.0' or '1.0.0'"""
base = get_base_version()
if PROJECT_PHASE and PROJECT_PHASE != "stable":
return f"{PROJECT_PHASE.upper()} {base}"
return base
def get_pip_version():
base = f"{MAJOR}.{MINOR}.{PATCH}"
phase_map = {"alpha": f"a{PRE_RELEASE_NUM}", "beta": f"b{PRE_RELEASE_NUM}"}
if PHASE:
base += phase_map.get(PHASE, PHASE)
# ... branch/dev logic unchangedPhase 2: Sync script update
Update scripts/sync-versions.py:
- Read/write
PROJECT_PHASEandPRE_RELEASE_NUMalongside existing fields - Add
--project-phaseCLI flag (parallel to existing--phase) - Update
to_pep440()to usePRE_RELEASE_NUM
Phase 3: CLI integration
Update src/ghtraf/cli.py to use get_display_version() for --version output.
Add DISPLAY_VERSION module-level export for convenience.
Phase 4: First stable-numbered PyPI release
Publish next version (e.g., 0.4.0) without a0 suffix. pip install github-traffic-tracker works without --pre.
Version field semantics
| Field | Controls | Changes when | Example values |
|---|---|---|---|
PROJECT_PHASE |
--version display, badges |
Project reaches new maturity | "prealpha", "alpha", "beta", "stable" |
PHASE |
PyPI version suffix | Specific release is a pre-release | None, "alpha", "beta", "rc1" |
PRE_RELEASE_NUM |
PEP 440 pre-release counter | Multiple pre-releases of same version | 0, 1, 2 |
Default state (most releases): PHASE = None → pip gets 0.4.0 (installable).
Pre-release state (testing): PHASE = "alpha" → pip gets 0.5.0a1 (needs --pre).
Git tag convention
Tags can retain -alpha suffix for human readability: v0.4.0-alpha. Git tags are not PEP 440 constrained. The PyPI version comes from PIP_VERSION in _version.py, not the tag name.
When PROJECT_PHASE changes: tags become v0.5.0-beta, then v1.0.0.
Design considerations
- Existing PyPI install:
0.4.0 > 0.2.8a0in PEP 440 ordering, sopip install --upgradeworks correctly. No conflict. - Classifier stays:
Development Status :: 3 - Alphainpyproject.tomlcontinues to signal maturity on the PyPI page. - No breaking change: The
PIP_VERSIONattribute name andpyproject.tomlreference don't change — only the computed value does. - Reversible: If needed, set
PHASE = "alpha"to return to pre-release PyPI versions. - Copy-first: Port from TeeClip's
_version.py— proven code, not a rewrite.
Acceptance criteria
-
version.pyhasPROJECT_PHASE,PRE_RELEASE_NUM, andPHASE = None -
src/ghtraf/_version.pymirrors the three-field model withget_display_version() -
scripts/sync-versions.pypropagates all three fields and supports--project-phaseflag -
get_pip_version()returns stable version by default (e.g.,0.4.0not0.4.0a0) -
get_display_version()returnsALPHA 0.4.0(or current project phase) -
ghtraf --versionshows display version with project phase prefix -
DISPLAY_VERSIONexported as module-level convenience -
pyproject.tomlstill readsPIP_VERSIONcorrectly (no change needed) - Alias package
pyproject.tomlsyncs to stable version number - Published to PyPI as stable-numbered version —
pip install github-traffic-trackerworks without--pre - Verified on TestPyPI before production publish
Related issues
- Refs Version binding — dashboard schema awareness and workflowVersion in state.json #45 — Version binding (different: schema awareness, not PEP 440 alignment)
- Refs Add alpha status warning and Current Status section to README #50 — Alpha status warning in README (display-side of the same maturity signal)
- Refs Architecture documentation — docs/ARCHITECTURE.md #33 — Architecture docs (version system should be documented)
Analysis
See 2026-02-28__16-56-20__dev-workflow-process_version-system-pypi-alignment.md for the full DEV WORKFLOW PROCESS analysis including comparison of GTT vs TeeClip version systems and evaluation of four solution approaches.