Skip to content

Commit c3b6e73

Browse files
ericyangpanclaude
andcommitted
ci(workflow): add guard logic for fork and dependabot Pull Requests
Add deploy_guard and cleanup_guard steps to skip preview deployment and cleanup for fork PRs and Dependabot PRs, which don't have access to repository secrets. - Add deploy_guard step to skip preview deployment for fork PRs and Dependabot PRs - Add cleanup_guard step to skip preview cleanup for fork PRs and Dependabot PRs - Update PR comments to show deployment/cleanup status with skip reasons - Fix wrangler command to use --env "" for preview aliases 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 8f30835 commit c3b6e73

File tree

2 files changed

+97
-4
lines changed

2 files changed

+97
-4
lines changed

.github/workflows/cleanup-preview.yml

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,44 @@ jobs:
1212
pull-requests: write
1313

1414
steps:
15+
- name: Determine whether preview cleanup should run
16+
id: cleanup_guard
17+
shell: bash
18+
env:
19+
CF_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
20+
CF_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
21+
PR_HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
22+
BASE_REPO: ${{ github.repository }}
23+
ACTOR: ${{ github.actor }}
24+
run: |
25+
# Fork PRs do not receive repository secrets, so cleanup must be skipped.
26+
SHOULD_CLEANUP="true"
27+
REASON=""
28+
29+
if [[ -n "$PR_HEAD_REPO" && "$PR_HEAD_REPO" != "$BASE_REPO" ]]; then
30+
SHOULD_CLEANUP="false"
31+
REASON="Fork pull requests do not have access to repository secrets in GitHub Actions."
32+
fi
33+
34+
if [[ "$ACTOR" == "dependabot[bot]" ]]; then
35+
SHOULD_CLEANUP="false"
36+
REASON="Dependabot pull requests do not have access to repository secrets in this workflow."
37+
fi
38+
39+
if [[ "$SHOULD_CLEANUP" == "true" ]]; then
40+
if [[ -z "$CF_API_TOKEN" || -z "$CF_ACCOUNT_ID" ]]; then
41+
echo "Missing required Cloudflare secrets. Please configure CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID in repository secrets."
42+
exit 1
43+
fi
44+
fi
45+
46+
{
47+
echo "should_cleanup=$SHOULD_CLEANUP"
48+
echo "reason=$REASON"
49+
} >> "$GITHUB_OUTPUT"
50+
1551
- name: Delete Preview Deployment
52+
if: steps.cleanup_guard.outputs.should_cleanup == 'true'
1653
uses: cloudflare/wrangler-action@v3
1754
with:
1855
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
@@ -22,13 +59,20 @@ jobs:
2259

2360
- name: Comment Cleanup Status
2461
uses: actions/github-script@v7
62+
env:
63+
SHOULD_CLEANUP: ${{ steps.cleanup_guard.outputs.should_cleanup }}
64+
SKIP_REASON: ${{ steps.cleanup_guard.outputs.reason }}
2565
with:
2666
script: |
2767
const prNumber = context.payload.pull_request.number;
68+
const shouldCleanup = process.env.SHOULD_CLEANUP === 'true';
69+
const skipReason = process.env.SKIP_REASON || 'Cleanup was skipped.';
2870
2971
await github.rest.issues.createComment({
3072
owner: context.repo.owner,
3173
repo: context.repo.repo,
3274
issue_number: prNumber,
33-
body: `### Preview deployment cleaned up\n\nThe preview deployment for PR #${prNumber} has been removed.`
75+
body: shouldCleanup
76+
? `### Preview deployment cleaned up\n\nThe preview deployment for PR #${prNumber} has been removed.`
77+
: `### Preview deployment cleanup skipped\n\n**Reason:** ${skipReason}`
3478
});

.github/workflows/deploy-preview.yml

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,46 @@ jobs:
2222
- name: Checkout code
2323
uses: actions/checkout@v6
2424

