Skip to content

chore: fix Keystatic app slug and update GitHub Actions versions #163

chore: fix Keystatic app slug and update GitHub Actions versions

chore: fix Keystatic app slug and update GitHub Actions versions #163

Workflow file for this run

name: Deploy static website to Cloudflare Pages
on:
push:
branches: ["main"]
paths-ignore:
- "apps/admin/**"
- ".github/workflows/deploy-admin.yml"
- "README.md"
- "docs/**"
workflow_dispatch:
inputs:
site_ref:
description: Website branch, tag, or commit to deploy
required: true
default: main
type: string
permissions:
contents: read
concurrency:
group: production-pages
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
outputs:
site_sha: ${{ steps.revision.outputs.sha }}
steps:
- name: Check out website revision
uses: actions/checkout@v7
with:
ref: ${{ inputs.site_ref || github.sha }}
persist-credentials: false
- name: Record source revision
id: revision
run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
- name: Set up pnpm
uses: pnpm/action-setup@v6
- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version: "22"
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Restore generated-image cache
uses: actions/cache@v6
with:
path: |
public/optimized
.cache/image-optimizer.json
key: ${{ runner.os }}-images-v4-${{ hashFiles('public/uploads/**', 'public/team/members/**', 'public/team/activities/**', 'scripts/optimize-all-images.ts', 'src/lib/image-widths.ts') }}
restore-keys: |
${{ runner.os }}-images-v4-
- name: Validate website and committed editorial content
run: pnpm check
- name: Audit dependencies
run: pnpm audit:dependencies
- name: Build static export
run: pnpm build:prepared
- name: Upload static export
uses: actions/upload-artifact@v7
with:
name: static-export
path: out
if-no-files-found: error
retention-days: 3
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: website-production
url: https://preferred.ai
steps:
- name: Download static export
uses: actions/download-artifact@v8
with:
name: static-export
path: out
- name: Reassert static Pages boundaries
shell: bash
run: |
set -euo pipefail
test ! -e out/_worker.js
test ! -e out/_routes.json
test ! -d out/functions
test -z "$(find out -type l -print -quit)"
file_count="$(find out -type f | wc -l | tr -d ' ')"
test "$file_count" -le 20000
while IFS= read -r file; do
size="$(stat -c '%s' "$file")"
test "$size" -le 26214400
done < <(find out -type f)
- name: Reject a superseded automatic deployment
if: github.event_name == 'push'
id: freshness
env:
EXPECTED_SHA: ${{ needs.build.outputs.site_sha }}
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
set -euo pipefail
current_sha="$(gh api "repos/$GITHUB_REPOSITORY/commits/main" --jq .sha)"
if [[ "$current_sha" == "$EXPECTED_SHA" ]]; then
echo "current=true" >> "$GITHUB_OUTPUT"
else
echo "current=false" >> "$GITHUB_OUTPUT"
echo "Skipping superseded revision $EXPECTED_SHA; main is $current_sha." >> "$GITHUB_STEP_SUMMARY"
fi
- name: Deploy to Cloudflare Pages production
if: github.event_name == 'workflow_dispatch' || steps.freshness.outputs.current == 'true'
uses: cloudflare/wrangler-action@v4
with:
apiToken: ${{ secrets.CLOUDFLARE_PAGES_API_TOKEN || secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
packageManager: npm
wranglerVersion: 4.124.0
command: pages deploy ./out --project-name=preferredai --branch=main --commit-hash=${{ needs.build.outputs.site_sha }}
- name: Smoke-test production
if: github.event_name == 'workflow_dispatch' || steps.freshness.outputs.current == 'true'
shell: bash
run: |
set -euo pipefail
index_file="$RUNNER_TEMP/preferredai-index.html"
curl --fail --silent --show-error --location --retry 10 --retry-all-errors https://preferred.ai/ > "$index_file"
for path in /blog /blog/page/2 /people /feed.xml /sitemap.xml /robots.txt /Brand.png; do
curl --fail --silent --show-error --location --retry 10 --retry-all-errors "https://preferred.ai$path" > /dev/null
done
static_asset="$(grep -o '/_next/static/[^" ]*' "$index_file" | sed -n '1p')"
test -n "$static_asset"
curl --fail --silent --show-error --location "https://preferred.ai$static_asset" > /dev/null
media_asset="$(grep -o '/optimized/[^" ]*' "$index_file" | sed -n '1p')"
test -n "$media_asset"
curl --fail --silent --show-error --location "https://preferred.ai$media_asset" > /dev/null
missing_status="$(curl --silent --output /dev/null --write-out '%{http_code}' https://preferred.ai/__deployment-smoke-missing__)"
test "$missing_status" = "404"
- name: Record deployment provenance
if: github.event_name == 'workflow_dispatch' || steps.freshness.outputs.current == 'true'
env:
SITE_SHA: ${{ needs.build.outputs.site_sha }}
run: |
{
echo "### Preferred.AI production deployment"
echo "- Website and content: \`$SITE_SHA\`"
} >> "$GITHUB_STEP_SUMMARY"