Skip to content

Commit bb48bd1

Browse files
cdoernleseb
andauthored
fix: support fork PRs in commit-recordings workflow (#5204)
## Summary - Fix empty `headRepository.nameWithOwner` from `gh pr view` for fork PRs by constructing repo name from `headRepositoryOwner.login/headRepository.name` - Split checkout in commit-recordings into same-repo and fork paths since `github.token` cannot clone fork repos - Use `RELEASE_PAT` (classic PAT with `repo` scope) for fork checkout and push, as `maintainerCanModify` requires a maintainer's credentials - Preserve recording artifacts across checkout by moving to `/tmp` ## Test plan - [x] Verified `headRepository.nameWithOwner` is empty for all PRs via `gh pr view` - [x] Verified new `headRepositoryOwner.login/headRepository.name` construction works for both fork and same-repo PRs - [x] Verified artifact preserve/restore round-trip - [ ] Run workflow_dispatch on a fork PR to validate end-to-end --------- Signed-off-by: Charlie Doern <cdoern@redhat.com> Co-authored-by: Sébastien Han <seb@redhat.com>
1 parent 4e6a48b commit bb48bd1

File tree

2 files changed

+28
-5
lines changed

2 files changed

+28
-5
lines changed

.github/workflows/commit-recordings.yml

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,15 +154,37 @@ jobs:
154154
core.setOutput('head_sha', headSha);
155155
core.setOutput('is_fork_pr', headRepo !== `${context.repo.owner}/${context.repo.repo}`);
156156
157-
- name: Checkout PR branch
158-
if: steps.pr-info.outputs.skip != 'true'
157+
- name: Preserve artifacts before checkout
158+
if: steps.pr-info.outputs.skip != 'true' && steps.pr-info.outputs.is_fork_pr != 'true'
159+
run: mv recordings-temp /tmp/recordings-temp 2>/dev/null || true
160+
161+
- name: Checkout PR branch (same-repo)
162+
if: steps.pr-info.outputs.skip != 'true' && steps.pr-info.outputs.is_fork_pr != 'true'
159163
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
160164
with:
161165
repository: ${{ steps.pr-info.outputs.head_repo }}
162166
ref: ${{ steps.pr-info.outputs.head_ref }}
163167
fetch-depth: 0
164168
token: ${{ github.token }}
165169

170+
- name: Restore artifacts after checkout
171+
if: steps.pr-info.outputs.skip != 'true' && steps.pr-info.outputs.is_fork_pr != 'true'
172+
run: mv /tmp/recordings-temp recordings-temp 2>/dev/null || true
173+
174+
- name: Checkout PR branch (fork)
175+
if: steps.pr-info.outputs.skip != 'true' && steps.pr-info.outputs.is_fork_pr == 'true'
176+
env:
177+
# RELEASE_PAT has repo scope, which allows cloning and pushing to fork
178+
# PR branches when maintainerCanModify is enabled. github.token can't do this.
179+
GH_TOKEN: ${{ secrets.RELEASE_PAT }}
180+
HEAD_REPO: ${{ steps.pr-info.outputs.head_repo }}
181+
HEAD_REF: ${{ steps.pr-info.outputs.head_ref }}
182+
run: |
183+
# Move artifacts out of the way before cloning, then restore after.
184+
mv recordings-temp /tmp/recordings-temp 2>/dev/null || true
185+
git clone --depth 1 --branch "${HEAD_REF}" "https://x-access-token:${GH_TOKEN}@github.com/${HEAD_REPO}.git" .
186+
mv /tmp/recordings-temp recordings-temp 2>/dev/null || true
187+
166188
- name: Copy recordings to repo
167189
if: steps.pr-info.outputs.skip != 'true'
168190
run: |
@@ -186,7 +208,7 @@ jobs:
186208
- name: Commit and push recordings
187209
if: steps.pr-info.outputs.skip != 'true'
188210
env:
189-
GH_TOKEN: ${{ github.token }}
211+
GH_TOKEN: ${{ steps.pr-info.outputs.is_fork_pr == 'true' && secrets.RELEASE_PAT || github.token }}
190212
PR_NUMBER: ${{ steps.pr-info.outputs.pr_number }}
191213
HEAD_REPO: ${{ steps.pr-info.outputs.head_repo }}
192214
HEAD_REF: ${{ steps.pr-info.outputs.head_ref }}

.github/workflows/record-integration-tests.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,12 @@ jobs:
8989
if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
9090
if [ -n "$INPUT_PR_NUMBER" ]; then
9191
# Fetch PR info via API
92-
PR_DATA=$(gh pr view "$INPUT_PR_NUMBER" --repo "$REPO" --json number,headRefName,headRefOid,headRepository)
92+
PR_DATA=$(gh pr view "$INPUT_PR_NUMBER" --repo "$REPO" --json number,headRefName,headRefOid,headRepository,headRepositoryOwner)
9393
PR_NUMBER="$INPUT_PR_NUMBER"
9494
HEAD_REF=$(echo "$PR_DATA" | jq -r '.headRefName')
9595
HEAD_SHA=$(echo "$PR_DATA" | jq -r '.headRefOid')
96-
HEAD_REPO=$(echo "$PR_DATA" | jq -r '.headRepository.nameWithOwner')
96+
# headRepository.nameWithOwner can be empty for fork PRs, so construct it manually
97+
HEAD_REPO=$(echo "$PR_DATA" | jq -r '"\(.headRepositoryOwner.login)/\(.headRepository.name)"')
9798
else
9899
# Use current branch
99100
PR_NUMBER="manual"

0 commit comments

Comments
 (0)