mafw.scripts.release_mgt

Development tool for the management of MAFw releases.

This module provides a Click-based command line interface for release maintenance tasks. It currently exposes:

  • release create to prepare 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.

  • deps latest check to validate dependency compatibility across a Python version range on CI.

  • deps oldest check as a placeholder for the oldest-supported-dependency workflow.

  • deps freeze and deps unfreeze to add and remove temporary upper bounds in pyproject.toml.

author:

Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)

Module Attributes

VALID_HATCH_SEGMENTS

Allowed Hatch version segments supported by this script.

VERSION_PATTERN

Regular expression used to parse local version strings (stable/alpha/beta/rc).

STABLE_TAG_PATTERN

Regular expression used to identify stable git tags in the form vX.Y.Z.

ABOUT_FILE

Path to the version source file managed by hatch version.

CHANGELOG_FILE

Path to the changelog file that is regenerated for each release.

NOTICE_FILE

Path to the notice file containing the public project version.

PYPROJECT_FILE

Path to the TOML file containing the project dependencies.

DEPS_REGISTRY_PACKAGE_NAME

Generic package name used for dependency reference uploads.

PYLOCK_REFERENCE_PATTERN

Regular expression used to validate dependency reference lock filenames.

RELEASE_TEMPLATE_FILE

Path to the markdown template used to build release notes.

RELEASE_SECTION_HEADERS

Release note section headers used in the markdown template.

CONTEXT_SETTINGS

Click context settings for command line help aliases.

DEFAULT_TEST_FILES

List of test files executed by default during dependency verification.

NOTICE_VERSION_PATTERN

Pattern used to update the version block in NOTICE.txt.

VersionKind

Supported release kinds used to drive changelog and release-note behavior.

DEFAULT_FREEZE_EXTRAS

Extras used when compiling dependency lockfiles for release freezing and compatibility checks.

DOC_TARGET_VERSION_PATTERN

Pattern used to validate documentation target version strings.

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.

commit_dependency_unfreeze(dry_run)

Commit the unfreezing of dependency upper bounds to main.

compute_upper_bound(lower_bound)

Compute an upper bound for a dependency based on PEP 440 compatible-release philosophy.

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.

freeze_dependencies(*, dry_run)

Freeze dependencies by adding computed upper bounds in pyproject.toml.

freeze_pyproject_toml(toml_text, *[, ...])

Freeze dependencies in a pyproject.toml payload by adding upper bounds.

freeze_requirement(requirement_text, *[, ...])

Add a computed upper bound to a requirement string, if eligible.

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.

unfreeze_dependencies(...)

Unfreeze dependencies by removing computed upper bounds in pyproject.toml.

unfreeze_pyproject_toml(toml_text, *[, ...])

Unfreeze dependencies in a pyproject.toml payload by removing computed upper bounds.

unfreeze_requirement(requirement_text)

Remove a computed upper bound from a requirement string, if it matches the computed rule.

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.

update_requirements_and_readme(*, dry_run)

Update the requirements RST files and README.rst.

Classes

DocTargetVersionPrompt(*args[, min_version])

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

class mafw.scripts.release_mgt.DocTargetVersionPrompt(*args: Any, min_version: str | None = None, **kwargs: Any)[source]

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.

validate_error_message = 'Please enter a version in major.minor form, for example 2.4.'

Message shown when the entered documentation target version is invalid.

mafw.scripts.release_mgt._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 None if the heading is not mappable.

Return type:

str | None

mafw.scripts.release_mgt._collect_compiled_dependency_versions(python_versions: list[str]) dict[str, Version][source]

Compile dependency lockfiles and collect the resolved versions they report.

The command mirrors the dependency verification workflow by invoking uv pip compile for each supported CPython version. A temporary lockfile is generated for each version and removed afterwards.

Parameters:

python_versions (list[str]) – Supported Python versions to compile.

Returns:

Mapping of package name to highest resolved version across the compiled lockfiles.

Return type:

dict[str, Version]

mafw.scripts.release_mgt._compile_dependency_lockfile(python_version: str, pylock_file: Path, extras: list[str], resolution: str | None = None, output_format: str | None = None, with_hashes: bool = False) None[source]

Compile a dependency lockfile for a specific CPython version.

Parameters:
  • python_version (str) – CPython version used for the uv pip compile run.

  • pylock_file (Path) – Output path for the generated lockfile.

  • extras (list[str]) – Project extras requested during compilation.

  • resolution (str | None) – Optional UV resolution strategy (e.g. ‘lowest-direct’, ‘highest’).

  • output_format (str | None) – Optional output format (e.g. ‘requirements.txt’).

  • with_hashes (bool) – Whether to generate hashes for the compiled requirements.

mafw.scripts.release_mgt._compile_python_selector(python_version: str) str[source]

Build the Python selector used by uv for dependency compilation.

For Python 3.14 and newer, request the GIL-enabled variant explicitly so free-threaded interpreters do not leak into dependency resolution.

This distinction is still needed because of the psycopg

Parameters:

python_version (str) – Base Python version in major.minor form.

Returns:

Python selector string passed to uv.

Return type:

str

mafw.scripts.release_mgt._compute_doc_target_version(version: str, segments: str, override: str | None = None) str[source]

Determine the new documentation target version for a release.

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

  • segments (str) – Normalized Hatch selector used for the release.

  • override (str | None) – Optional explicit documentation target override.

Returns:

Documentation target version in major.minor form.

Return type:

str

mafw.scripts.release_mgt._download_pylock_reference(api_config: GitlabAPIConfiguration, python_version: str, file_name: str, package_version: str, output_dir: Path, *, quiet_if_missing: bool = False) Path | None[source]

Download a single dependency reference file from the GitLab registry.

Parameters:
  • api_config (GitlabAPIConfiguration) – GitLab API configuration.

  • python_version (str) – Python version associated with the reference.

  • file_name (str) – Name of the reference file in the registry.

  • package_version (str) – Registry package version label.

  • output_dir (Path) – Directory where the file should be downloaded.

  • quiet_if_missing (bool) – If True, do not print a message if the file is missing.

Returns:

Path to the downloaded file, or None if not found.

Return type:

Path | None

mafw.scripts.release_mgt._ensure_mafw_project_root() list[str][source]

Ensure the current working directory is the MAFw project root.

Returns:

Validated supported Python versions from tool.mafw.supported-python.

Return type:

list[str]

Raises:

click.ClickException – If pyproject.toml is missing or does not identify MAFw.

mafw.scripts.release_mgt._format_requirement(requirement: Requirement) str[source]

Serialize a packaging requirement object back to a PEP 508 compatible string.

Parameters:

requirement (Requirement) – Parsed requirement instance.

Returns:

PEP 508 requirement string.

Return type:

str

mafw.scripts.release_mgt._get_expected_lower_bounds() dict[str, Requirement][source]

Read pyproject.toml and extract dependencies with their expected lower bounds.

Returns:

A dictionary mapping lowercase package names to their parsed Requirement objects.

Return type:

dict[str, Requirement]

Raises:

click.ClickException – If the pyproject.toml cannot be parsed.

mafw.scripts.release_mgt._has_frozen_upper_bound(requirement: Requirement) bool[source]

Determine whether a requirement already contains an upper bound constraint.

Parameters:

requirement (Requirement) – Parsed requirement instance.

Returns:

True if the requirement is already frozen.

Return type:

bool

mafw.scripts.release_mgt._highest_lower_bound(requirement: Requirement) str | None[source]

Extract the highest lower-bound version from >= and > specifiers.

Parameters:

requirement (Requirement) – Parsed requirement instance.

Returns:

Highest lower bound version string, or None if missing.

Return type:

str | None

Raises:

click.ClickException – If version parsing fails.

