mafw.devtools.release

Release management utilities for MAFw development tools.

This package provides business logic for version bumping, changelog generation, release note creation, and git workflow operations during the release process.

Functions

bump_version(segment, *, dry_run)

Compute or execute the version bump depending on dry-run mode.

check_main_branch()

Ensure the release process is executed from the main branch.

check_missing_release(current_version)

Prevent creating a new release when a stable release is already missing a tag.

classify_version(version)

Classify a version string into stable/rc/alpha/beta.

commit_changes(version, dry_run, *[, ...])

Commit tracked release artifacts for the target version.

create_release_note(version, dry_run)

Create the release note markdown file for the given version.

create_tag(version, dry_run)

Create the local git tag for the target version.

ensure_clean_git()

Ensure the git working tree is clean (excluding untracked files).

extract_change_sections_from_changelog(version)

Extract release change sections from CHANGELOG.md.

extract_change_sections_from_changelog_block(...)

Extract release change sections from a changelog block.

extract_version_changelog_block(...)

Extract the changelog block associated with the target version.

generate_changelog(version, dry_run)

Generate the project changelog for the target release.

get_contributors(since_ref)

Collect contributor names since the baseline reference.

get_last_stable_tag()

Return the latest stable tag matching vX.Y.Z.

get_release_note_base_ref()

Determine the git reference used as baseline for release-note metadata.

get_release_statistics(since_ref)

Collect release statistics since the baseline reference.

normalize_hatch_segments(segments)

Normalize the user-provided segment selector to a Hatch-compatible token list.

parse_stable_tag(tag)

Parse a stable tag in the form vX.Y.Z.

parse_version(version)

Parse a version string in the form X.Y.Z or with a pre-release suffix.

prevent_duplicate_tag(version)

Ensure the target release tag does not already exist.

push_changes(dry_run)

Push commits and tags to the remote repository.

read_current_version()

Read the project version using hatch version.

render_release_note_section(content, header, ...)

Replace a release-note section in the markdown template.

update_doc_target_version(version, dry_run)

Update the documentation target version in src/mafw/__about__.py.

update_notice_version(version, dry_run)

Update the version in NOTICE.txt to match the release version.

Classes

DocTargetVersionPrompt(*args[, min_version])

Prompt that validates documentation target versions in major.minor form.

class mafw.devtools.release.DeprecatedOption(*args: Any, deprecated_message: str = '', **kwargs: Any)[source]

Bases: Option

A Click Option subclass that emits a DeprecationWarning when explicitly used.

Use this class as cls=DeprecatedOption in a @click.option decorator to mark an option as deprecated. The warning is only emitted when the user explicitly provides the option on the command line; default-value resolution does not trigger the warning. The resolved value is passed through to the command callback unchanged.

Parameters:

deprecated_message (str) – Warning text emitted when the option is explicitly provided on the command line.

Added in version 2.2.

consume_value(ctx: Context, opts: Mapping[str, Parameter]) tuple[Any, ParameterSource][source]

Intercept value consumption to detect explicit CLI usage.

Parameters:
  • ctx (click.Context) – Current Click context.

  • opts (Mapping[str, click.Parameter]) – Parsed option tokens from the command line.

Returns:

Tuple of (value, source) as returned by the parent implementation.

Return type:

tuple[Any, click.core.ParameterSource]

class mafw.devtools.release.DocTargetVersionPrompt(*args: Any, min_version: str | None = None, **kwargs: Any)

Bases: Prompt

Prompt that validates documentation target versions in major.minor form.

Initialize the prompt with an optional minimum allowed version.

Parameters:

min_version (str | None) – Lowest allowed documentation target version in major.minor form.

process_response(value: str) str[source]

Validate and normalize the documentation target version entered by the user.

Parameters:

value (str) – Raw user input.

Returns:

Normalized version string.

Return type:

str

Raises:

InvalidResponse – If the value does not match major.minor or is below the minimum.

mafw.devtools.release.bump_version(segment: str, *, dry_run: bool) str

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__.py file 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.devtools.release.check_main_branch() None

Ensure the release process is executed from the main branch.

Raises:

DevtoolsError – If the current branch is not main.

mafw.devtools.release.check_missing_release(current_version: str) None

Prevent creating a new release when a stable release is already missing a tag.

Parameters:

current_version (str) – Current project version.

Raises:

