From a7334131fab99abf706346dfaac6e1016bd5717d Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Mon, 21 Sep 2026 23:50:13 -0700 Subject: [PATCH] build(release): fetch PR body in get_pr_info and grant PR read permissions The release preparation completion workflow parses the merged PR body to locate the associated release tracking issue. Previously, the workflow failed to resolve the tracking issue because `get_pr_info` omitted the PR `body` field and the GitHub Actions workflow lacked permission to read pull requests. Request the `body` field when querying PR metadata and grant `pull-requests: read` permission to the workflow so it can extract the issue number from the merged preparation PR. Work towards #4175 --- .../workflows/release_complete_prepare.yaml | 1 + dev/release/gh.py | 4 ++-- tests/tools/private/release/gh_test.py | 23 +++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release_complete_prepare.yaml b/.github/workflows/release_complete_prepare.yaml index 8315057da3..6d07024de6 100644 --- a/.github/workflows/release_complete_prepare.yaml +++ b/.github/workflows/release_complete_prepare.yaml @@ -27,6 +27,7 @@ on: permissions: contents: write issues: write + pull-requests: read jobs: complete_prepare: diff --git a/dev/release/gh.py b/dev/release/gh.py index b3bff9c214..ec43662bd9 100644 --- a/dev/release/gh.py +++ b/dev/release/gh.py @@ -731,9 +731,9 @@ def get_pr_info(self, pr_num: int) -> PrDict: pr_num: The PR number. Returns: - Dictionary containing PR fields (state, isDraft, mergeCommit, etc.). + Dictionary containing PR fields (state, isDraft, mergeCommit, body, etc.). """ - output = self._gh_pr_view(pr_num, "state", "isDraft", "mergeCommit") + output = self._gh_pr_view(pr_num, "state", "isDraft", "mergeCommit", "body") return json.loads(output) if output else {} @override diff --git a/tests/tools/private/release/gh_test.py b/tests/tools/private/release/gh_test.py index e1aea0e8cf..814bedb3dc 100644 --- a/tests/tools/private/release/gh_test.py +++ b/tests/tools/private/release/gh_test.py @@ -122,6 +122,29 @@ def test_get_pr_files(gh, auto_patch_cmd_helpers): ) +def test_get_pr_info(gh, auto_patch_cmd_helpers): + auto_patch_cmd_helpers.run_gh.return_value = ( + '{"state": "MERGED", "isDraft": false, ' + '"mergeCommit": {"oid": "abc1234"}, "body": "Work towards #4175"}' + ) + info = gh.get_pr_info(123) + assert info == { + "state": "MERGED", + "isDraft": False, + "mergeCommit": {"oid": "abc1234"}, + "body": "Work towards #4175", + } + auto_patch_cmd_helpers.run_gh.assert_called_with( + "pr", + "view", + "123", + "--json=state,isDraft,mergeCommit,body", + "--repo=my-owner/my-repo", + check=True, + capture_output=True, + ) + + def test_get_pr_files_not_found(gh, auto_patch_cmd_helpers): auto_patch_cmd_helpers.run_gh.side_effect = subprocess.CalledProcessError(1, ["gh"]) with pytest.raises(GetPrError, match="Failed to get PR #123 on my-owner/my-repo"):