Use versioned Worker previews for branch content

This commit is contained in:
Kevin
2026-09-02 11:01:09 -04:00
parent dfc87b86ac
commit bdf0d06c1a
7 changed files with 59 additions and 17 deletions
+8 -4
View File
@@ -1,4 +1,4 @@
name: Deploy blog static Worker preview name: Upload blog Worker preview version
on: on:
push: push:
@@ -19,7 +19,7 @@ on:
jobs: jobs:
preview: preview:
name: Preview blog name: Preview blog version
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
contents: read contents: read
@@ -39,8 +39,12 @@ jobs:
run: npm run build:site run: npm run build:site
- name: Verify selected output - name: Verify selected output
run: npm run verify:build run: npm run verify:build
- name: Deploy non-production Worker - name: Upload non-production preview version
run: npx wrangler deploy --config wrangler/blog.jsonc run: |
raw_ref="${GITHUB_REF_NAME:-${GITEA_REF_NAME:-preview}}"
preview_alias="$(printf '%s' "$raw_ref" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9-]+/-/g; s/^-+//; s/-+$//' | cut -c1-40)"
preview_alias="${preview_alias:-preview}"
npx wrangler versions upload --config wrangler/blog.production.jsonc --preview-alias "$preview_alias"
env: env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }} CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
+8 -4
View File
@@ -1,4 +1,4 @@
name: Deploy primary static Worker preview name: Upload primary Worker preview version
on: on:
push: push:
@@ -19,7 +19,7 @@ on:
jobs: jobs:
preview: preview:
name: Preview www name: Preview www version
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
contents: read contents: read
@@ -39,8 +39,12 @@ jobs:
run: npm run build:site run: npm run build:site
- name: Verify selected output - name: Verify selected output
run: npm run verify:build run: npm run verify:build
- name: Deploy non-production Worker - name: Upload non-production preview version
run: npx wrangler deploy --config "wrangler/${SITE_KEY}.jsonc" run: |
raw_ref="${GITHUB_REF_NAME:-${GITEA_REF_NAME:-preview}}"
preview_alias="$(printf '%s' "$raw_ref" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9-]+/-/g; s/^-+//; s/-+$//' | cut -c1-40)"
preview_alias="${preview_alias:-preview}"
npx wrangler versions upload --config wrangler/www.production.jsonc --preview-alias "$preview_alias"
env: env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }} CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
+6 -7
View File
@@ -33,13 +33,12 @@ routes, account IDs, or secrets.
## Preview deployment ## Preview deployment
The Gitea workflows deploy scoped non-production Workers from every non-`main` The Gitea workflows upload scoped non-production preview versions of the
branch: `3031023-xyz-www-preview` for primary-site changes and production Workers from every non-`main` branch. Cloudflare assigns each branch
`3031023-xyz-blog-preview` for blog changes. Relevant primary-site pushes to a readable `workers.dev` preview alias without changing production traffic.
`main` deploy the existing `3031023-xyz-www` production Worker automatically. Relevant primary-site pushes to `main` deploy `3031023-xyz-www`, and relevant
Relevant blog pushes to `main` deploy the separate `3031023-xyz-blog` blog pushes to `main` deploy `3031023-xyz-blog`, automatically. Both production
production Worker automatically. Both production workflows deploy static assets workflows deploy static assets only.
only.
It uses the existing `CF_API_TOKEN` and `CF_ACCOUNT_ID`. The token retains the It uses the existing `CF_API_TOKEN` and `CF_ACCOUNT_ID`. The token retains the
Pages permissions needed for the `main` rollback target and now also permits Pages permissions needed for the `main` rollback target and now also permits
the non-production Worker preview deployment. the non-production Worker preview deployment.
+2 -2
View File
@@ -17,7 +17,7 @@ for (const { file, html } of pages) {
const home = await readFile(resolve(root, 'index.html'), 'utf8'); const home = await readFile(resolve(root, 'index.html'), 'utf8');
if (key === 'www') { if (key === 'www') {
if (!home.includes('What services do you offer?') || !home.includes('How do I book a visit?')) throw new Error('Primary FAQ Markdown entries are missing from the homepage.'); for (const question of ['What services do you offer?', 'How do I book a visit?', 'How far ahead should I book pet care?', 'Can you accommodate special routines?']) if (!home.includes(question)) throw new Error(`Primary FAQ Markdown entry is missing: ${question}.`);
if (home.includes('What information should I bring to a meet and greet?')) throw new Error('Draft FAQ entry appeared in the homepage.'); if (home.includes('What information should I bring to a meet and greet?')) throw new Error('Draft FAQ entry appeared in the homepage.');
const services = await readFile(resolve(root, 'services/index.html'), 'utf8'); const services = await readFile(resolve(root, 'services/index.html'), 'utf8');
for (const title of ['Dog walking', 'Grooming', 'Overnight care']) if (!services.includes(title)) throw new Error(`Service Markdown entry is missing: ${title}.`); for (const title of ['Dog walking', 'Grooming', 'Overnight care']) if (!services.includes(title)) throw new Error(`Service Markdown entry is missing: ${title}.`);
@@ -25,7 +25,7 @@ if (key === 'www') {
for (const name of ['Sarah Mitchell', 'Marcus Rivera', 'Emily Chen', 'David Okonkwo']) if (!about.includes(name)) throw new Error(`Team Markdown entry is missing: ${name}.`); for (const name of ['Sarah Mitchell', 'Marcus Rivera', 'Emily Chen', 'David Okonkwo']) if (!about.includes(name)) throw new Error(`Team Markdown entry is missing: ${name}.`);
} }
if (key === 'blog') { if (key === 'blog') {
const publishedPosts = ['first-walk-after-work', 'gentler-grooming-day', 'overnight-care-checklist']; const publishedPosts = ['first-walk-after-work', 'gentler-grooming-day', 'overnight-care-checklist', 'weekend-care-prep'];
await Promise.all(publishedPosts.map((slug) => access(resolve(root, `posts/${slug}/index.html`)))); await Promise.all(publishedPosts.map((slug) => access(resolve(root, `posts/${slug}/index.html`))));
if (home.includes('Draft only example for editorial review')) throw new Error('Draft blog post appeared in the journal.'); if (home.includes('Draft only example for editorial review')) throw new Error('Draft blog post appeared in the journal.');
try { try {
@@ -0,0 +1,15 @@
---
title: A simple weekend-care checklist for your dog
description: A calm, practical checklist to help your dog keep familiar routines while you are away for the weekend.
pubDate: 2026-09-02
tags:
- Overnight care
- Planning
draft: false
---
Before a weekend away, share your dog's feeding rhythm, favorite walking route,
comfort items, and any little details that help a new routine feel familiar.
The goal is not a perfect schedule. It is a calm handoff that gives your dog
familiar cues and gives you confidence while you are away.
@@ -0,0 +1,10 @@
---
question: How far ahead should I book pet care?
category: Booking
order: 30
draft: false
---
For this pilot, the best answer is to reach out as soon as you know your dates.
A live Happy Tails site would replace this sample guidance with the business's
actual availability, booking window, and cancellation policy.
+10
View File
@@ -0,0 +1,10 @@
---
question: Can you accommodate special routines?
category: Care preferences
order: 40
draft: false
---
This pilot's answer is a starting point: share feeding notes, medication
instructions, mobility needs, and comfort cues before the first visit. A live
site would publish only the care practices the business has approved.