Skip to content

Commit 08ea6f4

Browse files
Use environment protection for external PRs (#180)
Switch from pull_request to pull_request_target with environment protection rules to enable full CI for external PRs with secrets. Workflows pause at jobs requiring secrets, awaiting maintainer approval via GitHub UI. Internal PRs run immediately without approval. Replaces label-based approach which didn't work because pull_request from forks never receives secrets.
1 parent f06fee3 commit 08ea6f4

File tree

3 files changed

+24
-24
lines changed

3 files changed

+24
-24
lines changed

.github/workflows/claude-code-review.yml

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
name: Claude Code Review
22

33
on:
4-
pull_request:
5-
types: [opened, synchronize, labeled]
4+
pull_request_target:
5+
types: [opened, synchronize]
66
# Optional: Only run on specific file changes
77
# paths:
88
# - "src/**/*.ts"
@@ -13,14 +13,12 @@ on:
1313
jobs:
1414
claude-review:
1515
# Skip review for automated "Version Packages" PRs created by changesets
16-
# For external PRs: requires 'ci' label
17-
# For internal PRs: runs automatically
18-
if: |
19-
github.event.pull_request.title != 'Version Packages' &&
20-
(github.event.pull_request.head.repo.full_name == github.repository ||
21-
contains(github.event.pull_request.labels.*.name, 'ci'))
16+
# For external PRs: requires manual approval via 'external-pr' environment
17+
# For internal PRs: runs automatically without approval
18+
if: github.event.pull_request.title != 'Version Packages'
2219

2320
runs-on: ubuntu-latest
21+
environment: ${{ github.event.pull_request.head.repo.full_name != github.repository && 'external-pr' || null }}
2422
permissions:
2523
contents: read
2624
pull-requests: read
@@ -31,6 +29,7 @@ jobs:
3129
- name: Checkout repository
3230
uses: actions/checkout@v4
3331
with:
32+
ref: ${{ github.event.pull_request.head.sha }}
3433
fetch-depth: 1
3534

3635
- name: Run Claude Code Review

.github/workflows/pkg-pr-new.yml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,26 @@ permissions:
55
pull-requests: write # Required for pkg.pr.new to comment on PRs
66

77
on:
8-
pull_request:
9-
types: [opened, synchronize, reopened, labeled]
8+
pull_request_target:
9+
types: [opened, synchronize, reopened]
1010
paths:
1111
- '**'
1212
- '!**/*.md'
1313
- '!.changeset/**'
1414

1515
jobs:
1616
publish-preview:
17-
# For external PRs: requires 'ci' label
18-
# For internal PRs: runs automatically
19-
if: |
20-
github.event.pull_request.head.repo.full_name == github.repository ||
21-
contains(github.event.pull_request.labels.*.name, 'ci')
17+
# For external PRs: requires manual approval via 'external-pr' environment
18+
# For internal PRs: runs automatically without approval
2219
runs-on: ubuntu-latest
2320
timeout-minutes: 15
21+
environment: ${{ github.event.pull_request.head.repo.full_name != github.repository && 'external-pr' || null }}
2422

2523
steps:
2624
- name: Checkout code
2725
uses: actions/checkout@v4
2826
with:
27+
ref: ${{ github.event.pull_request.head.sha }}
2928
fetch-depth: 0
3029

3130
- name: Setup Node.js

.github/workflows/pullrequest.yml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ permissions:
44
contents: read
55

66
on:
7-
pull_request:
8-
types: [opened, synchronize, reopened, labeled]
7+
pull_request_target:
8+
types: [opened, synchronize, reopened]
99

1010
concurrency:
1111
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
@@ -20,6 +20,8 @@ jobs:
2020
version: ${{ steps.get-version.outputs.version }}
2121
steps:
2222
- uses: actions/checkout@v4
23+
with:
24+
ref: ${{ github.event.pull_request.head.sha }}
2325

2426
- uses: actions/setup-node@v4
2527
with:
@@ -72,17 +74,17 @@ jobs:
7274
run: npm run test -w @repo/sandbox-container
7375

7476
# E2E tests against deployed worker
75-
# For external PRs: requires 'ci' label
76-
# For internal PRs: runs automatically
77+
# For external PRs: requires manual approval via 'external-pr' environment
78+
# For internal PRs: runs automatically without approval
7779
e2e-tests:
7880
needs: unit-tests
79-
if: |
80-
github.event.pull_request.head.repo.full_name == github.repository ||
81-
contains(github.event.pull_request.labels.*.name, 'ci')
8281
timeout-minutes: 30
8382
runs-on: ubuntu-latest
83+
environment: ${{ github.event.pull_request.head.repo.full_name != github.repository && 'external-pr' || null }}
8484
steps:
8585
- uses: actions/checkout@v4
86+
with:
87+
ref: ${{ github.event.pull_request.head.sha }}
8688

8789
- uses: actions/setup-node@v4
8890
with:
@@ -103,7 +105,7 @@ jobs:
103105
- name: Set environment name
104106
id: env-name
105107
run: |
106-
if [ "${{ github.event_name }}" = "pull_request" ]; then
108+
if [ "${{ github.event_name }}" = "pull_request_target" ]; then
107109
echo "env_name=pr-${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
108110
echo "worker_name=sandbox-e2e-test-worker-pr-${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
109111
else
@@ -161,7 +163,7 @@ jobs:
161163

162164
# Cleanup: Delete test worker and container (only for PR environments)
163165
- name: Cleanup test deployment
164-
if: always() && github.event_name == 'pull_request'
166+
if: always() && github.event_name == 'pull_request_target'
165167
continue-on-error: true
166168
run: |
167169
cd tests/e2e/test-worker

0 commit comments

Comments
 (0)