-
Couldn't load subscription status.
- Fork 8
Description
Summary
Provide a helper function to centralize logic for deciding whether the RELEASE_NOTES.md file in downstream repos should be reset after tagging a release, especially when version ("default") branches like v1.x.x are used. The logic must not assume a main branch exists: many repos use a rolling version branch (vMAJOR.x.x) as the default working branch.
Motivation
At present we only develop and release from the default version branch (e.g. v1.x.x). As we evolve toward having multiple active maintenance branches (e.g. v1.4.x for fixes, while v1.x.x tracks upcoming minor work, and later v2.x.x becomes the new default), each repository would otherwise need custom Bash to decide:
- Which branch a release tag (semantic
vMAJOR.MINOR.PATCH) semantically belongs to. - Whether to reset the release notes on the branch that just produced the tag.
- When to skip resetting (e.g. patch/minor released from a maintenance branch should not reset notes on the default version branch).
Centralizing this logic avoids duplication and simplifies transition from a single default version branch workflow to multiple maintenance branches.
Desired API (Proposal)
Add something like:
from dataclasses import dataclass
from typing import Optional
@dataclass
class ReleaseNotesResetDecision:
tag: str # e.g. 'v1.4.2'
branch: str # resolved branch (e.g. 'v1.4.x' or 'v1.x.x')
perform_reset: bool # whether to reset RELEASE_NOTES.md in that branch
reason: str # human explanation for logs
def compute_release_notes_reset(
repo: Optional["git.Repo"] = None,
tag: Optional[str] = None,
default_branch: str | None = None,
) -> ReleaseNotesResetDecision:
"""Decide if/where to reset release notes for a given tag.
Assumptions:
- Repositories may use a version-pattern default branch like `v1.x.x` (no `main`).
- Maintenance branches follow patterns: `vMAJOR.MINOR.x` (e.g. `v1.4.x`).
- Optional long-lived major line branch pattern: `vMAJOR.x.x` (serving as the default branch) e.g. `v1.x.x`.
Logic:
1. Parse `tag` (`vX.Y.Z`).
2. Candidate branches (in order): `vX.Y.x`, then `vX.x.x` (if not already default branch), then provided `default_branch` (if given and different), else raise if no matching head commit.
3. Pick the first existing candidate whose HEAD commit equals the tag commit.
4. `perform_reset` is True iff:
* Chosen branch is a maintenance branch (`vX.Y.x`), OR
* Chosen branch is the default version branch (`vX.x.x`) AND this is a new major release (`Y == 0 and Z == 0`).
(So patch/minor releases on the default version branch do NOT reset.)
5. Raise informative exception if tag commit doesn't match the chosen branch head.
"""
...The return value can be consumed by a lightweight workflow script to decide whether to overwrite RELEASE_NOTES.md with the template.
Edge / Future Considerations
- Pre‑release tags (
v1.2.0-rc1) handling (likely always skip or separate flag) — future enhancement. - Allow customizing branch name patterns.
- Could later extend to drive documentation versioning actions.
Implementation Notes
- Reuse existing tag & branch parsing (
BranchVersion.parse,to_semver). - Tests should cover:
- Major release on default version branch (
v2.0.0onv2.x.x) -> reset. - Minor release on default version branch (
v1.4.0onv1.x.x) when nov1.4.xyet -> no reset. - Minor release on newly created maintenance branch (
v1.4.0tag onv1.4.x) -> reset. - Patch release on maintenance branch (
v1.4.2onv1.4.x) -> reset. - Patch release when only default version branch exists (
v1.4.2onv1.x.x) -> no reset.
- Major release on default version branch (
- Provide clear exceptions when the tag commit mismatches all candidate branch heads.
Acceptance Criteria
- Helper implemented with docstring and typing.
- Decision matrix tested for scenarios above.
- Example usage snippet (GitHub Actions) in docs/README.
Example Outcome Table (abridged)
| Tag | Branches present | Resolved branch | perform_reset | Reason |
|---|---|---|---|---|
| v2.0.0 | v2.x.x | v2.x.x | True | New major on default version branch |
| v1.4.0 | v1.x.x | v1.x.x | False | Minor on default version branch (no maintenance yet) |
| v1.4.0 | v1.x.x, v1.4.x | v1.4.x | True | Maintenance branch minor release |
| v1.4.2 | v1.x.x, v1.4.x | v1.4.x | True | Maintenance branch patch release |
| v1.4.2 | v1.x.x | v1.x.x | False | Patch on default version branch |
Let me know if you prefer alternative naming or additional signals in the decision object (e.g. enum for branch kind).