Source code for mafw.devtools.release.checks

#  Copyright 2026 European Union
#  Author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
#  SPDX-License-Identifier: EUPL-1.2
"""
Release validation checks for MAFw.

This module contains non-git business logic checks used during the release
process: tag parsing and missing-release detection.
"""

from __future__ import annotations

from mafw.devtools import DevtoolsError
from mafw.devtools.git import get_last_stable_tag
from mafw.devtools.release.versioning import (
    STABLE_TAG_PATTERN,
    classify_version,
    parse_version,
)


[docs] def parse_stable_tag(tag: str) -> tuple[int, int, int]: """Parse a stable tag in the form ``vX.Y.Z``. :param tag: Stable tag value. :type tag: str :return: Parsed stable version tuple. :rtype: tuple[int, int, int] :raises DevtoolsError: If the tag does not match ``vX.Y.Z``. """ match = STABLE_TAG_PATTERN.fullmatch(tag) if match is None: raise DevtoolsError(f'Unsupported stable tag format "{tag}".') return ( int(match.group('major')), int(match.group('minor')), int(match.group('micro')), )
[docs] def check_missing_release(current_version: str) -> None: """Prevent creating a new release when a stable release is already missing a tag. :param current_version: Current project version. :type current_version: str :raises DevtoolsError: If a missing stable release is detected. """ current_kind = classify_version(current_version) if current_kind != 'stable': return current_major, current_minor, current_micro, _ = parse_version(current_version) last_stable_tag = get_last_stable_tag() if last_stable_tag is None: return last_major, last_minor, last_micro = parse_stable_tag(last_stable_tag) current_tuple = (current_major, current_minor, current_micro) last_tuple = (last_major, last_minor, last_micro) if current_tuple > last_tuple: raise DevtoolsError( 'Missing stable release detected: ' f'last stable tag is {last_stable_tag}, but current version is v{current_version}. ' 'Tag the current stable version first, or disable this check with ' '--without-missing-release-check.' )