CI / security-codeql (push) Blocked by required conditions
CI / test-unit (push) Blocked by required conditions
CI / test-integration (push) Blocked by required conditions
CI / test-env-virtual (push) Blocked by required conditions
CI / test-env-nix (push) Blocked by required conditions
CI / test-e2e (push) Blocked by required conditions
CI / test-virgin-user (push) Blocked by required conditions
CI / test-virgin-root (push) Blocked by required conditions
CI / lint-shell (push) Blocked by required conditions
CI / lint-python (push) Blocked by required conditions
CI / lint-docker (push) Blocked by required conditions
Docker Linter / Lint Dockerfile (push) Blocked by required conditions
CodeQL Advanced / Check security (none, actions) (push) Blocked by required conditions
CodeQL Advanced / Check security (none, python) (push) Blocked by required conditions
Test Units / test-unit (push) Blocked by required conditions
Test Code Integration / test-integration (push) Blocked by required conditions
Test OS Containers / test-env-virtual (arch) (push) Blocked by required conditions
Test OS Containers / test-env-virtual (centos) (push) Blocked by required conditions
Test OS Containers / test-env-virtual (debian) (push) Blocked by required conditions
Test OS Containers / test-env-virtual (fedora) (push) Blocked by required conditions
Test OS Containers / test-env-virtual (ubuntu) (push) Blocked by required conditions
Test Virgin Nix (flake only) / test-env-nix (arch) (push) Blocked by required conditions
Test Virgin Nix (flake only) / test-env-nix (centos) (push) Blocked by required conditions
Test Virgin Nix (flake only) / test-env-nix (debian) (push) Blocked by required conditions
Test Virgin Nix (flake only) / test-env-nix (fedora) (push) Blocked by required conditions
Test Virgin Nix (flake only) / test-env-nix (ubuntu) (push) Blocked by required conditions
Test End-To-End / test-e2e (arch) (push) Blocked by required conditions
Test End-To-End / test-e2e (centos) (push) Blocked by required conditions
Test End-To-End / test-e2e (debian) (push) Blocked by required conditions
Test End-To-End / test-e2e (fedora) (push) Blocked by required conditions
Test End-To-End / test-e2e (ubuntu) (push) Blocked by required conditions
Test Virgin User / test-virgin-user (arch) (push) Blocked by required conditions
Test Virgin User / test-virgin-user (centos) (push) Blocked by required conditions
Test Virgin User / test-virgin-user (debian) (push) Blocked by required conditions
Test Virgin User / test-virgin-user (fedora) (push) Blocked by required conditions
Test Virgin User / test-virgin-user (ubuntu) (push) Blocked by required conditions
Test Virgin Root / test-virgin-root (arch) (push) Blocked by required conditions
Test Virgin Root / test-virgin-root (centos) (push) Blocked by required conditions
Test Virgin Root / test-virgin-root (debian) (push) Blocked by required conditions
Test Virgin Root / test-virgin-root (fedora) (push) Blocked by required conditions
Test Virgin Root / test-virgin-root (ubuntu) (push) Blocked by required conditions
ShellCheck / lint-shell (push) Blocked by required conditions
Ruff (Python code sniffer) / lint-python (push) Blocked by required conditions
The release base used to be the latest v* tag only. It is now the highest version found in that tag and in every file the release writes: pyproject.toml, CHANGELOG.md, flake.nix, PKGBUILD, the RPM spec, debian/changelog and Cargo.toml. A lagging file can no longer lower the base and a file ahead of the tag raises it; when the sources disagree the release says so and names the version it starts from. Repos whose sources agree release exactly as before. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
95 lines
3.4 KiB
Python
95 lines
3.4 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
import tempfile
|
|
import unittest
|
|
from unittest.mock import patch
|
|
|
|
from pkgmgr.actions.release.versioning import (
|
|
bump_semver,
|
|
determine_current_version,
|
|
)
|
|
from pkgmgr.core.version.semver import SemVer
|
|
|
|
|
|
class TestDetermineCurrentVersion(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
self._tmp = tempfile.TemporaryDirectory()
|
|
self.repo = self._tmp.name
|
|
|
|
def tearDown(self) -> None:
|
|
self._tmp.cleanup()
|
|
|
|
def _write(self, name: str, content: str) -> None:
|
|
with open(os.path.join(self.repo, name), "w", encoding="utf-8") as f:
|
|
f.write(content)
|
|
|
|
@patch("pkgmgr.actions.release.versioning.get_tags", return_value=[])
|
|
def test_determine_current_version_no_tags_returns_zero(
|
|
self,
|
|
mock_get_tags,
|
|
) -> None:
|
|
ver = determine_current_version(self.repo)
|
|
self.assertIsInstance(ver, SemVer)
|
|
self.assertEqual((ver.major, ver.minor, ver.patch), (0, 0, 0))
|
|
mock_get_tags.assert_called_once()
|
|
|
|
@patch("pkgmgr.actions.release.versioning.find_latest_version")
|
|
@patch("pkgmgr.actions.release.versioning.get_tags")
|
|
def test_determine_current_version_uses_latest_semver_tag(
|
|
self,
|
|
mock_get_tags,
|
|
mock_find_latest_version,
|
|
) -> None:
|
|
mock_get_tags.return_value = ["v0.1.0", "v1.2.3"]
|
|
mock_find_latest_version.return_value = ("v1.2.3", SemVer(1, 2, 3))
|
|
|
|
ver = determine_current_version(self.repo)
|
|
|
|
self.assertEqual((ver.major, ver.minor, ver.patch), (1, 2, 3))
|
|
mock_get_tags.assert_called_once()
|
|
mock_find_latest_version.assert_called_once_with(["v0.1.0", "v1.2.3"])
|
|
|
|
@patch("pkgmgr.actions.release.versioning.get_tags", return_value=["v0.3.0"])
|
|
def test_lagging_cargo_version_does_not_lower_the_base(self, _tags) -> None:
|
|
self._write("Cargo.toml", '[package]\nname = "x"\nversion = "0.1.0"\n')
|
|
self._write("CHANGELOG.md", "# Changelog\n\n## [0.3.0] - 2026-10-30\n")
|
|
|
|
self.assertEqual(determine_current_version(self.repo), SemVer(0, 3, 0))
|
|
|
|
@patch("pkgmgr.actions.release.versioning.get_tags", return_value=["v1.0.0"])
|
|
def test_file_ahead_of_the_tag_raises_the_base(self, _tags) -> None:
|
|
self._write("pyproject.toml", '[project]\nname = "x"\nversion = "1.4.0"\n')
|
|
self._write(
|
|
"CHANGELOG.md",
|
|
"# Changelog\n\n## [Unreleased]\n\n## [1.0.0] - 2026-10-01\n",
|
|
)
|
|
|
|
self.assertEqual(determine_current_version(self.repo), SemVer(1, 4, 0))
|
|
|
|
|
|
class TestBumpSemVer(unittest.TestCase):
|
|
def test_bump_semver_major(self) -> None:
|
|
base = SemVer(1, 2, 3)
|
|
bumped = bump_semver(base, "major")
|
|
self.assertEqual((bumped.major, bumped.minor, bumped.patch), (2, 0, 0))
|
|
|
|
def test_bump_semver_minor(self) -> None:
|
|
base = SemVer(1, 2, 3)
|
|
bumped = bump_semver(base, "minor")
|
|
self.assertEqual((bumped.major, bumped.minor, bumped.patch), (1, 3, 0))
|
|
|
|
def test_bump_semver_patch(self) -> None:
|
|
base = SemVer(1, 2, 3)
|
|
bumped = bump_semver(base, "patch")
|
|
self.assertEqual((bumped.major, bumped.minor, bumped.patch), (1, 2, 4))
|
|
|
|
def test_bump_semver_invalid_type_raises(self) -> None:
|
|
base = SemVer(1, 2, 3)
|
|
with self.assertRaises(ValueError):
|
|
bump_semver(base, "invalid-type")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|