from __future__ import annotations import importlib.util import json import shutil import subprocess from pathlib import Path import pytest ROOT = Path(__file__).resolve().parents[2] SCRIPT = ROOT / "scripts" / "build_release_package.py" def load_script(): spec = importlib.util.spec_from_file_location("build_release_package", SCRIPT) assert spec is not None and spec.loader is not None module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module def test_release_version_is_consistent_across_runtime_packages() -> None: version = (ROOT / "VERSION").read_text(encoding="utf-8").strip() config = (ROOT / "backend" / "app" / "core" / "config.py").read_text( encoding="utf-8" ) pyproject = (ROOT / "backend" / "pyproject.toml").read_text(encoding="utf-8") frontend = json.loads( (ROOT / "frontend" / "package.json").read_text(encoding="utf-8") ) package_lock = json.loads( (ROOT / "frontend" / "package-lock.json").read_text(encoding="utf-8") ) assert version == "1.0.0" assert f'default="{version}"' in config assert "GEOINTEL_APP_VERSION" in config assert 'version = "1.0.0"' in pyproject assert frontend["version"] == version assert package_lock["version"] == version assert package_lock["packages"][""]["version"] == version def test_release_image_carries_semantic_version_identity() -> None: dockerfile = (ROOT / "deploy" / "unraid" / "Dockerfile.all-in-one").read_text( encoding="utf-8" ) deploy = (ROOT / "deploy" / "unraid" / "deploy-release.sh").read_text( encoding="utf-8" ) assert "ARG GEOINTEL_APP_VERSION=1.0.0" in dockerfile assert 'org.opencontainers.image.version="${GEOINTEL_APP_VERSION}"' in dockerfile assert "GEOINTEL_APP_VERSION=\"$(tr -d '[:space:]' < VERSION)\"" in deploy assert "--build-arg GEOINTEL_APP_VERSION=" in deploy assert "stored_version" in deploy @pytest.mark.skipif(shutil.which("ssh-keygen") is None, reason="ssh-keygen unavailable") def test_release_package_signature_and_checksums_fail_closed(tmp_path: Path) -> None: module = load_script() key = tmp_path / "release-key" result = subprocess.run( ["ssh-keygen", "-q", "-t", "ed25519", "-N", "", "-f", str(key)], capture_output=True, text=True, check=False, ) assert result.returncode == 0, result.stderr package = tmp_path / "package" package.mkdir() evidence = package / "readiness.txt" evidence.write_text("passed\n", encoding="utf-8") nested_checksums = package / "backup" / module.CHECKSUMS_NAME nested_checksums.parent.mkdir() nested_checksums.write_text("backup evidence\n", encoding="utf-8") identity = "geointel-release" namespace = "geointel-release" (package / module.SIGNERS_NAME).write_text( f"{identity} {module.public_key(key)}\n", encoding="utf-8", ) manifest = { "schema_version": 1, "release_id": "v1.0.0", "version": "1.0.0", "scope": "Belgium and the Belgian North Sea", "signature": {"identity": identity, "namespace": namespace}, "evidence": [ { "path": evidence.name, "size_bytes": evidence.stat().st_size, "sha256": module.sha256(evidence), } ], } manifest_path = package / module.MANIFEST_NAME manifest_path.write_text(json.dumps(manifest) + "\n", encoding="utf-8") module.run( ( "ssh-keygen", "-Y", "sign", "-f", str(key), "-n", namespace, str(manifest_path), ) ) module.write_checksums(package) verified = module.verify_package(package) assert verified["release_id"] == "v1.0.0" evidence.write_text("tampered\n", encoding="utf-8") with pytest.raises(RuntimeError, match="Checksum mismatch"): module.verify_package(package) def test_release_package_cli_requires_tagged_clean_revision() -> None: source = SCRIPT.read_text(encoding="utf-8") readiness = (ROOT / "scripts" / "run_readiness_check.sh").read_text( encoding="utf-8" ) assert 'run(("git", "status", "--porcelain=v1"))' in source assert 'run(("git", "rev-list", "-n", "1", release_id))' in source assert "Image revision must equal the tagged Git commit" in source assert "ssh-keygen" in source assert "verify_checksums(package_dir)" in source assert "py_compile scripts/build_release_package.py" in readiness