Add merge_approval_gate assessment so gitea_merge_pr fails closed when visible APPROVED reviews do not pin the live head SHA. Expose approval_at_current_head and stale_approval_block_reason in review feedback. Document re-review requirement in canonical merge workflow. Closes #471. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
59 lines
2.1 KiB
Python
59 lines
2.1 KiB
Python
"""Hermetic tests for merge approval head pinning (#471)."""
|
|
import sys
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
|
|
from merge_approval_gate import assess_merge_approval_head # noqa: E402
|
|
|
|
HEAD_OLD = "8b61c4b41f1b49b271ed3b99657431cf06eeda3e"
|
|
HEAD_NEW = "3e4b721d60e97147ba0704773cf57cd0d42cbe31"
|
|
|
|
|
|
class TestMergeApprovalGate(unittest.TestCase):
|
|
def test_fresh_approval_at_current_head(self):
|
|
result = assess_merge_approval_head(
|
|
current_head_sha=HEAD_NEW,
|
|
latest_by_reviewer={
|
|
"reviewer1": {
|
|
"verdict": "APPROVED",
|
|
"dismissed": False,
|
|
"reviewed_head_sha": HEAD_NEW,
|
|
"submitted_at": "2026-07-06T12:00:00Z",
|
|
}
|
|
},
|
|
)
|
|
self.assertTrue(result["approval_at_current_head"])
|
|
self.assertIsNone(result["stale_approval_block_reason"])
|
|
|
|
def test_stale_approval_after_rebase(self):
|
|
result = assess_merge_approval_head(
|
|
current_head_sha=HEAD_NEW,
|
|
latest_by_reviewer={
|
|
"reviewer1": {
|
|
"verdict": "APPROVED",
|
|
"dismissed": False,
|
|
"reviewed_head_sha": HEAD_OLD,
|
|
"submitted_at": "2026-07-06T10:00:00Z",
|
|
}
|
|
},
|
|
)
|
|
self.assertFalse(result["approval_at_current_head"])
|
|
self.assertEqual(result["latest_approved_head_sha"], HEAD_OLD)
|
|
self.assertIn("stale approval", result["stale_approval_block_reason"])
|
|
self.assertIn(HEAD_OLD, result["stale_approval_block_reason"])
|
|
self.assertIn(HEAD_NEW, result["stale_approval_block_reason"])
|
|
self.assertIn("re-review PR at current head", result["stale_approval_block_reason"])
|
|
|
|
def test_no_approval_entries(self):
|
|
result = assess_merge_approval_head(
|
|
current_head_sha=HEAD_NEW,
|
|
latest_by_reviewer={},
|
|
)
|
|
self.assertFalse(result["approval_at_current_head"])
|
|
self.assertIsNone(result["latest_approved_head_sha"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main() |