From b0ff80a662ff0856a7a0b534c894a7bc10247c0e Mon Sep 17 00:00:00 2001 From: Jon Church Date: Sat, 23 May 2026 02:09:07 -0400 Subject: [PATCH] fix(release): reject release PRs from forked repositories (#13) --- README.md | 4 +++- release/action.yml | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c46f3bc..fc8c51f 100644 --- a/README.md +++ b/README.md @@ -56,12 +56,14 @@ jobs: # The release PR was merged: tag the squash commit, cut a GitHub release # from the PR body, and dispatch the publish workflow. The `release/v` - # head-ref guard keeps regular feature-PR merges from triggering this. + # head-ref guard keeps regular feature-PR merges from triggering this; + # the head-repo guard keeps merged fork PRs from triggering it. release: if: | github.event_name == 'pull_request' && github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'release/v') + && github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest permissions: contents: write # push the `vX.Y.Z` tag and create the GitHub release diff --git a/release/action.yml b/release/action.yml index 7f07f4e..4c0b3ec 100644 --- a/release/action.yml +++ b/release/action.yml @@ -33,6 +33,8 @@ runs: EVENT_NAME: ${{ github.event_name }} PR_MERGED: ${{ github.event.pull_request.merged }} PR_HEAD_REF: ${{ github.event.pull_request.head.ref }} + PR_HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }} + BASE_REPO: ${{ github.repository }} run: | set -euo pipefail if [ "$EVENT_NAME" != "pull_request" ]; then @@ -47,6 +49,10 @@ runs: echo "::error::danielroe/uppt/release expected a 'release/v*' head ref, got '$PR_HEAD_REF'." exit 1 fi + if [ "$PR_HEAD_REPO" != "$BASE_REPO" ]; then + echo "::error::danielroe/uppt/release requires the release PR to originate from this repository (got '$PR_HEAD_REPO', expected '$BASE_REPO'). Add 'github.event.pull_request.head.repo.full_name == github.repository' to the release job's if: condition to skip fork PRs at the workflow level." + exit 1 + fi - name: Checkout if: inputs.checkout == 'true' -- 2.51.2