feat(forgejo): add package prune script with retention depth 3
List and optionally delete package versions beyond the newest three, protecting production Helm image tags. Adds Make targets and unit tests for ACTIVITY-WP-0020.
This commit is contained in:
parent
2806f2cdda
commit
715631dedd
5 changed files with 564 additions and 1 deletions
67
tests/test_forgejo_package_prune.py
Normal file
67
tests/test_forgejo_package_prune.py
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
REPO_DIR = Path(__file__).resolve().parents[1]
|
||||
SPEC = importlib.util.spec_from_file_location(
|
||||
"forgejo_package_prune", REPO_DIR / "scripts/forgejo_package_prune.py"
|
||||
)
|
||||
prune = importlib.util.module_from_spec(SPEC)
|
||||
assert SPEC.loader is not None
|
||||
sys.modules[SPEC.name] = prune
|
||||
SPEC.loader.exec_module(prune)
|
||||
|
||||
|
||||
class ForgejoPackagePruneTests(unittest.TestCase):
|
||||
def test_collect_protected_versions_from_helm_values(self) -> None:
|
||||
import tempfile
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
root = Path(tmpdir)
|
||||
helm = root / "helm"
|
||||
helm.mkdir()
|
||||
(helm / "vergabe-teilnahme-values.yaml").write_text(
|
||||
"""
|
||||
image:
|
||||
repository: forgejo.coulomb.social/coulomb/vergabe-teilnahme
|
||||
tag: "064d295"
|
||||
""".lstrip(),
|
||||
encoding="utf-8",
|
||||
)
|
||||
protected = prune.collect_protected_versions(root)
|
||||
self.assertIn(("container", "vergabe-teilnahme", "064d295"), protected)
|
||||
|
||||
def test_build_delete_plans_respects_depth_and_protection(self) -> None:
|
||||
protected = {("container", "vergabe-teilnahme", "old-prod")}
|
||||
versions = [
|
||||
{"version": "v4", "created_at": "2026-07-12T10:00:00Z"},
|
||||
{"version": "v3", "created_at": "2026-07-11T10:00:00Z"},
|
||||
{"version": "v2", "created_at": "2026-07-10T10:00:00Z"},
|
||||
{"version": "v1", "created_at": "2026-07-09T10:00:00Z"},
|
||||
{"version": "old-prod", "created_at": "2026-07-08T10:00:00Z"},
|
||||
]
|
||||
|
||||
with mock.patch.object(prune, "list_packages", return_value=[{"name": "vergabe-teilnahme"}]):
|
||||
with mock.patch.object(prune, "list_versions", return_value=versions):
|
||||
plans, errors = prune.build_delete_plans(
|
||||
base_url="https://forgejo.example",
|
||||
token="token",
|
||||
owner="coulomb",
|
||||
package_types=["container"],
|
||||
max_versions=3,
|
||||
protected=protected,
|
||||
)
|
||||
|
||||
self.assertEqual(errors, [])
|
||||
deletable = {(p.name, p.version) for p in plans if not p.protected}
|
||||
protected_plans = {(p.name, p.version) for p in plans if p.protected}
|
||||
self.assertEqual(deletable, {("vergabe-teilnahme", "v1")})
|
||||
self.assertEqual(protected_plans, {("vergabe-teilnahme", "old-prod")})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue