Files
Folo/.github/workflows/deploy-cloudflare-ssr.yml
DIYgodandClaude Opus 5.5 5559b7c09a build: deploy the Cloudflare Workers with cf instead of Wrangler
Migrate folo-web (apps/desktop), landing-vinext (apps/landing), folo-ota
(apps/ota) and folo-ssr (apps/ssr) with `cf migrate` and finish the
follow-up work from the cf migration guide.

- cloudflare.config.ts now configures each Worker, and the Wrangler `dev`
  environment is the `dev` mode (`--mode dev`). Worker names, routes and
  zone, custom domain, bindings and resource IDs, cron trigger,
  compatibility date and flags, placement, limits, observability,
  workers.dev and assets settings are unchanged. Build settings moved to
  wrangler.config.ts (Wrangler bundler) and vite.config.ts (landing).
- landing-next-dev keeps the IMAGES binding it is deployed with today:
  CI deployed the top-level landing config with only the name and route
  overridden.
- CI builds each Worker with cf (landing still builds with vinext), then
  deploys that Build Output with `cf deploy --prebuilt` and the matching
  mode. Triggers, build steps and secrets are unchanged, and only the
  deploy steps receive the API token. turbo now caches landing's Build
  Output.
- Package scripts call cf. The landing deploy scripts used `vinext
  deploy`, which vinext no longer has.
- cf only looks for its build tool in the Worker package's own
  node_modules, while this workspace hoists every dependency to the
  root, so a postinstall step links the hoisted Wrangler or Vite plugin
  into each Worker app.
- The Vite plugin beta writes the client build into cf's Build Output,
  so landing drops the unused `output: 'standalone'` step that read
  dist/client. Worker source maps stay off, as they were with Wrangler.
- The KV preview_id has no cf equivalent; `cf dev` uses local data.
- wrangler.jsonc stays for `wrangler tail` and as a fallback until the
  Workers have been deployed to production with cf.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 22:38:53 +08:00

113 lines
3.7 KiB
YAML

name: "\u2601\ufe0f Deploy SSR to Cloudflare"
on:
push:
branches: [main, dev]
workflow_dispatch:
inputs:
confirm_production_deploy:
description: Deploy the selected branch to production (app.folo.is)
required: true
default: false
type: boolean
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'workflow_dispatch' && format('manual-prod-{0}', github.ref) || github.ref }}
cancel-in-progress: true
jobs:
deploy:
name: Build & Deploy SSR Worker
runs-on: ubuntu-latest
env:
VITE_SENTRY_DSN: ${{ vars.VITE_SENTRY_DSN }}
VITE_FIREBASE_CONFIG: ${{ vars.VITE_FIREBASE_CONFIG }}
CF_SEND_TELEMETRY: "false"
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
lfs: true
- name: Checkout LFS objects
run: git lfs checkout
- name: Cache turbo build setup
uses: actions/cache@v6
with:
path: .turbo
key: ${{ runner.os }}-turbo-${{ github.sha }}
restore-keys: |
${{ runner.os }}-turbo-
- uses: pnpm/action-setup@v6
- name: Use Node.js LTS
uses: actions/setup-node@v7
with:
node-version: lts/*
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfile --child-concurrency=1
- name: Resolve deployment target
id: target
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
if [[ "${{ inputs.confirm_production_deploy }}" != "true" ]]; then
echo "Manual production deploy was not confirmed." >&2
exit 1
fi
echo "environment=prod" >> "$GITHUB_OUTPUT"
echo "vite_web_url=https://app.folo.is" >> "$GITHUB_OUTPUT"
echo "vite_api_url=https://api.folo.is" >> "$GITHUB_OUTPUT"
exit 0
fi
if [[ "${{ github.ref }}" == "refs/heads/dev" ]]; then
echo "environment=dev" >> "$GITHUB_OUTPUT"
echo "vite_web_url=https://dev.folo.is" >> "$GITHUB_OUTPUT"
echo "vite_api_url=https://api.dev.folo.is" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "environment=prod" >> "$GITHUB_OUTPUT"
echo "vite_web_url=https://app.folo.is" >> "$GITHUB_OUTPUT"
echo "vite_api_url=https://api.folo.is" >> "$GITHUB_OUTPUT"
- name: Build desktop web (SSR assets)
working-directory: apps/desktop
env:
VITE_WEB_URL: ${{ steps.target.outputs.vite_web_url }}
VITE_API_URL: ${{ steps.target.outputs.vite_api_url }}
run: pnpm run build:web
- name: Build SSR Worker
working-directory: apps/ssr
run: pnpm run build:worker
- name: Copy WASM file
run: cp apps/ssr/node_modules/@resvg/resvg-wasm/index_bg.wasm apps/ssr/dist/worker/resvg.wasm
- name: Bundle SSR Worker for Cloudflare
working-directory: apps/ssr
run: pnpm exec cf build ${{ steps.target.outputs.environment == 'dev' && '--mode dev' || '' }}
- name: Deploy SSR Worker to Cloudflare (dev)
if: steps.target.outputs.environment == 'dev'
working-directory: apps/ssr
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
run: pnpm exec cf deploy --prebuilt --mode dev
- name: Deploy SSR Worker to Cloudflare (prod)
if: steps.target.outputs.environment == 'prod'
working-directory: apps/ssr
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
run: pnpm exec cf deploy --prebuilt