Skip to content

Commit fda2e54

Browse files
committed
ci: add Cloudflare Pages deploy as canonical host
- new deploy-cloudflare.yml: full Bun + Rust/wasm build with typecheck/lint gates, SPA _redirects fallback, deploys project torena-sim - point suggestion-bot CORS ALLOWED_ORIGIN at torena-sim.pages.dev - document Cloudflare as canonical host + required CF secrets
1 parent cc67d94 commit fda2e54

6 files changed

Lines changed: 149 additions & 7 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: Deploy to Cloudflare Pages
2+
3+
on:
4+
# Run after Versioning so semantic-release has created the release tag before
5+
# changelog:generate reads git history for the in-app changelog.
6+
workflow_run:
7+
workflows: [Versioning]
8+
types: [completed]
9+
branches: [main]
10+
workflow_dispatch:
11+
12+
permissions:
13+
contents: read
14+
15+
concurrency:
16+
group: cloudflare-pages
17+
cancel-in-progress: true
18+
19+
jobs:
20+
deploy:
21+
name: Deploy to Cloudflare Pages
22+
runs-on: ubuntu-latest
23+
env:
24+
VITE_PUBLIC_POSTHOG_KEY: ${{ secrets.VITE_PUBLIC_POSTHOG_KEY }}
25+
VITE_PUBLIC_POSTHOG_HOST: ${{ vars.VITE_PUBLIC_POSTHOG_HOST }}
26+
# Cloudflare Pages serves at the domain root, so no base path.
27+
VITE_BASE_PATH: /
28+
VITE_SITE_URL: https://torena-sim.pages.dev
29+
VITE_SUGGESTION_WORKER_URL: ${{ vars.VITE_SUGGESTION_WORKER_URL }}
30+
VITE_TURNSTILE_SITE_KEY: ${{ vars.VITE_TURNSTILE_SITE_KEY }}
31+
32+
steps:
33+
- name: Checkout code
34+
uses: actions/checkout@v6.0.2
35+
with:
36+
fetch-depth: 0
37+
38+
- name: Setup Bun
39+
uses: oven-sh/setup-bun@v2
40+
41+
- name: Setup Rust toolchain (wasm32)
42+
uses: dtolnay/rust-toolchain@stable
43+
with:
44+
targets: wasm32-unknown-unknown
45+
46+
- name: Cache Rust build
47+
uses: swatinem/rust-cache@v2
48+
with:
49+
workspaces: packages
50+
51+
- name: Install wasm-pack
52+
uses: jetli/wasm-pack-action@v0.4.0
53+
54+
- name: Install dependencies
55+
run: bun install --frozen-lockfile
56+
57+
- name: Generate changelog for build
58+
run: bun run changelog:generate
59+
60+
- name: Run type check
61+
run: bun run typecheck
62+
63+
- name: Run linter
64+
run: bun run lint
65+
66+
- name: Build app
67+
run: bun run build
68+
69+
- name: Add SPA fallback for client-side routing
70+
run: printf '/* /index.html 200\n' > dist/_redirects
71+
72+
- name: Deploy to Cloudflare Pages
73+
uses: cloudflare/wrangler-action@v3
74+
with:
75+
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
76+
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
77+
command: pages deploy dist --project-name=torena-sim --branch=main
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Deploy to Netlify
2+
3+
on:
4+
# Run after Versioning so semantic-release has created the release tag before
5+
# changelog:generate reads git history for the in-app changelog.
6+
workflow_run:
7+
workflows: [Versioning]
8+
types: [completed]
9+
branches: [main]
10+
workflow_dispatch:
11+
12+
concurrency:
13+
group: netlify
14+
cancel-in-progress: true
15+
16+
jobs:
17+
deploy:
18+
name: Deploy to Netlify
19+
runs-on: ubuntu-latest
20+
env:
21+
VITE_PUBLIC_POSTHOG_KEY: ${{ secrets.VITE_PUBLIC_POSTHOG_KEY }}
22+
VITE_PUBLIC_POSTHOG_HOST: ${{ vars.VITE_PUBLIC_POSTHOG_HOST }}
23+
VITE_SITE_URL: https://sundays-shadow.netlify.app
24+
VITE_SUGGESTION_WORKER_URL: ${{ vars.VITE_SUGGESTION_WORKER_URL }}
25+
VITE_TURNSTILE_SITE_KEY: ${{ vars.VITE_TURNSTILE_SITE_KEY }}
26+
27+
steps:
28+
- name: Checkout code
29+
uses: actions/checkout@v6.0.2
30+
with:
31+
fetch-depth: 0
32+
33+
- name: Setup Bun
34+
uses: oven-sh/setup-bun@v2
35+
36+
- name: Install dependencies
37+
run: bun install --frozen-lockfile
38+
39+
- name: Generate changelog for build
40+
run: bun run changelog:generate
41+
42+
- name: Build app
43+
run: bun run build
44+
45+
- name: Copy netlify.toml to dist
46+
run: cp netlify.toml dist/
47+
48+
- name: Deploy to Netlify
49+
uses: nwtgck/actions-netlify@v3
50+
with:
51+
publish-dir: ./dist
52+
production-deploy: true
53+
env:
54+
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
55+
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,15 @@ See [docs/data-extraction/data-pipeline.md](docs/data-extraction/data-pipeline.m
5656

5757
Production deploys run automatically on every push to `main` (rolling releases). GitHub Releases from [semantic-release](https://github.com/semantic-release/semantic-release) are for changelog/tags only and do not trigger deploys.
5858

59-
Deployment target:
59+
The canonical app is hosted on **Cloudflare Pages**. GitHub Pages and Netlify are kept only as 301 redirects to the canonical domain so legacy inbound links don't break.
6060

61-
| Target | Workflow | URL |
62-
| ---------------- | -------------------------------------- | ---------------------------------- |
63-
| **GitHub Pages** | `.github/workflows/deploy-pages.yml` | Configured in repo Pages settings |
61+
| Target | Role | Workflow | URL |
62+
| -------------------- | ----------- | --------------------------------------- | ---------------------------------- |
63+
| **Cloudflare Pages** | Canonical | `.github/workflows/deploy-cloudflare.yml` | https://torena-sim.pages.dev |
64+
| **GitHub Pages** | 301 redirect | `.github/workflows/deploy-pages.yml` | Configured in repo Pages settings |
65+
| **Netlify** | 301 redirect | `.github/workflows/deploy-netlify.yml` | https://sundays-shadow.netlify.app |
6466

65-
The workflow can also be triggered manually via `workflow_dispatch`.
67+
Only Cloudflare Pages runs the full build (incl. the Rust/wasm engine). The two redirect workflows publish a tiny static redirect and do not build the app. All workflows can also be triggered manually via `workflow_dispatch`.
6668

6769
### Versioning
6870

@@ -87,6 +89,10 @@ Use `DATA_UPDATE_PAT` as `GITHUB_TOKEN` for local releases.
8789
| Name | Type | Used by |
8890
| -------------------------- | -------- | ---------------------------------------------------------------- |
8991
| `DATA_UPDATE_PAT` | Secret | `versioning.yml` — PAT for semantic-release (push tags, releases) |
92+
| `CLOUDFLARE_API_TOKEN` | Secret | Cloudflare Pages deploy (scope: *Cloudflare Pages → Edit*) |
93+
| `CLOUDFLARE_ACCOUNT_ID` | Secret | Cloudflare Pages deploy (also used by the suggestion-bot Worker) |
94+
| `NETLIFY_AUTH_TOKEN` | Secret | Netlify redirect deploy |
95+
| `NETLIFY_SITE_ID` | Secret | Netlify redirect deploy |
9096
| `VITE_PUBLIC_POSTHOG_KEY` | Secret | Build-time analytics key |
9197
| `VITE_PUBLIC_POSTHOG_HOST` | Variable | Build-time analytics host |
9298
| `VITE_BASE_PATH` | Variable | GitHub Pages base path |

netlify.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[[redirects]]
2+
from = "/*"
3+
to = "/index.html"
4+
status = 200

workers/suggestion-bot/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ wrangler login
3636
```
3737

3838
Set the app origin(s) in `wrangler.jsonc``vars.ALLOWED_ORIGIN`. Multiple origins are
39-
comma-separated, e.g. `https://jalbarrang.github.io`. The
39+
comma-separated, e.g. `https://torena-sim.pages.dev,https://jalbarrang.github.io`. The
4040
Worker echoes back whichever origin matches the request (CORS requires a single concrete origin)
4141
and rejects browser requests from origins not on the list.
4242

workers/suggestion-bot/wrangler.jsonc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
// Public, non-secret config. Comma-separated list of app origins allowed via CORS.
1616
"vars": {
17-
"ALLOWED_ORIGIN": "https://jalbarrang.github.io"
17+
"ALLOWED_ORIGIN": "https://torena-sim.pages.dev,https://jalbarrang.github.io"
1818
}
1919

2020
// ── Secrets (set via `wrangler secret put <NAME>`, never commit) ──

0 commit comments

Comments
 (0)