25+
- name: Determine whether preview deploy should run
26+
id: deploy_guard
27+
shell: bash
28+
env:
29+
CF_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
30+
CF_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
31+
PR_HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
32+
BASE_REPO: ${{ github.repository }}
33+
EVENT_NAME: ${{ github.event_name }}
34+
ACTOR: ${{ github.actor }}
35+
run: |
36+
# Decide whether we can deploy a preview safely.
37+
# Fork PRs do not receive repository secrets, so deployment must be skipped.
38+
SHOULD_DEPLOY="true"
39+
REASON=""
40+
41+
if [[ "$EVENT_NAME" == "pull_request" ]]; then
42+
if [[ -n "$PR_HEAD_REPO" && "$PR_HEAD_REPO" != "$BASE_REPO" ]]; then
43+
SHOULD_DEPLOY="false"
44+
REASON="Fork pull requests do not have access to repository secrets in GitHub Actions."
45+
fi
46+
47+
if [[ "$ACTOR" == "dependabot[bot]" ]]; then
48+
SHOULD_DEPLOY="false"
49+
REASON="Dependabot pull requests do not have access to repository secrets in this workflow."
50+
fi
51+
fi
52+
53+
if [[ "$SHOULD_DEPLOY" == "true" ]]; then
54+
if [[ -z "$CF_API_TOKEN" || -z "$CF_ACCOUNT_ID" ]]; then
55+
echo "Missing required Cloudflare secrets. Please configure CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID in repository secrets."
56+
exit 1
57+
fi
58+
fi
59+
60+
{
61+
echo "should_deploy=$SHOULD_DEPLOY"
62+
echo "reason=$REASON"
63+
} >> "$GITHUB_OUTPUT"
64+
2565
- name: Compute preview identifiers
2666
id: preview_meta
2767
run: |
@@ -71,21 +111,26 @@ jobs:
71111
BUILD_TIME: ${{ github.event.pull_request.updated_at || github.event.head_commit.timestamp }}
72112

73113
- name: Deploy Preview
114+
if: steps.deploy_guard.outputs.should_deploy == 'true'
74115
uses: cloudflare/wrangler-action@v3
75116
with:
76117
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
77118
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
78-
command: versions upload --preview-alias ${{ steps.preview_meta.outputs.preview_alias }}
119+
command: versions upload --env "" --preview-alias ${{ steps.preview_meta.outputs.preview_alias }}
79120

80121
- name: Comment Preview URL
81122
if: github.event_name == 'pull_request'
82123
uses: actions/github-script@v7
83124
env:
84125
PREVIEW_URL: ${{ steps.preview_meta.outputs.preview_url }}
126+
SHOULD_DEPLOY: ${{ steps.deploy_guard.outputs.should_deploy }}
127+
SKIP_REASON: ${{ steps.deploy_guard.outputs.reason }}
85128
with:
86129
script: |
87130
const prNumber = context.payload.pull_request.number;
88131
const previewUrl = process.env.PREVIEW_URL;
132+
const shouldDeploy = process.env.SHOULD_DEPLOY === 'true';
133+
const skipReason = process.env.SKIP_REASON || 'Preview deployment was skipped.';
89134
const commitSha = context.sha.substring(0, 7);
90135
91136
// Find existing bot comment
@@ -99,14 +144,18 @@ jobs:
99144
c.user.type === 'Bot' && c.body.includes('Preview deployment')
100145
);
101146
147+
const status = shouldDeploy ? 'Ready' : 'Skipped';
148+
const urlCell = shouldDeploy ? `[${previewUrl}](${previewUrl})` : '-';
149+
const reasonBlock = shouldDeploy ? '' : `\n\n**Reason:** ${skipReason}\n\nIf you want a preview deployment, please ask a maintainer to run this from a branch within the main repository.`;
150+
102151
const body = `### Preview deployment
103152
104153
| Status | URL |
105154
|--------|-----|
106-
| Ready | [${previewUrl}](${previewUrl}) |
155+
| ${status} | ${urlCell} |
107156
108157
**Commit:** \`${commitSha}\`
109-
**Updated:** ${new Date().toISOString()}`;
158+
**Updated:** ${new Date().toISOString()}${reasonBlock}`;
110159
111160
if (botComment) {
112161
await github.rest.issues.updateComment({

0 commit comments

Comments
 (0)