mafw.scripts.release_mgt._iter_specifiers(requirement: Requirement) list[Specifier][source]

Return a concrete list of specifiers for the given requirement.

Parameters:

requirement (Requirement) – Parsed requirement instance.

Returns:

List of specifier objects.

Return type:

list[Specifier]

mafw.scripts.release_mgt._load_pyproject_doc(toml_text: str) TOMLDocument[source]

Parse a pyproject.toml payload once and return the TOML document.

Parameters:

toml_text (str) – Raw TOML payload.

Returns:

Parsed TOML document.

Return type:

tomlkit.TOMLDocument

Raises:

click.ClickException – If the TOML payload cannot be parsed.

mafw.scripts.release_mgt._next_minor_version(version: str) str[source]

Compute the next major.minor target from a release version.

Parameters:

version (str) – Release version in major.minor.micro form.

Returns:

Next documentation target version.

Return type:

str

mafw.scripts.release_mgt._normalize_mafw_version_option(value: str | None) str[source]

Return the registry label version, defaulting to the current MAFw version.

mafw.scripts.release_mgt._normalize_pylock_input(item: str) tuple[str, str][source]

Normalize a dependency registry item into its Python version and file name.

mafw.scripts.release_mgt._parse_major_minor(version: str) tuple[int, int][source]

Parse a version string in major.minor form.

Parameters:

version (str) – Version string to parse.

Returns:

Parsed major and minor components.

Return type:

tuple[int, int]

Raises:

click.ClickException – If the version format is invalid.

mafw.scripts.release_mgt._parse_python_version(version: str) tuple[int, int][source]

Parse a Python version string in major.minor form.

Parameters:

version (str) – Python version string.

Returns:

Major/minor version tuple.

Return type:

tuple[int, int]

Raises:

click.ClickException – If the version is invalid.

mafw.scripts.release_mgt._project_python_versions() list[str][source]

Read the supported CPython versions from tool.mafw.supported-python list in pyproject.toml.

The field is expected to be a list of strings representing CPython major.minor versions. The helper validates each entry and returns a sorted, de-duplicated list so downstream callers have deterministic ordering.

Returns:

Sorted list of supported CPython versions.

Return type:

list[str]

Raises:

click.ClickException – If pyproject.toml cannot be parsed or the field contains unsupported values.

mafw.scripts.release_mgt._project_python_versions_from_doc(doc: TOMLDocument) list[str][source]

Extract supported CPython versions from a parsed pyproject.toml document.

Parameters:

doc (tomlkit.TOMLDocument) – Parsed TOML document.

Returns:

Sorted list of supported CPython versions.

Return type:

list[str]

Raises:

click.ClickException – If the tool.mafw.supported-python field is invalid.

mafw.scripts.release_mgt._python_versions_between(min_python_ver: str, max_python_ver: str, supported_versions: list[str]) list[str][source]

Build the inclusive list of Python versions between two bounds.

The returned versions must also be present in supported_versions.

Parameters:
  • min_python_ver (str) – Minimum Python version.

  • max_python_ver (str) – Maximum Python version.

  • supported_versions (list[str]) – List of supported Python versions from project metadata.

Returns:

Ordered list of version strings.

Return type:

list[str]

mafw.scripts.release_mgt._read_compiled_dependency_versions(pylock_text: str) dict[str, Version][source]

Read resolved dependency versions from a compiled lockfile payload.

The returned mapping stores the highest resolved version seen for each dependency name, normalized to lowercase for stable lookups.

Parameters:

pylock_text (str) – Raw pylock.pyX.Y.toml content.

Returns:

Mapping of package name to highest resolved version.

Return type:

dict[str, Version]

Raises:

click.ClickException – If the TOML payload cannot be parsed.

mafw.scripts.release_mgt._registry_api_config(ctx: Context) GitlabAPIConfiguration[source]

Build the GitLab API configuration stored in the Click context.

mafw.scripts.release_mgt._run_pip_audit(req_file: Path, output_file: Path, output_format: str) CompletedProcess[Any][source]

Run pip-audit on a requirements file and save the output.

Parameters:
  • req_file (Path) – Requirements file to audit.

  • output_file (Path) – Path to the output report.

  • output_format (str) – Format of the report (e.g. ‘markdown’, ‘json’).

Returns:

Completed process produced by the command execution.

Return type:

subprocess.CompletedProcess[Any]

mafw.scripts.release_mgt._summarize_freeze_changes(before: str, after: str) str[source]

Build a short summary for dry-run output.

Parameters:
  • before (str) – Original TOML content.

  • after (str) – Updated TOML content.

Returns:

Human-readable summary line.

Return type:

str

mafw.scripts.release_mgt._update_dependency_list(dependencies: Any, *, transformer: Callable[[str], tuple[str, list[str]]], warnings: list[str], context: str) None[source]

Update a TOML list of dependency strings in-place.

Parameters:
  • dependencies (Any) – TOML array that contains dependency strings.

  • transformer (Any) – Callable applied to each dependency string.

  • warnings (list[str]) – List of warnings to append to.

  • context (str) – Human-readable location for warnings.

mafw.scripts.release_mgt._upload_pylock_reference(api_config: GitlabAPIConfiguration, python_version: str, file_path: Path, package_version: str) None[source]

Upload a single dependency reference file to the GitLab registry.

Parameters:
  • api_config (GitlabAPIConfiguration) – GitLab API configuration.

  • python_version (str) – Python version associated with the reference.

  • file_path (Path) – Path to the local reference file.

  • package_version (str) – Registry package version label.

mafw.scripts.release_mgt._validate_doc_target_version(version: str) str[source]

Validate a documentation target version string.

Parameters:

version (str) – Version string to validate.

Returns:

Normalized version string.

Return type:

str

Raises:

click.ClickException – If the version format is invalid.

mafw.scripts.release_mgt._verify_lowest_resolution(env_name: str, python_version: str, expected_bounds: dict[str, Requirement]) None[source]

Verify that the specified environment has the expected lowest dependency versions.

This function executes uv pip list in the given environment, parses the output, and compares installed versions against the expected lower bounds extracted from pyproject.toml.

Parameters:
  • env_name (str) – The name of the environment (e.g., ‘hatch-test’, ‘types’).

  • python_version (str) – The Python version string (e.g., ‘3.11’).

  • expected_bounds (dict[str, Requirement]) – Mapping of package names to their Requirement objects.

Raises:

click.ClickException – If a required dependency is missing.

mafw.scripts.release_mgt.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__.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.scripts.release_mgt.check_main_branch() None[source]

Ensure the release process is executed from the main branch.

Raises:

click.ClickException – If the current branch is not main.

mafw.scripts.release_mgt.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.release_mgt.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.release_mgt.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.md should be staged and committed as part of the release artifacts.

mafw.scripts.release_mgt.commit_dependency_unfreeze(dry_run: bool) None[source]

Commit the unfreezing of dependency upper bounds to main.

Parameters:

dry_run (bool) – Whether command execution is disabled.

mafw.scripts.release_mgt.compute_upper_bound(lower_bound: str) str[source]

Compute an upper bound for a dependency based on PEP 440 compatible-release philosophy.

The rule implemented here is purposely conservative and mirrors the intent of compatible release clauses while remaining explicit:

  • For major-versioned releases (X.* with X > 0), freeze to <(X + 1).

  • For 0.* releases, freeze to <0.(minor + 1) (rolling compatibility during pre-1.0).

Parameters:

lower_bound (str) – Version string used as the starting point for the freeze rule.

Returns:

Upper-bound version string without operator.

Return type:

str

Raises:

click.ClickException – If the version cannot be parsed.

mafw.scripts.release_mgt.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.release_mgt.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.release_mgt.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.release_mgt.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.release_mgt.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.release_mgt.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.release_mgt.freeze_dependencies(*, dry_run: bool) str[source]

