feat: derive SemVer release tag from pyproject.toml's PEP 440 version automatically (muse#64)
pyproject.toml's version field must stay in canonical PEP 440 form (0.2.0rc15, no hyphen) -- a hyphenated form was tried once during the rc15 release and broke publish_muse_release.sh's tarball-filename lookup, since hatchling normalizes it away regardless of what's written in the file. Separately, `muse tag add` enforces strict SemVer 2.0, which *requires* a hyphen before a pre-release identifier (v0.2.0-rc15 is valid, v0.2.0rc15 is rejected). The two canonical forms are incompatible at the string level, so the SemVer tag must be derived from the PEP 440 version, not hand-typed as a second, independently-maintained string.
Added deploy/pep440_to_semver_tag.py: a small helper (using the already-available packaging library, following the exact pattern of the existing deploy/prune_releases.py) that converts a PEP 440 version string to its SemVer tag equivalent (e.g. "0.2.1rc12" -> "v0.2.1-rc12"). Usable as both a library function and a CLI (`python3 pep440_to_semver_tag.py <version>`).
Wired into publish_muse_release.sh as a new step 8, after the smoke test succeeds: computes $TAG via the helper and runs `muse -C "$MUSE_REPO" tag add "$TAG" --message "release $MUSE_VERSION"`. A tagging failure (e.g. the tag already exists from a prior run) is a warning, not fatal -- wrapped in an explicit if/else so it survives `set -euo pipefail` without aborting after the release is already live.
Updated .museagent.md's "Standard release flow" section to document the new automatic tagging step and why the tag is derived rather than hand-typed.
New tests: - tests/test_pep440_to_semver_tag.py: unit tests for the helper (rc/a/b pre-release forms, final releases, the documented dev-segment-dropped limitation, invalid-version rejection) plus CLI subprocess tests. - tests/test_publish_muse_release_tag.py: source-level assertions that the script correctly wires in the helper (matching this repo's existing convention in test_publish_muse_release_prune.py for validating deploy scripts without executing real AWS/muse calls) -- confirmed genuine RED against the pre-fix script (5 of 6 failed) before GREEN with the fix.
Per the ticket's explicit sequencing ("manual QA first, then tag"), this commit does NOT retroactively tag any existing release, and does not run publish_muse_release.sh for a real release -- that remains gated on muse#63 being signed off, same as the ticket's own deferred deliverable. The code/docs work (deliverables 1-2) is unblocked by that gate; only the one-time real-release QA (deliverable 3) is not.
Targeted regression suite -- test_pep440_to_semver_tag.py (11), test_publish_muse_release_tag.py (6), test_publish_muse_release_prune.py (8, unaffected sibling), test_deployment.py (44), test_prune_releases.py (9) -- all pass (76 passed), zero regressions. bash -n confirms the script still parses as valid bash.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Semantic Changes
36 symbols
Files Changed
+3
~2
1088 in snapshot
0 comments
muse hub commit comment sha256:8c52c8464b3c4abcb640dd432b8b85bf43fb0c6adf16066d1dfa8d646ff01701 --body "your comment"
No comments yet. Be the first to start the discussion.