Files
msime-windows/tests/test_release_pr_ci.py
Evan ee4334dddd fix(ci): attach automatic release checks to the pull request (#175)
* ci(codeql): 避免版本元数据 PR 产生待人工批准的扫描

* fix(ci): attach release validation to the pull request
2026-09-06 11:10:05 +09:00

71 lines
2.6 KiB
Python

"""Exercise the release merge gate with a fake GitHub CLI and no network or writes."""
import json
import os
from pathlib import Path
import subprocess
import tempfile
import unittest
SCRIPT = Path(__file__).resolve().parents[1] / 'scripts/ci/land-release-pr.sh'
SHA = 'a' * 40
FAKE_GH = r'''#!/usr/bin/env python3
import json, os, sys
args = sys.argv[1:]
with open(os.environ['CALL_LOG'], 'a') as log:
log.write(json.dumps(args) + '\n')
if args[:2] == ['api', 'repos/test/repo/git/matching-refs/heads/release-please--']:
print('release-please--branches--main')
elif args[:2] == ['pr', 'list']:
print('12')
elif args[:2] == ['pr', 'view']:
if 'mergeCommit' in args:
print('b' * 40)
else:
print(json.dumps(dict(state='OPEN', isDraft=False,
headRefName='release-please--branches--main', headRefOid='a'*40, baseRefName='main')))
elif args[:2] == ['run', 'list']:
assert args[args.index('--event')+1] == 'pull_request'
assert 'a'*40 in args[args.index('--jq')+1]
print('123')
elif args[:2] == ['run', 'watch']:
assert args[2] == '123' and '--exit-status' in args
sys.exit(int(os.environ['CI_RESULT']))
elif args[:2] == ['pr', 'merge']:
assert '--admin' not in args and '--auto' not in args
assert args[args.index('--match-head-commit')+1] == 'a'*40
elif args[0] == 'api' and '/compare/' in args[1]:
print('ahead')
else:
raise AssertionError(args)
'''
class ReleasePRCI(unittest.TestCase):
def run_gate(self, result):
with tempfile.TemporaryDirectory() as directory:
directory = Path(directory)
gh = directory / 'gh'
gh.write_text(FAKE_GH)
gh.chmod(0o755)
log = directory / 'calls.jsonl'
env = dict(os.environ, GH_REPO='test/repo', CALL_LOG=str(log), CI_RESULT=str(result))
env['PATH'] = str(directory) + os.pathsep + env['PATH']
run = subprocess.run(['bash', str(SCRIPT)], env=env, text=True, capture_output=True)
calls = [json.loads(line) for line in log.read_text().splitlines()]
return run, calls
def test_passing_pr_ci_merges_only_tested_head(self):
run, calls = self.run_gate(0)
self.assertEqual(run.returncode, 0, run.stderr)
self.assertTrue(any(call[:2] == ['pr', 'merge'] for call in calls))
self.assertFalse(any(call[:2] == ['workflow', 'run'] for call in calls))
def test_failed_pr_ci_never_merges(self):
run, calls = self.run_gate(1)
self.assertNotEqual(run.returncode, 0)
self.assertFalse(any(call[:2] == ['pr', 'merge'] for call in calls))
if __name__ == '__main__':
unittest.main()