DevtoolsError – If a missing stable release is detected.

mafw.devtools.release.classify_version(version: str) Literal['stable', 'rc', 'alpha', 'beta']

Classify a version string into stable/rc/alpha/beta.

Parameters:

version (str) – Version string to classify.

Returns:

Classified version kind.

Return type:

str

Raises:

DevtoolsError – If the version cannot be parsed.

mafw.devtools.release.commit_changes(version: str, dry_run: bool, *, include_changelog: bool = True) None

Commit tracked release artifacts for the target version.

Parameters:
  • version (str) – Target release version.

  • dry_run (bool) – Whether command execution is disabled.

  • include_changelog (bool) – Whether CHANGELOG.md should be staged and committed as part of the release artifacts.

mafw.devtools.release.create_release_note(version: str, dry_run: bool) Path

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:

DevtoolsError – If the template is missing.

mafw.devtools.release.create_tag(version: str, dry_run: bool) str

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.devtools.release.ensure_clean_git() None

Ensure the git working tree is clean (excluding untracked files).

Raises:

DevtoolsError – If tracked changes are present.

mafw.devtools.release.extract_change_sections_from_changelog(version: str) dict[str, str]

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:

DevtoolsError – If changelog file does not exist or the requested section is missing.

mafw.devtools.release.extract_change_sections_from_changelog_block(changelog_block: str) dict[str, str]

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.devtools.release.extract_version_changelog_block(changelog_content: str, version: str) str

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:

DevtoolsError – If no section for the target version is found.

mafw.devtools.release.generate_changelog(version: str, dry_run: bool) None

Generate the project changelog for the target release.

Parameters:
  • version (str) – Target release version.

  • dry_run (bool) – Whether command execution is disabled.

mafw.devtools.release.get_contributors(since_ref: str) list[str]

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.devtools.release.get_last_stable_tag() str | None

Return the latest stable tag matching vX.Y.Z.

Returns:

Latest stable tag or None when no stable tags are present.

Return type:

str | None

mafw.devtools.release.get_release_note_base_ref() str

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.devtools.release.get_release_statistics(since_ref: str) tuple[str, str]

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.devtools.release.normalize_hatch_segments(segments: str) str

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:

DevtoolsError – If the selector is empty or contains unsupported segments.

mafw.devtools.release.parse_stable_tag(tag: str) tuple[int, int, int]

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:

DevtoolsError – If the tag does not match vX.Y.Z.

mafw.devtools.release.parse_version(version: str) tuple[int, int, int, int | None]

Parse a version string in the form X.Y.Z or with a pre-release suffix.

Supported suffixes follow Hatch/PEP 440 conventions:

  • Release candidates: X.Y.ZrcN

  • Alpha releases: X.Y.ZaN

  • Beta 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:

DevtoolsError – If the version format is unsupported.

mafw.devtools.release.prevent_duplicate_tag(version: str) None

Ensure the target release tag does not already exist.

Parameters:

version (str) – Target release version.

Raises:

DevtoolsError – If v<version> already exists.

mafw.devtools.release.push_changes(dry_run: bool) None

Push commits and tags to the remote repository.

Parameters:

dry_run (bool) – Whether command execution is disabled.

mafw.devtools.release.read_current_version() str

Read the project version using hatch version.

Returns:

Current project version string.

Return type:

str

Raises:

DevtoolsError – If the version cannot be extracted.

mafw.devtools.release.render_release_note_section(content: str, header: str, section_markdown: str) str

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:

DevtoolsError – If the section header cannot be matched in template.

mafw.devtools.release.update_doc_target_version(version: str, dry_run: bool) None

Update the documentation target version in src/mafw/__about__.py.

Parameters:
  • version (str) – Target documentation version in major.minor form.

  • dry_run (bool) – Whether filesystem changes are disabled.

mafw.devtools.release.update_notice_version(version: str, dry_run: bool) None

Update the version in NOTICE.txt to match the release version.

Parameters:
  • version (str) – Target release version.

  • dry_run (bool) – Whether filesystem changes are disabled.

Raises:

DevtoolsError – If NOTICE.txt is missing or has unexpected format.

Modules

changelog

Changelog generation and parsing utilities for MAFw releases.

checks

Release validation checks for MAFw.

notes

Release note generation utilities for MAFw releases.

versioning

Version parsing, classification, and bumping utilities for MAFw releases.