Skip to content

Commit 844e6c4

Browse files
committed
ci: resolve fork PRs from workflow head
Signed-off-by: Zujian Zhang <zhangzujian.7@gmail.com>
1 parent ad1025f commit 844e6c4

2 files changed

Lines changed: 39 additions & 1 deletion

File tree

.github/workflows/x86-e2e-gate.yaml

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ jobs:
101101
RUN_ATTEMPT: ${{ github.event.workflow_run.run_attempt }}
102102
RUN_EVENT: ${{ github.event.workflow_run.event }}
103103
RUN_HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
104+
RUN_HEAD_REPOSITORY: ${{ github.event.workflow_run.head_repository.full_name }}
104105
RUN_ID: ${{ github.event.workflow_run.id }}
105106
RUN_NAME: ${{ github.event.workflow_run.display_title }}
106107
RUN_PATH: ${{ github.event.workflow_run.path }}
@@ -143,6 +144,35 @@ jobs:
143144
trustedExecution=true
144145
else
145146
printf '%s' "$RUN_PULL_REQUESTS" > run-pull-requests.json
147+
if [ "$(jq 'length' run-pull-requests.json)" -eq 0 ]; then
148+
if ! [[ "$RUN_WORKFLOW_SHA" =~ ^[0-9a-f]{40}$ ]]; then
149+
echo 'The pull request workflow HEAD is invalid.' >&2
150+
exit 1
151+
fi
152+
headOwner=${RUN_HEAD_REPOSITORY%%/*}
153+
if [ -z "$headOwner" ] || [ "$headOwner" = "$RUN_HEAD_REPOSITORY" ]; then
154+
echo 'The pull request workflow head repository is invalid.' >&2
155+
exit 1
156+
fi
157+
gh api --method GET \
158+
"repos/$GITHUB_REPOSITORY/pulls" \
159+
-f state=open \
160+
-f "head=$headOwner:$RUN_HEAD_BRANCH" \
161+
> associated-pull-requests.json
162+
jq \
163+
--arg repository "$GITHUB_REPOSITORY" \
164+
--arg headSHA "$RUN_WORKFLOW_SHA" \
165+
--arg headRepository "$RUN_HEAD_REPOSITORY" \
166+
'[.[] | select(
167+
.state == "open" and
168+
.head.sha == $headSHA and
169+
.head.repo.full_name == $headRepository and
170+
.base.repo.full_name == $repository
171+
)] |
172+
if length == 1 then .
173+
else error("workflow HEAD must resolve to exactly one open pull request")
174+
end' associated-pull-requests.json > run-pull-requests.json
175+
fi
146176
prNumber=$(jq -r '.[0].number // empty' run-pull-requests.json)
147177
expectedHead=$(jq -r '.[0].head.sha // empty' run-pull-requests.json)
148178
trustedRef=$(jq -r '.[0].base.sha // empty' run-pull-requests.json)
@@ -158,7 +188,7 @@ jobs:
158188
approved=false
159189
trustedExecution=false
160190
if [ -z "$prNumber" ] || [ -z "$expectedHead" ] || [ -z "$trustedRef" ]; then
161-
echo 'The completed pull_request run is not associated with a pull request.' >&2
191+
echo 'The completed pull_request run is not associated with one open pull request.' >&2
162192
exit 1
163193
fi
164194
fi

hack/test_e2e_control.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,14 @@ def testGateWorkflowCanOnlyReadRunsAndWriteChecks(self):
874874
self.assertIn("RUN_ACTOR: ${{ github.event.workflow_run.actor.login }}", workflow)
875875
self.assertIn("RUN_ATTEMPT: ${{ github.event.workflow_run.run_attempt }}", workflow)
876876
self.assertIn("RUN_TRIGGERING_ACTOR: ${{ github.event.workflow_run.triggering_actor.login }}", workflow)
877+
self.assertIn(
878+
"RUN_HEAD_REPOSITORY: ${{ github.event.workflow_run.head_repository.full_name }}",
879+
workflow,
880+
)
881+
self.assertIn('-f "head=$headOwner:$RUN_HEAD_BRANCH"', workflow)
882+
self.assertIn("workflow HEAD must resolve to exactly one open pull request", workflow)
883+
self.assertIn('.head.repo.full_name == $headRepository', workflow)
884+
self.assertIn('.base.repo.full_name == $repository', workflow)
877885
self.assertIn("automatic: ${{ steps.context.outputs.automatic }}", workflow)
878886
self.assertIn("controlledLabels: ${{ steps.context.outputs.controlledLabels }}", workflow)
879887
self.assertIn("A trusted comment approval supersedes this automatic executor.", workflow)

0 commit comments

Comments
 (0)