gabriel / muse public
derive-semver-tag-from-pep440-version.md markdown
70 lines 2.9 KB
Raw
sha256:c0eba5ad689cec79f4a3fcdc4f5da78556cb4b8cb7b330f944634356c10379ed chore: pivot to nightly channel — bump version to 0.2.0.dev… Sonnet 5 patch 12 days ago

Derive the SemVer release tag from pyproject.toml automatically

Background

pyproject.toml's version field must stay in canonical PEP 440 form (0.2.0rc15, no hyphen) because that's the literal string hatchling embeds in the built sdist's filename — publish_muse_release.sh and smoke_muse.sh both derive the tarball URL directly from it. A hyphenated form (0.2.0-rc15) was tried during the rc15 release and broke the publish script's tarball-filename lookup (hatchling normalizes it away regardless of what's written in the file), so it was reverted back to 0.2.0rc15.

Separately, muse tag add enforces strict SemVer 2.0, which requires the hyphen before a pre-release identifier (v0.2.0-rc15 is valid, v0.2.0rc15 is rejected with "Version tag must start with 'v' ... is not valid semver").

These two canonical forms are incompatible at the string level — there is no single literal that satisfies both PEP 440's canonical form and SemVer 2.0's required hyphen. pyproject.toml stays the single source of truth in PEP 440 form (see decision above); the SemVer tag needs to be derived from it, not hand-typed as a second, independently-maintained version string.

Goal

Whenever a release is tagged with muse tag add, the SemVer-hyphenated tag string is computed from pyproject.toml's PEP 440 version automatically — no one hand-types v0.2.0-rc15 and risks a typo or drift from the actual shipped version.

Suggested approach

A small helper (Python, using the already-available packaging library) that takes a PEP 440 version string and emits the SemVer-compatible tag:

from packaging.version import Version

def pep440_to_semver_tag(version_str: str) -> str:
    v = Version(version_str)
    pre = f"-{v.pre[0]}{v.pre[1]}" if v.pre else ""
    return f"v{v.major}.{v.minor}.{v.micro}{pre}"

# pep440_to_semver_tag("0.2.0rc15") -> "v0.2.0-rc15"

Wire this into the standard release flow (documented in musehub/.muse/agent.md's "Standard release flow" section) as a step after publish_muse_release.sh succeeds:

TAG=$(python3 -c "from packaging.version import Version; v=Version('$MUSE_VERSION'); pre=f'-{v.pre[0]}{v.pre[1]}' if v.pre else ''; print(f'v{v.major}.{v.minor}.{v.micro}{pre}')")
muse tag add "$TAG" --message "release $MUSE_VERSION"

Deliverables

  • [ ] Helper function (or inline one-liner, whichever fits the existing script style better) added to the release flow, not hand-typed.
  • [ ] musehub/.muse/agent.md's "Standard release flow" section updated with the new tagging step.
  • [ ] Manually QA'd once against a real release before considering this done (tag the current 0.2.0rc15 release once MWP verb QA — muse#63 — is fully signed off, per gabriel's explicit sequencing: manual QA first, then tag).

Out of scope

  • Changing pyproject.toml's format — settled as PEP 440, no hyphen, per the incident above.
  • Retroactively tagging any release prior to this ticket.
File History 1 commit
sha256:c287f599c5429903a139eadf3c5db5d930520e57cb0c3c575d9570e953c3b2d6 chore: bump version to 0.2.0.dev2 — nightly.2 Sonnet 4.6 patch 11 days ago