Mirror of TS ``normalizePublicVersion`` (version.ts:9-16): semver-``coerce`` the string (the FIRST version-ish number found, padded to ``maj.min.patch``) — handles ``[0.1.0] - 2026-04-19``, ``v0.5.0``, and release-please link headings — else strip a leading ``v``.
(version: str)
| 24 | |
| 25 | |
| 26 | def normalize_public_version(version: str) -> str: |
| 27 | """Mirror of TS ``normalizePublicVersion`` (version.ts:9-16): semver-``coerce`` the |
| 28 | string (the FIRST version-ish number found, padded to ``maj.min.patch``) — handles |
| 29 | ``[0.1.0] - 2026-04-19``, ``v0.5.0``, and release-please link headings — else strip |
| 30 | a leading ``v``.""" |
| 31 | trimmed = version.strip() |
| 32 | m = _VERSION_RE.search(trimmed) |
| 33 | if m: |
| 34 | # Matched digits kept VERBATIM (no int-normalization): semver coerce rejects |
| 35 | # leading-zero components (-> TS falls back to the strip-^v path, returning |
| 36 | # them unchanged), so "01.02.03" must stay "01.02.03" here too. |
| 37 | major, minor, patch = m.group(1), m.group(2) or "0", m.group(3) or "0" |
| 38 | return f"{major}.{minor}.{patch}" |
| 39 | return re.sub(r"^v", "", trimmed, flags=re.IGNORECASE) # /^v/i — case-insensitive like TS |
| 40 | |
| 41 | |
| 42 | def parse_changelog(content: str) -> dict[str, list[str]]: |