diff --git a/src/devx/ci/release.py b/src/devx/ci/release.py index 1146941..23b8d77 100644 --- a/src/devx/ci/release.py +++ b/src/devx/ci/release.py @@ -136,10 +136,14 @@ def verify_tag_consistency() -> list[str]: """ errors: list[str] = [] tags = get_all_tags() - # Sort oldest first to identify the first tag - sorted_tags = sorted(tags, key=lambda t: [int(x) for x in t.lstrip("v").split(".")]) + # Filter to version tags (vX.Y.Z) and sort oldest first + version_tags = [t for t in tags if re.match(r"^v\d+\.\d+\.\d+$", t)] + sorted_tags = sorted(version_tags, key=lambda t: [int(x) for x in t.lstrip("v").split(".")]) first_tag = sorted_tags[0] if sorted_tags else None for tag in tags: + # Skip non-version tags (e.g., branch names like "master") + if not re.match(r"^v\d+\.\d+\.\d+$", tag): + continue tag_version = tag.lstrip("v") commit_version = get_commit_version(tag) if commit_version is None: @@ -478,7 +482,7 @@ def verify_alignment() -> int: ) if result.returncode == 0 and result.stdout.strip(): all_release_commits = result.stdout.strip().split("\n") - all_tags_set = {t.lstrip("v") for t in get_all_tags()} + all_tags_set = {t.lstrip("v") for t in get_all_tags() if re.match(r"^v\d+\.\d+\.\d+$", t)} truly_untagged: list[str] = [] duplicates: list[str] = [] for line in all_release_commits: diff --git a/tests/unit/test_release.py b/tests/unit/test_release.py index e27bf3b..e3532bf 100644 --- a/tests/unit/test_release.py +++ b/tests/unit/test_release.py @@ -270,6 +270,15 @@ class TestVerifyTagConsistency: mock_tags.return_value = [] assert verify_tag_consistency() == [] + @patch("devx.ci.release.get_commit_version") + @patch("devx.ci.release.get_all_tags") + def test_non_version_tags_ignored(self, mock_tags: MagicMock, mock_cv: MagicMock) -> None: + """Non-version tags like 'master' should be skipped, not crash.""" + mock_tags.return_value = ["v0.2.0", "master", "v0.1.0"] + mock_cv.side_effect = ["0.2.0", "0.1.0"] # only version tags get checked + errors = verify_tag_consistency() + assert errors == [] + class TestGetInitVersion: def test_returns_version(self, tmp_path, monkeypatch) -> None: