From 3e0abfef0e297271da56288488eae5933bd8e6d7 Mon Sep 17 00:00:00 2001 From: LiHaohua Date: Thu, 6 Aug 2026 13:14:25 +0800 Subject: [PATCH] fix(ci): resolve the PR by head repo and branch, not by commit Syncs from CardputerZero/dev-portal (50bd9c4). listPullRequestsAssociatedWithCommit only sees commits in the repository it is asked about, so for a fork PR it returned nothing and the privileged stage silently skipped both the comment and the merge (seen on #101). Listing open PRs filtered by head does find them, and the head SHA from the event is still checked, so the decision rests on the same trusted inputs. Co-authored-by: Cursor --- .github/workflows/validate-pr-comment.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/validate-pr-comment.yml b/.github/workflows/validate-pr-comment.yml index 389ecc9..c276933 100644 --- a/.github/workflows/validate-pr-comment.yml +++ b/.github/workflows/validate-pr-comment.yml @@ -36,18 +36,22 @@ jobs: run-id: ${{ github.event.workflow_run.id }} github-token: ${{ secrets.GITHUB_TOKEN }} - # The head SHA comes from the event, so the PR it belongs to is resolved - # through the API rather than read out of the artifact. + # Resolved from the event's head repository, branch and SHA, so the PR + # being acted on never comes from the artifact. Listing by head is what + # works for forks: listPullRequestsAssociatedWithCommit only sees commits + # in this repository and returns nothing for a fork's head. - name: Resolve the pull request id: pr uses: actions/github-script@v7 with: script: | - const sha = context.payload.workflow_run.head_sha; - const { data: prs } = await github.rest.repos.listPullRequestsAssociatedWithCommit({ - owner: context.repo.owner, repo: context.repo.repo, commit_sha: sha, + const run = context.payload.workflow_run; + const sha = run.head_sha; + const { data: prs } = await github.rest.pulls.list({ + owner: context.repo.owner, repo: context.repo.repo, state: 'open', + head: `${run.head_repository.owner.login}:${run.head_branch}`, }); - const pr = prs.find((p) => p.state === 'open' && p.head.sha === sha); + const pr = prs.find((p) => p.head.sha === sha); if (!pr) { core.info(`no open PR at ${sha}; nothing to comment on`); return;