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
88 changes: 88 additions & 0 deletions .github/workflows/preview-cloudflare.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: Preview (Cloudflare)

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

permissions:
contents: read
pull-requests: write

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

jobs:
preview:
runs-on: ubuntu-latest
# Forked-repo PRs don't get repo secrets; skip rather than fail noisily.
if: github.event.pull_request.head.repo.full_name == github.repository

steps:
- name: Check out code
uses: actions/checkout@v5

- name: Set up Node.js
uses: actions/setup-node@v5
with:
node-version: "24"
cache: npm

- name: Install dependencies
run: npm ci

- name: Compute preview alias
id: alias
run: |
alias=$(echo "${{ github.head_ref }}" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9-]+/-/g; s/^-+|-+$//g')
echo "value=$alias" >> "$GITHUB_OUTPUT"

- name: Upload preview version
id: upload
run: |
npx wrangler versions upload \
--config platforms/cloudflare/wrangler.toml \
--preview-alias "${{ steps.alias.outputs.value }}" \
--var APP_VERSION:pr-${{ github.event.pull_request.number }}-$(git rev-parse --short HEAD) \
--message "PR #${{ github.event.pull_request.number }}" \
| tee wrangler-upload.log
url=$(grep -oE 'https://[^[:space:]]*workers\.dev[^[:space:]]*' wrangler-upload.log | head -1)
if [ -z "$url" ]; then
echo "::error::Could not find a preview URL in wrangler output."
exit 1
fi
echo "url=$url" >> "$GITHUB_OUTPUT"
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

- name: Comment preview URL on PR
uses: actions/github-script@v8
with:
script: |
const marker = "<!-- cloudflare-preview-url -->";
const url = "${{ steps.upload.outputs.url }}";
const body = `${marker}\n🔎 **Cloudflare preview:** ${url}\n\nUploaded from \`${{ github.sha }}\`. This is a Worker *version* preview — it shares the production D1 database, so it reads/writes real data; it does not receive cron-triggered refreshes.`;

const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const existing = comments.find((c) => 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,
});
}
5 changes: 5 additions & 0 deletions platforms/cloudflare/wrangler.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ name = "feedreader"
main = "src/index.ts"
compatibility_date = "2025-01-01"

# Explicit (not relying on the workers.dev-matching default) so PR preview
# deploys (.github/workflows/preview-cloudflare.yml, `wrangler versions
# upload --preview-alias`) always get a reachable *.workers.dev URL.
preview_urls = true

[observability]
enabled = true

Expand Down