diff --git a/.github/scripts/release_pr.py b/.github/scripts/release_pr.py index 51fd5ad61..4143e0d4d 100644 --- a/.github/scripts/release_pr.py +++ b/.github/scripts/release_pr.py @@ -123,7 +123,8 @@ def _cli_classify(pr_number: int, strict: bool, since: str | None = None) -> Non print(f"::error::open PR #{number} already releases {path}; one in-flight release PR per major") sys.exit(1) if since and not strict: - head = _gh_json(["pr", "view", str(pr_number), "-R", repo, "--json", "headRefOid", "--jq", ".headRefOid"]) + # No --jq: gh prints a jq string result unquoted, which is not JSON. + head = _gh_json(["pr", "view", str(pr_number), "-R", repo, "--json", "headRefOid"])["headRefOid"] pushed = _push_files(repo, since, head) if pushed is not None and changelog_only(pushed): print("::notice::this push changed only release CHANGELOG.md files; the pre-release populated for the previous head stands (populate skipped)") diff --git a/tests/test_release_pr_script.py b/tests/test_release_pr_script.py index d85a3867c..4d287be5c 100644 --- a/tests/test_release_pr_script.py +++ b/tests/test_release_pr_script.py @@ -93,3 +93,35 @@ def test_changelog_only(): ) assert not m.changelog_only(["root/ppg/staging/18/CHANGELOG.md"]) assert not m.changelog_only([]) + + +def test_cli_classify_push_reads_head_sha(tmp_path, monkeypatch): + # A synchronize push (--since) looks up the PR head; gh prints a jq + # string result unquoted, so the lookup must not use --jq. + import json + import subprocess + + mod = _load() + files = [{"path": "root/ppg/releases/17/release.yaml"}] + + def fake_run(cmd, capture_output=True, text=True): + args = cmd[1:] + if args[:2] == ["pr", "view"] and "files" in args: + out = json.dumps(files) + elif args[:2] == ["pr", "list"]: + out = "[]" + elif args[:2] == ["pr", "view"] and "headRefOid" in args: + out = "abc123\n" if "--jq" in args else json.dumps({"headRefOid": "abc123"}) + elif args[0] == "api": + assert args[1].endswith("/compare/old...abc123") + out = json.dumps(["root/ppg/releases/17/CHANGELOG.md"]) + else: + raise AssertionError(cmd) + return subprocess.CompletedProcess(cmd, 0, out, "") + + out_file = tmp_path / "out" + monkeypatch.setenv("GITHUB_REPOSITORY", "o/r") + monkeypatch.setenv("GITHUB_OUTPUT", str(out_file)) + monkeypatch.setattr(mod.subprocess, "run", fake_run) + mod._cli_classify(201, False, "old") + assert "kind=changelog" in out_file.read_text()