diff --git a/tests/test_version_alignment.py b/tests/test_version_alignment.py index f1b4e30..f050635 100644 --- a/tests/test_version_alignment.py +++ b/tests/test_version_alignment.py @@ -6,6 +6,7 @@ import subprocess import sys import tempfile import unittest +from unittest.mock import patch META_ROOT = Path(__file__).resolve().parents[1] @@ -20,6 +21,7 @@ from govoplan_release.version_alignment import ( # noqa: E402 repository_version_issues, selected_repository_version_issues, ) +from govoplan_release.git_state import sanitized_git_environment # noqa: E402 from govoplan_release.model import ( # noqa: E402 CatalogSnapshot, DashboardSummary, @@ -398,6 +400,68 @@ class VersionAlignmentTests(unittest.TestCase): ) self.assertTrue(all("must contain" in issue.message for issue in issues)) + def test_annotated_release_tags_work_with_sanitized_git_configuration(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + workspace = Path(tmp) + meta = workspace / "govoplan" + core = workspace / "govoplan-core" + module = workspace / "govoplan-example" + meta.mkdir() + (core / "webui").mkdir(parents=True) + (module / "webui").mkdir(parents=True) + backend_ref = "git+ssh://git@example.test/acme/govoplan-example.git@v1.2.3" + webui_ref = "git+ssh://git@example.test/acme/govoplan-example.git#v1.2.3" + (meta / "requirements-release.txt").write_text(f"govoplan-example @ {backend_ref}\n") + (module / "pyproject.toml").write_text('[project]\nname="govoplan-example"\nversion="1.2.3"\n') + (module / "webui" / "package.json").write_text( + '{"name":"@govoplan/example-webui","version":"1.2.3"}\n' + ) + subprocess.run(["git", "init", "-q", str(module)], check=True) + subprocess.run(["git", "-C", str(module), "config", "user.email", "test@example.test"], check=True) + subprocess.run(["git", "-C", str(module), "config", "user.name", "Test"], check=True) + subprocess.run(["git", "-C", str(module), "add", "pyproject.toml", "webui/package.json"], check=True) + subprocess.run(["git", "-C", str(module), "commit", "-qm", "release"], check=True) + subprocess.run( + ["git", "-C", str(module), "tag", "-a", "v1.2.3", "-m", "Release v1.2.3"], + check=True, + ) + tagged_commit = subprocess.run( + ["git", "-C", str(module), "rev-parse", "refs/tags/v1.2.3^{commit}"], + check=True, + text=True, + stdout=subprocess.PIPE, + ).stdout.strip() + dependencies = {"@govoplan/example-webui": webui_ref} + (core / "pyproject.toml").write_text('[project]\nname="govoplan-core"\nversion="2.0.0"\n') + (core / "webui" / "package.release.json").write_text( + json.dumps({"version": "2.0.0", "dependencies": dependencies}) + ) + (core / "webui" / "package-lock.release.json").write_text( + json.dumps( + { + "packages": { + "": {"version": "2.0.0", "dependencies": dependencies}, + "node_modules/@govoplan/example-webui": { + "version": "1.2.3", + "resolved": f"git+ssh://git@example.test/acme/govoplan-example.git#{tagged_commit}", + }, + } + } + ) + ) + + git_environment = sanitized_git_environment() + git_environment["GIT_TEST_ASSUME_DIFFERENT_OWNER"] = "1" + with patch( + "govoplan_release.version_alignment.sanitized_git_environment", + return_value=git_environment, + ): + composition_issues = release_composition_issues(meta, core_root=core) + core_issues = repository_version_issues(core) + + self.assertEqual((), composition_issues) + self.assertEqual((), core_issues) + if __name__ == "__main__": unittest.main() diff --git a/tools/release/govoplan_release/version_alignment.py b/tools/release/govoplan_release/version_alignment.py index 2cd8af7..fcb2e2c 100644 --- a/tools/release/govoplan_release/version_alignment.py +++ b/tools/release/govoplan_release/version_alignment.py @@ -681,10 +681,22 @@ def _git_lock_resolution_issues( def _git_tag_commit(repo_path: Path, tag: str) -> str | None: + repo_path = repo_path.resolve() if not (repo_path / ".git").exists(): return None result = subprocess.run( - ["/usr/bin/git", "-C", str(repo_path), "rev-list", "-n", "1", tag], + [ + "/usr/bin/git", + "-c", + "core.hooksPath=/dev/null", + "-c", + f"safe.directory={repo_path}", + "-C", + str(repo_path), + "rev-parse", + "--verify", + f"refs/tags/{tag}^{{commit}}", + ], check=False, text=True, stdout=subprocess.PIPE, @@ -697,10 +709,22 @@ def _git_tag_commit(repo_path: Path, tag: str) -> str | None: def _git_tag_file(repo_path: Path, tag: str, relative_path: str) -> str | None: + repo_path = repo_path.resolve() if not (repo_path / ".git").exists(): return None result = subprocess.run( - ["/usr/bin/git", "-C", str(repo_path), "show", f"{tag}:{relative_path}"], + [ + "/usr/bin/git", + "-c", + "core.hooksPath=/dev/null", + "-c", + f"safe.directory={repo_path}", + "-C", + str(repo_path), + "cat-file", + "blob", + f"refs/tags/{tag}^{{commit}}:{relative_path}", + ], check=False, text=True, stdout=subprocess.PIPE,