Skip to content

Commit 56ce164

Browse files
committed
fix: pull_request_target should not skip fork PR comments
The is_fork_pr() guard only applies to pull_request events where GITHUB_TOKEN is read-only. With pull_request_target, the token always has the workflow's configured permissions. - Add is_fork_pr_with_readonly_token() that checks both is_fork_pr() and GITHUB_EVENT_NAME - Update add_pr_comments() to use the new guard - Add unit tests for the new helper - Update README Option 2 to confirm pr-comments works with pull_request_target
1 parent 294ddde commit 56ce164

3 files changed

Lines changed: 40 additions & 1 deletion

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,10 @@ jobs:
310310
pr-comments: true
311311
```
312312

313+
> ✅ With `pull_request_target`, `pr-comments: true` **does work** on fork PRs —
314+
> the token has the workflow's configured permissions regardless of whether the PR
315+
> is from a fork.
316+
>
313317
> **When to use this:** Only if the two-workflow pattern is too complex for your setup
314318
> and you have thoroughly reviewed the security implications.
315319

main.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,14 +263,25 @@ def is_fork_pr() -> bool:
263263
return False
264264

265265

266+
def is_fork_pr_with_readonly_token() -> bool:
267+
"""Returns True when the PR is from a fork AND the event has a read-only token.
268+
269+
Under the pull_request event, GITHUB_TOKEN is read-only for fork PRs.
270+
Under pull_request_target, GITHUB_TOKEN has the workflow's configured
271+
permissions regardless of whether the PR is from a fork.
272+
"""
273+
return is_fork_pr() and os.getenv("GITHUB_EVENT_NAME", "") != "pull_request_target"
274+
275+
266276
def add_pr_comments() -> int:
267277
"""Posts the commit check result as a comment on the pull request."""
268278
if not PR_COMMENTS_ENABLED:
269279
return 0
270280

271281
# Fork PRs triggered by the pull_request event receive a read-only token;
272282
# the GitHub API will always reject comment writes with 403.
273-
if is_fork_pr():
283+
# pull_request_target events always have the configured token permissions.
284+
if is_fork_pr_with_readonly_token():
274285
msg = (
275286
"Skipping PR comment: pull requests from forked repositories "
276287
"cannot write comments via the pull_request event (GITHUB_TOKEN is "

main_test.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,30 @@ def test_fork_pr_writes_job_summary_hint(self):
516516
self.assertIn("fork-pr-comments", content)
517517

518518

519+
class TestIsForkPrWithReadonlyToken(unittest.TestCase):
520+
def test_fork_pr_with_pull_request_event(self):
521+
with (
522+
patch("main.is_fork_pr", return_value=True),
523+
patch.dict(os.environ, {"GITHUB_EVENT_NAME": "pull_request"}),
524+
):
525+
self.assertTrue(main.is_fork_pr_with_readonly_token())
526+
527+
def test_fork_pr_with_pull_request_target_event(self):
528+
"""pull_request_target has write token — not considered read-only."""
529+
with (
530+
patch("main.is_fork_pr", return_value=True),
531+
patch.dict(os.environ, {"GITHUB_EVENT_NAME": "pull_request_target"}),
532+
):
533+
self.assertFalse(main.is_fork_pr_with_readonly_token())
534+
535+
def test_same_repo_not_fork(self):
536+
with (
537+
patch("main.is_fork_pr", return_value=False),
538+
patch.dict(os.environ, {"GITHUB_EVENT_NAME": "pull_request"}),
539+
):
540+
self.assertFalse(main.is_fork_pr_with_readonly_token())
541+
542+
519543
class TestIsForkPr(unittest.TestCase):
520544
def test_no_event_path(self):
521545
with patch.dict(os.environ, {}, clear=True):

0 commit comments

Comments
 (0)