test_post_land_sync_cycle.py python
97 lines 3.4 KB
Raw
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 1 day ago
1 """E2E tier §PLS.10 — real temp git repos: land stubbed to merged, sync via real git."""
2
3 from __future__ import annotations
4
5 import subprocess
6 from pathlib import Path
7
8 import pytest
9
10 from tests.support import gh_merged_runner, pls_config
11 from tools.close_ritual.pr_land import EXIT_OK, run_pr_land
12
13
14 def _git(cwd: Path, *args: str) -> str:
15 completed = subprocess.run(
16 ["git", *args], cwd=str(cwd), capture_output=True, text=True, check=True
17 )
18 return completed.stdout.strip()
19
20
21 @pytest.fixture
22 def land_repos(tmp_path: Path) -> tuple[Path, Path]:
23 """Return ``(work, origin)``: a clone plus a bare origin one commit ahead on main."""
24 origin = tmp_path / "origin.git"
25 origin.mkdir()
26 _git(origin, "init", "--bare", "-b", "main")
27
28 work = tmp_path / "work"
29 _git(tmp_path, "clone", str(origin), "work")
30 _git(work, "config", "user.email", "[email protected]")
31 _git(work, "config", "user.name", "test")
32 (work / "docs").mkdir()
33 (work / "docs" / "HANDOVER.md").write_text("v1\n", encoding="utf-8")
34 # Keep the test-harness config out of porcelain so "clean tree" means clean.
35 (work / ".gitignore").write_text(".overseer/\n", encoding="utf-8")
36 _git(work, "add", ".")
37 _git(work, "commit", "-m", "seed")
38 _git(work, "push", "-u", "origin", "main")
39
40 # Simulate the PR landing on GitHub main from elsewhere.
41 other = tmp_path / "other"
42 _git(tmp_path, "clone", str(origin), "other")
43 _git(other, "config", "user.email", "[email protected]")
44 _git(other, "config", "user.name", "test")
45 (other / "docs" / "HANDOVER.md").write_text("v2 landed\n", encoding="utf-8")
46 _git(other, "add", ".")
47 _git(other, "commit", "-m", "landed PR")
48 _git(other, "push", "origin", "main")
49
50 (work / ".overseer").mkdir()
51 return work, origin
52
53
54 def test_clean_feature_branch_ends_on_main_matching_origin(
55 land_repos: tuple[Path, Path],
56 ) -> None:
57 work, _origin = land_repos
58 _git(work, "checkout", "-b", "feat/pls-work")
59
60 result = run_pr_land(
61 "9",
62 authorization="operator: e2e land",
63 runner=gh_merged_runner(),
64 sleep_fn=lambda _s: None,
65 repo_root=work,
66 config=pls_config(work),
67 )
68
69 assert result.exit_code == EXIT_OK
70 assert result.post_land_sync["status"] == "synced"
71 assert _git(work, "rev-parse", "--abbrev-ref", "HEAD") == "main"
72 assert _git(work, "rev-parse", "main") == _git(work, "rev-parse", "origin/main")
73 assert (work / "docs" / "HANDOVER.md").read_text(encoding="utf-8") == "v2 landed\n"
74
75
76 def test_dirty_tree_skips_head_unchanged_exit_zero(land_repos: tuple[Path, Path]) -> None:
77 work, _origin = land_repos
78 _git(work, "checkout", "-b", "feat/pls-dirty")
79 (work / "docs" / "HANDOVER.md").write_text("uncommitted local edits\n", encoding="utf-8")
80 head_before = _git(work, "rev-parse", "HEAD")
81
82 result = run_pr_land(
83 "9",
84 authorization="operator: e2e dirty land",
85 runner=gh_merged_runner(),
86 sleep_fn=lambda _s: None,
87 repo_root=work,
88 config=pls_config(work),
89 )
90
91 assert result.exit_code == EXIT_OK
92 assert result.post_land_sync["status"] == "skipped_dirty"
93 assert _git(work, "rev-parse", "--abbrev-ref", "HEAD") == "feat/pls-dirty"
94 assert _git(work, "rev-parse", "HEAD") == head_before
95 assert (work / "docs" / "HANDOVER.md").read_text(encoding="utf-8") == (
96 "uncommitted local edits\n"
97 )
File History 1 commit
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 1 day ago