Skip to content
Merged
Show file tree
Hide file tree
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
66 changes: 66 additions & 0 deletions .github/workflows/preview-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Preview Deploy

on:
pull_request:
types: [opened, synchronize, reopened]
branches: [main]

permissions:
contents: read
pull-requests: write

jobs:
preview-deploy:
name: Deploy Cloudflare Preview
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run build

# Uploads a new Worker version (not a full deploy — never touches the
# production/Active deployment) with a preview alias tied to this PR
# number. The alias is stable across pushes to the same PR, so the
# posted URL never changes even as new commits land. Missing runtime
# secrets (e.g. RECAPTCHA_SECRET) don't block this step — Workers
# secrets are resolved at request time, not at version-upload time —
# so routes that don't depend on them (every page but the contact
# form's POST handler) preview correctly regardless.
- name: Upload preview version
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_KEY }}
CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}
run: |
set -euo pipefail
npx wrangler versions upload \
--config dist/server/wrangler.json \
--preview-alias "pr-${{ github.event.number }}" \
| tee wrangler-preview.log

PREVIEW_URL=$(grep -oE 'https://[a-zA-Z0-9.-]*\.workers\.dev' wrangler-preview.log | head -n1)
if [ -z "$PREVIEW_URL" ]; then
echo "Could not find a preview URL in wrangler's output." >&2
exit 1
fi
echo "PREVIEW_URL=$PREVIEW_URL" >> "$GITHUB_ENV"

- name: Post or update preview URL comment
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
MARKER="<!-- cloudflare-preview-url -->"
BODY="$(printf '%s\n🔍 **Preview deployment:** %s' "$MARKER" "$PREVIEW_URL")"

EXISTING_ID=$(gh api "repos/${{ github.repository }}/issues/${{ github.event.number }}/comments" --paginate \
--jq ".[] | select(.body | startswith(\"$MARKER\")) | .id" | head -n1)

if [ -n "$EXISTING_ID" ]; then
gh api -X PATCH "repos/${{ github.repository }}/issues/comments/$EXISTING_ID" -f body="$BODY"
else
gh api -X POST "repos/${{ github.repository }}/issues/${{ github.event.number }}/comments" -f body="$BODY"
fi
8 changes: 8 additions & 0 deletions wrangler.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ compatibility_date = "2026-01-01"
# the nodejs_compat flag.
compatibility_flags = ["nodejs_compat"]

# Required by @astrojs/cloudflare's built-in sessions feature (auto-injects
# a SESSION KV binding regardless of whether this project uses sessions
# directly). KV namespace IDs are not secret — see
# https://developers.cloudflare.com/kv/concepts/kv-namespaces/.
[[kv_namespaces]]
binding = "SESSION"
id = "cf7dafbef60049ea95d4982cbe2504f9"

# Contact form outbound email, via the classic Email Routing `send_email`
# binding (legacy EmailMessage/mimetext API) rather than the newer Email
# Sending product, which requires a Workers Paid plan this account does not
Expand Down
Loading