Freeze dependencies by adding computed upper bounds in pyproject.toml.

Parameters:

dry_run (bool) – Whether command execution is disabled.

Returns:

Original pyproject.toml content captured before freeze.

Return type:

str

mafw.scripts.release_mgt.freeze_pyproject_toml(toml_text: str, *, resolved_versions: dict[str, Version] | None = None, doc: TOMLDocument | None = None) tuple[str, list[str]][source]

Freeze dependencies in a pyproject.toml payload by adding upper bounds.

The TOML structure is preserved via tomlkit; only dependency strings may be normalized.

When resolved_versions is provided, the function uses those compiled versions as the basis for upper-bound computation. Otherwise the declared lower bounds are used as a fallback.

Parameters:
  • toml_text (str) – Raw TOML file content.

  • resolved_versions (dict[str, Version] | None) – Optional mapping of dependency names to resolved versions.

  • doc (tomlkit.TOMLDocument | None) – Optional pre-parsed TOML document to reuse when available.

Returns:

Updated TOML plus warnings.

Return type:

tuple[str, list[str]]

Raises:

click.ClickException – If TOML parsing fails.

mafw.scripts.release_mgt.freeze_requirement(requirement_text: str, *, resolved_version: str | None = None) tuple[str, list[str]][source]

Add a computed upper bound to a requirement string, if eligible.

The function is intentionally conservative:

  • URL-based requirements are skipped (cannot be version constrained).

  • Requirements already containing <, <=, ~=, == or === are skipped.

  • Requirements without a lower bound emit a warning and are left unchanged.

  • When a resolved version is provided, the upper bound is computed from that version instead of the declared lower bound.

Parameters:

requirement_text (str) – Raw PEP 508 requirement string.

Returns:

Updated requirement text plus warnings.

Return type:

tuple[str, list[str]]

Raises:

click.ClickException – If parsing fails.

mafw.scripts.release_mgt.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.release_mgt.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.release_mgt.get_last_stable_tag() str | None[source]

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.scripts.release_mgt.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.release_mgt.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.release_mgt.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.release_mgt.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.release_mgt.parse_version(version: str) tuple[int, int, int, int | None][source]

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:

click.ClickException – If the version format is unsupported.

mafw.scripts.release_mgt.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.release_mgt.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.release_mgt.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.release_mgt.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.release_mgt.unfreeze_dependencies(original_pyproject_toml: str, *, dry_run: bool) None[source]

Unfreeze dependencies by removing computed upper bounds in pyproject.toml.

Parameters:

dry_run (bool) – Whether command execution is disabled.

mafw.scripts.release_mgt.unfreeze_pyproject_toml(toml_text: str, *, baseline_toml_text: str | None = None, doc: TOMLDocument | None = None, baseline_doc: TOMLDocument | None = None) tuple[str, list[str]][source]

Unfreeze dependencies in a pyproject.toml payload by removing computed upper bounds.

Only upper bounds matching the computed rule are removed; existing manual constraints remain.

Parameters:
  • toml_text (str) – Raw TOML file content.

  • baseline_toml_text (str | None) – Optional original TOML text captured before freezing. When provided, unfreezing is computed against the baseline to avoid altering dependencies that were already frozen before release.

  • doc (tomlkit.TOMLDocument | None) – Optional pre-parsed TOML document to reuse when available.

  • baseline_doc (tomlkit.TOMLDocument | None) – Optional pre-parsed baseline TOML document to reuse when available.

Returns:

Updated TOML plus warnings.

Return type:

tuple[str, list[str]]

Raises:

click.ClickException – If TOML parsing fails.

mafw.scripts.release_mgt.unfreeze_requirement(requirement_text: str) tuple[str, list[str]][source]

Remove a computed upper bound from a requirement string, if it matches the computed rule.

