mafw.scripts.new_release
Release automation script for maintainers.
This module provides a Click-based command line interface that prepares a new MAFw release by bumping the version, updating NOTICE.txt, regenerating the changelog, optionally generating release notes, committing tracked release artifacts, creating the git tag, and optionally pushing to the remote repository.
- author:
Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
Module Attributes
Allowed Hatch version segments supported by this script. |
|
Regular expression used to parse local version strings (stable/alpha/beta/rc). |
|
Regular expression used to identify stable git tags in the form |
|
Path to the version source file managed by |
|
Path to the changelog file that is regenerated for each release. |
|
Path to the notice file containing the public project version. |
|
Path to the markdown template used to build release notes. |
|
Release note section headers used in the markdown template. |
|
Click context settings for command line help aliases. |
|
Pattern used to update the version block in |
|
Supported release kinds used to drive changelog and release-note behavior. |
Functions
|
Compute or execute the version bump depending on dry-run mode. |
Ensure the release process is executed from the |
|
|
Prevent creating a new release when a stable release is already missing a tag. |
|
Classify a version string into stable/rc/alpha/beta. |
|
Execute a subprocess command and always return a completed process object. |
|
Commit tracked release artifacts for the target version. |
|
Create the release note markdown file for the given version. |
|
Create the local git tag for the target version. |
Ensure the git working tree is clean (excluding untracked files). |
|
Extract release change sections from |
|
Extract release change sections from a changelog block. |
|
Extract the changelog block associated with the target version. |
|
|
Generate the project changelog for the target release. |
|
Collect contributor names since the baseline reference. |
Return the latest stable tag matching |
|
Determine the git reference used as baseline for release-note metadata. |
|
|
Collect release statistics since the baseline reference. |
|
Normalize the user-provided segment selector to a Hatch-compatible token list. |
|
Parse a stable tag in the form |
|
Parse a version string in the form |
|
Ensure the target release tag does not already exist. |
|
Push commits and tags to the remote repository. |
Read the project version using |
|
|
Replace a release-note section in the markdown template. |
|
Execute a command and return stripped standard output. |
|
Update the version in |
- mafw.scripts.new_release._classify_changelog_subsection(subsection_heading: str) str | None[source]
Map a changelog subsection heading to a release-note category key.
- Parameters:
subsection_heading (str) – Raw level-3 heading from changelog.
- Returns:
Category key, or
Noneif the heading is not mappable.- Return type:
str | None
- mafw.scripts.new_release._to_command_line(command: str | list[str]) str[source]
Convert a command into a printable shell-like string.
- Parameters:
command (str | list[str]) – Command expressed as a string or tokenized list.
- Returns:
Human-readable command line.
- Return type:
str
- mafw.scripts.new_release.bump_version(segment: str, *, dry_run: bool) str[source]
Compute or execute the version bump depending on dry-run mode.
Hatch is used as single source of truth for the resolved target version. In dry-run mode, the
__about__.pyfile is temporarily rewritten by Hatch and restored afterwards so the git worktree remains unchanged.- Parameters:
segment (str) – Hatch selector segments (comma-separated).
dry_run (bool) – Whether command execution is disabled.
- Returns:
New version string.
- Return type:
str
- mafw.scripts.new_release.check_main_branch() None[source]
Ensure the release process is executed from the
mainbranch.- Raises:
click.ClickException – If the current branch is not
main.
- mafw.scripts.new_release.check_missing_release(current_version: str) None[source]
Prevent creating a new release when a stable release is already missing a tag.
If the current project version is stable and ahead of the last stable git tag, the release is aborted to avoid skipping the untagged stable release.
- Parameters:
current_version (str) – Current project version.
- Raises:
click.ClickException – If a missing stable release is detected.
- mafw.scripts.new_release.classify_version(version: str) Literal['stable', 'rc', 'alpha', 'beta'][source]
Classify a version string into stable/rc/alpha/beta.
- Parameters:
version (str) – Version string to classify.
- Returns:
Classified version kind.
- Return type:
VersionKind
- Raises:
click.ClickException – If the version cannot be parsed.
- mafw.scripts.new_release.cmd(command: str | list[str], *, dry_run: bool = False, **kwargs: Any) CompletedProcess[Any][source]
Execute a subprocess command and always return a completed process object.
The command line is always printed. In dry-run mode, execution is skipped and a successful synthetic
CompletedProcessis returned.- Parameters:
command (str | list[str]) – Command to execute.
dry_run (bool) – If
True, print the command without executing it.kwargs (Any) – Additional keyword arguments forwarded to
subprocess.run.
- Returns:
Completed process produced by the command execution.
- Return type:
subprocess.CompletedProcess[Any]
- mafw.scripts.new_release.commit_changes(version: str, dry_run: bool, *, include_changelog: bool = True) None[source]
Commit tracked release artifacts for the target version.
The generated release note is intentionally not staged and remains untracked as requested.
- Parameters:
version (str) – Target release version.
dry_run (bool) – Whether command execution is disabled.
include_changelog (bool) – Whether
CHANGELOG.mdshould be staged and committed as part of the release artifacts.
- mafw.scripts.new_release.create_release_note(version: str, dry_run: bool) Path[source]
Create the release note markdown file for the given version.
Change sections are copied from the generated changelog for the same version to ensure release notes stay aligned with changelog content.
- Parameters:
version (str) – Target release version.
dry_run (bool) – Whether command execution is disabled.
- Returns:
Path to the release note markdown file.
- Return type:
Path
- Raises:
click.ClickException – If the template is missing.
- mafw.scripts.new_release.create_tag(version: str, dry_run: bool) str[source]
Create the local git tag for the target version.
- Parameters:
version (str) – Target release version.
dry_run (bool) – Whether command execution is disabled.
- Returns:
Created tag name.
- Return type:
str
- mafw.scripts.new_release.ensure_clean_git() None[source]
Ensure the git working tree is clean (excluding untracked files).
- Raises:
click.ClickException – If tracked changes are present.
- mafw.scripts.new_release.extract_change_sections_from_changelog(version: str) dict[str, str][source]
Extract release change sections from
CHANGELOG.md.- Parameters:
version (str) – Target release version without leading
v.- Returns:
Mapping from release-note category key to markdown content.
- Return type:
dict[str, str]
- Raises:
click.ClickException – If changelog file does not exist or the requested section is missing.
- mafw.scripts.new_release.extract_change_sections_from_changelog_block(changelog_block: str) dict[str, str][source]
Extract release change sections from a changelog block.
The parsing logic expects the block to contain level-3 headings (
###) with standardized labels (e.g. “New Features”, “Bug Fixes”, …).- Parameters:
changelog_block (str) – Changelog markdown block to parse.
- Returns:
Mapping from release-note category key to markdown content.
- Return type:
dict[str, str]
- mafw.scripts.new_release.extract_version_changelog_block(changelog_content: str, version: str) str[source]
Extract the changelog block associated with the target version.
- Parameters:
changelog_content (str) – Complete changelog markdown text.
version (str) – Target release version without leading
v.
- Returns:
Markdown block for the selected release.
- Return type:
str
- Raises:
click.ClickException – If no section for the target version is found.
- mafw.scripts.new_release.generate_changelog(version: str, dry_run: bool) None[source]
Generate the project changelog for the target release.
- Parameters:
version (str) – Target release version.
dry_run (bool) – Whether command execution is disabled.
- mafw.scripts.new_release.get_contributors(since_ref: str) list[str][source]
Collect contributor names since the baseline reference.
- Parameters:
since_ref (str) – Baseline reference to compare against
HEAD.- Returns:
Ordered list of contributor names.
- Return type:
list[str]
- mafw.scripts.new_release.get_last_stable_tag() str | None[source]
Return the latest stable tag matching
vX.Y.Z.- Returns:
Latest stable tag or
Nonewhen no stable tags are present.- Return type:
str | None
- mafw.scripts.new_release.get_release_note_base_ref() str[source]
Determine the git reference used as baseline for release-note metadata.
- Returns:
Last stable tag if available, otherwise the first commit hash.
- Return type:
str
- mafw.scripts.new_release.get_release_statistics(since_ref: str) tuple[str, str][source]
Collect release statistics since the baseline reference.
- Parameters:
since_ref (str) – Baseline reference to compare against
HEAD.- Returns:
Commit count and short diff statistics.
- Return type:
tuple[str, str]
- mafw.scripts.new_release.normalize_hatch_segments(segments: str) str[source]
Normalize the user-provided segment selector to a Hatch-compatible token list.
The selector supports comma-separated segments and follows Hatch semantics. Examples:
minor,rc: bump minor and create/reset an RC suffix.rc: increment the release-candidate counter only.alpha/beta: create alpha/beta pre-release suffix.release: remove any pre-release suffix (stable release).
- Parameters:
segments (str) – Raw selector as passed on the command line.
- Returns:
Normalized Hatch selector (comma-separated, lowercase, no whitespace).
- Return type:
str
- Raises:
click.ClickException – If the selector is empty or contains unsupported segments.
- mafw.scripts.new_release.parse_stable_tag(tag: str) tuple[int, int, int][source]
Parse a stable tag in the form
vX.Y.Z.- Parameters:
tag (str) – Stable tag value.
- Returns:
Parsed stable version tuple.
- Return type:
tuple[int, int, int]
- Raises:
click.ClickException – If the tag does not match
vX.Y.Z.
- mafw.scripts.new_release.parse_version(version: str) tuple[int, int, int, int | None][source]
Parse a version string in the form
X.Y.Zor with a pre-release suffix.Supported suffixes follow Hatch/PEP 440 conventions:
Release candidates:
X.Y.ZrcNAlpha releases:
X.Y.ZaNBeta releases:
X.Y.ZbN
- Parameters:
version (str) – Version string to parse.
- Returns:
Parsed major, minor, micro, and optional pre-release index.
- Return type:
tuple[int, int, int, int | None]
- Raises:
click.ClickException – If the version format is unsupported.
- mafw.scripts.new_release.prevent_duplicate_tag(version: str) None[source]
Ensure the target release tag does not already exist.
- Parameters:
version (str) – Target release version.
- Raises:
click.ClickException – If
v<version>already exists.
- mafw.scripts.new_release.push_changes(dry_run: bool) None[source]
Push commits and tags to the remote repository.
- Parameters:
dry_run (bool) – Whether command execution is disabled.
- mafw.scripts.new_release.read_current_version() str[source]
Read the project version using
hatch version.- Returns:
Current project version string.
- Return type:
str
- Raises:
click.ClickException – If the version cannot be extracted.
- mafw.scripts.new_release.render_release_note_section(content: str, header: str, section_markdown: str) str[source]
Replace a release-note section in the markdown template.
If the provided section markdown is empty, the entire section (header and placeholder) is removed from the content.
- Parameters:
content (str) – Current release note markdown text.
header (str) – Section header to replace.
section_markdown (str) – Markdown content to insert under the section header.
- Returns:
Updated markdown text.
- Return type:
str
- Raises:
click.ClickException – If the section header cannot be matched in template.
- mafw.scripts.new_release.run_stdout(command: str | list[str], *, dry_run: bool = False, **kwargs: Any) str[source]
Execute a command and return stripped standard output.
- Parameters:
command (str | list[str]) – Command to execute.
dry_run (bool) – If
True, do not execute the command.kwargs (Any) – Additional keyword arguments forwarded to
cmd.
- Returns:
Standard output stripped of leading and trailing whitespace.
- Return type:
str
- mafw.scripts.new_release.update_notice_version(version: str, dry_run: bool) None[source]
Update the version in
NOTICE.txtto match the release version.- Parameters:
version (str) – Target release version.
dry_run (bool) – Whether filesystem changes are disabled.
- Raises:
click.ClickException – If NOTICE.txt is missing or has unexpected format.
- mafw.scripts.new_release.ABOUT_FILE = PosixPath('src/mafw/__about__.py')
Path to the version source file managed by
hatch version.
- mafw.scripts.new_release.CHANGELOG_FILE = PosixPath('CHANGELOG.md')
Path to the changelog file that is regenerated for each release.
- mafw.scripts.new_release.CONTEXT_SETTINGS = {'help_option_names': ['-h', '--help']}
Click context settings for command line help aliases.
- mafw.scripts.new_release.NOTICE_FILE = PosixPath('NOTICE.txt')
Path to the notice file containing the public project version.
- mafw.scripts.new_release.NOTICE_VERSION_PATTERN = re.compile('MAFw - Modular Analysis Framework\\n\\nversion:\\s*V[0-9]+\\.[0-9]+\\.[0-9]+(?:[-a-zA-Z0-9\\.\\-_]+)?', re.MULTILINE)
Pattern used to update the version block in
NOTICE.txt.
- mafw.scripts.new_release.RELEASE_SECTION_HEADERS = {'bug_fixes': '## 🐛 Bug Fixes', 'deprecated': '## ⚠️ Deprecated', 'new_features': '## 🚀 New Features', 'other_changes': '## ️*️⃣ Other Changes', 'refactorings': '## ♻️ Refactorings', 'removed': '## 🗑️ Removals', 'security': '## 🔒 Security'}
Release note section headers used in the markdown template.
- mafw.scripts.new_release.RELEASE_TEMPLATE_FILE = PosixPath('.gitlab/release_templates/Default.md')
Path to the markdown template used to build release notes.
- mafw.scripts.new_release.STABLE_TAG_PATTERN = re.compile('^v(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<micro>\\d+)$')
Regular expression used to identify stable git tags in the form
vX.Y.Z.
- mafw.scripts.new_release.VALID_HATCH_SEGMENTS: Final[tuple[str, ...]] = ('major', 'minor', 'micro', 'rc', 'alpha', 'beta', 'release')
Allowed Hatch version segments supported by this script.
- mafw.scripts.new_release.VERSION_PATTERN = re.compile('^(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<micro>\\d+)(?:(?P<suffix>rc|a|b)(?P<suffix_num>\\d+))?$')
Regular expression used to parse local version strings (stable/alpha/beta/rc).
- mafw.scripts.new_release.VersionKind
Supported release kinds used to drive changelog and release-note behavior.
alias of
Literal[‘stable’, ‘rc’, ‘alpha’, ‘beta’]