From 8ac8f645dfc6715900d78ac35c69151558bf1d12 Mon Sep 17 00:00:00 2001 From: "Jason T. Greene" Date: Wed, 9 Sep 2026 23:19:31 -0500 Subject: [PATCH] ci: find the PR by head repository and branch so fork PRs get pr-N images publish-pr-image resolved the PR number with GET /repos/{repo}/commits/{sha}/pulls. That endpoint returns nothing for the head commit of an open pull request from a fork, so the pusher skips every fork PR with "No open PR has as its head" while the run still ends green, and no pr- image is pushed. Query GET /repos/{repo}/pulls?head=:&state=open instead, with the owner and branch taken from the workflow_run payload, and keep the head-SHA equality filter so a superseded run still yields to the newer one. All inputs remain GitHub-written payload fields; nothing is read from the PR run's artifacts. Same change as rh-forge/rh-forge-ui#100, where the new lookup resolved fork PR #57 in a live workflow_run (run 34430851255). Co-Authored-By: Claude Opus 5 --- .github/workflows/publish-pr-image.yml | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish-pr-image.yml b/.github/workflows/publish-pr-image.yml index 57955a09a..0a2f2aa7c 100644 --- a/.github/workflows/publish-pr-image.yml +++ b/.github/workflows/publish-pr-image.yml @@ -20,8 +20,9 @@ name: publish-pr-image # - only pushes image names on the hard-coded allowlist below, so a # malicious PR cannot rename its artifact to overwrite another # repository's package, and -# - derives the PR number from the head SHA via the API instead of -# trusting anything the PR run wrote. +# - resolves the PR number from the workflow_run payload's head +# repository, branch and SHA via the API instead of trusting anything +# the PR run wrote. # # workflow_run always executes this file as it exists on the default branch, # never the PR's copy. @@ -60,13 +61,24 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} HEAD_SHA: ${{ github.event.workflow_run.head_sha }} + HEAD_OWNER: ${{ github.event.workflow_run.head_repository.owner.login }} + HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }} run: | + # Look the PR up by head repository and branch, not by commit: + # `GET /repos/{repo}/commits/{sha}/pulls` returns nothing for the + # head commit of an open PR from a fork (measured 2026-09-09 on + # rh-forge-ui #97 and #98), and fork PRs are routine in this + # organisation. All three inputs are written by GitHub into the + # workflow_run payload; nothing here is taken from the PR run's + # artifacts. + # # The SHA-equality filter also drops runs whose PR has since gained # newer commits -- the newer run, not this one, owns the pr-N tag. - number=$(gh api "repos/${{ github.repository }}/commits/${HEAD_SHA}/pulls" \ - --jq "[.[] | select(.state == \"open\" and .head.sha == \"${HEAD_SHA}\")][0].number // empty") + number=$(gh api --method GET "repos/${{ github.repository }}/pulls" \ + -f head="${HEAD_OWNER}:${HEAD_BRANCH}" -f state=open \ + --jq "[.[] | select(.head.sha == \"${HEAD_SHA}\")][0].number // empty") if [ -z "$number" ]; then - echo "No open PR has ${HEAD_SHA} as its head; nothing to publish." + echo "No open PR from ${HEAD_OWNER}:${HEAD_BRANCH} has ${HEAD_SHA} as its head; nothing to publish." echo "skip=true" >> "$GITHUB_OUTPUT" else echo "number=$number" >> "$GITHUB_OUTPUT"