Only the auto-generated upper bound <upper is removed; existing manual upper bounds are preserved.

Parameters:

requirement_text (str) – Raw PEP 508 requirement string.

Returns:

Updated requirement text plus warnings.

Return type:

tuple[str, list[str]]

Raises:

click.ClickException – If parsing fails.

mafw.scripts.release_mgt.update_doc_target_version(version: str, dry_run: bool) None[source]

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.scripts.release_mgt.update_notice_version(version: str, dry_run: bool) None[source]

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:

click.ClickException – If NOTICE.txt is missing or has unexpected format.

mafw.scripts.release_mgt.update_requirements_and_readme(*, dry_run: bool) None[source]

Update the requirements RST files and README.rst.

Parameters:

dry_run (bool) – Whether command execution is disabled.

mafw.scripts.release_mgt.ABOUT_FILE = PosixPath('src/mafw/__about__.py')

Path to the version source file managed by hatch version.

mafw.scripts.release_mgt.CHANGELOG_FILE = PosixPath('CHANGELOG.md')

Path to the changelog file that is regenerated for each release.

mafw.scripts.release_mgt.CONTEXT_SETTINGS = {'help_option_names': ['-h', '--help']}

Click context settings for command line help aliases.

mafw.scripts.release_mgt.DEFAULT_FREEZE_EXTRAS: Final[tuple[str, ...]] = ('seaborn', 'all-db', 'steering-gui')

Extras used when compiling dependency lockfiles for release freezing and compatibility checks.

mafw.scripts.release_mgt.DEFAULT_TEST_FILES: Final[list[str]] = ['tests/test_full_integration.py']

List of test files executed by default during dependency verification.

mafw.scripts.release_mgt.DEPS_REGISTRY_PACKAGE_NAME: Final[str] = 'mafw-deps'

Generic package name used for dependency reference uploads.

mafw.scripts.release_mgt.DOC_TARGET_VERSION_PATTERN = re.compile('^\\d+\\.\\d+$')

Pattern used to validate documentation target version strings.

mafw.scripts.release_mgt.NOTICE_FILE = PosixPath('NOTICE.txt')

Path to the notice file containing the public project version.

mafw.scripts.release_mgt.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.release_mgt.PYLOCK_REFERENCE_PATTERN = re.compile('^pylock\\.py(?P<python_version>3\\.\\d+)_ref\\.toml$')

Regular expression used to validate dependency reference lock filenames.

mafw.scripts.release_mgt.PYPROJECT_FILE = PosixPath('pyproject.toml')

Path to the TOML file containing the project dependencies.

mafw.scripts.release_mgt.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.release_mgt.RELEASE_TEMPLATE_FILE = PosixPath('.gitlab/release_templates/Default.md')

Path to the markdown template used to build release notes.

mafw.scripts.release_mgt.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.release_mgt.VALID_HATCH_SEGMENTS: Final[tuple[str, ...]] = ('major', 'minor', 'micro', 'rc', 'alpha', 'beta', 'release')

Allowed Hatch version segments supported by this script.

mafw.scripts.release_mgt.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.release_mgt.VersionKind

Supported release kinds used to drive changelog and release-note behavior.

alias of Literal[‘stable’, ‘rc’, ‘alpha’, ‘beta’]

mafw.scripts.release_mgt._FREEZE_PYLOCK_PATTERN: Final[Pattern[str]] = re.compile('^pylock\\.py(?P<python_version>\\d+\\.\\d+)\\.toml$')

Pattern used to identify compiled dependency lockfiles produced by uv pip compile.

mafw.scripts.release_mgt._FROZEN_OPERATORS: Final[set[str]] = {'<', '<=', '==', '===', '~='}

Operators that already constrain the maximum compatible version and should not be auto-frozen.

mafw.scripts.release_mgt._PYTHON_VERSION_RE: Final[Pattern[str]] = re.compile('^\\d+\\.\\d+$')

Pattern used to identify supported CPython version selectors.