Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions .github/workflows/pr-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Builds every PR and uploads the result to Cloudflare as a Worker *version* —
# a preview that leaves production untouched — then comments the preview URL on
# the PR. Complements Workers Builds, which deploys `main` to production but
# reports nothing back to GitHub.
#
# Requires two repository secrets:
# CLOUDFLARE_API_TOKEN — API token with Workers Scripts: Edit on the account
# CLOUDFLARE_ACCOUNT_ID — the Cloudflare account id
# Until they are set (and on fork/Dependabot PRs, which cannot read secrets),
# the build still runs as a check and the preview upload is skipped with a note.
name: PR preview

on:
pull_request:
branches: [main]

concurrency:
group: pr-preview-${{ github.event.pull_request.number }}
cancel-in-progress: true

permissions:
contents: read
pull-requests: write

jobs:
preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: npm

- run: npm ci

- run: npx astro build

- name: Check for Cloudflare credentials
id: creds
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
run: |
if [ -n "$CLOUDFLARE_API_TOKEN" ]; then
echo "available=true" >> "$GITHUB_OUTPUT"
else
echo "available=false" >> "$GITHUB_OUTPUT"
echo "CLOUDFLARE_API_TOKEN is not available (missing secret, fork PR, or Dependabot) — preview upload skipped." >> "$GITHUB_STEP_SUMMARY"
fi

- name: Upload preview version to Cloudflare
if: steps.creds.outputs.available == 'true'
id: upload
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: versions upload

- name: Comment the preview URL on the PR
if: steps.creds.outputs.available == 'true'
uses: actions/github-script@v7
env:
WRANGLER_OUTPUT: ${{ steps.upload.outputs.command-output }}
with:
script: |
const match = (process.env.WRANGLER_OUTPUT || '').match(/https:\/\/\S+\.workers\.dev/);
const marker = '<!-- workers-preview-comment -->';
const sha = context.payload.pull_request.head.sha.slice(0, 7);
const body = match
? `${marker}\n### 🔍 Preview\n\n**${match[0]}**\n\nBuilt from \`${sha}\`. Uploaded as a Worker version — production is unaffected until merge.`
: `${marker}\n### 🔍 Preview\n\nThe preview version uploaded, but no preview URL appeared in the wrangler output — check that the worker's Preview URLs setting is enabled. Built from \`${sha}\`.`;
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
per_page: 100,
});
const existing = comments.find((c) => c.body && c.body.includes(marker));
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});
}
Loading