fix(deploy): configure pnpm allowBuilds and add Cloudflare deployment setup
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
name: CI
|
||||
|
||||
# Gitea Actions mirror of .github/workflows/ci.yml.
|
||||
# Typecheck / test / build on every push & PR; deploy the SPA to Cloudflare
|
||||
# Workers (static assets) on pushes to main.
|
||||
#
|
||||
# Required Gitea config (Repo → Settings → Actions → Secrets / Variables):
|
||||
# Variable VITE_API_BASE_URL — Laravel API base URL baked into the build
|
||||
# Secret CLOUDFLARE_API_TOKEN — token with "Edit Cloudflare Workers" scope
|
||||
# Secret CLOUDFLARE_ACCOUNT_ID — Cloudflare account id
|
||||
#
|
||||
# Requires an act_runner registered with the `ubuntu-latest` label, using an
|
||||
# image that has git + node bootstrapping (e.g. catthehacker/ubuntu:act-22.04).
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ gitea.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: Typecheck, test & build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm run generate-routes
|
||||
- run: pnpm run typecheck
|
||||
- run: pnpm test
|
||||
- run: pnpm run build
|
||||
env:
|
||||
VITE_API_BASE_URL: ${{ vars.VITE_API_BASE_URL }}
|
||||
|
||||
deploy:
|
||||
name: Deploy to Cloudflare Workers
|
||||
needs: check
|
||||
if: gitea.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm run generate-routes
|
||||
# cf:build runs `vite build` then copies the TanStack Start SPA shell
|
||||
# (_shell.html) to index.html so Cloudflare's single-page-application
|
||||
# fallback (wrangler.jsonc) returns it for every client route.
|
||||
- name: Build SPA
|
||||
run: pnpm run cf:build
|
||||
env:
|
||||
VITE_API_BASE_URL: ${{ vars.VITE_API_BASE_URL }}
|
||||
- name: Deploy
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
@@ -0,0 +1,68 @@
|
||||
name: CI
|
||||
|
||||
# Typecheck / test / build on every push & PR; deploy the SPA to Cloudflare
|
||||
# Workers (static assets) on pushes to main.
|
||||
#
|
||||
# Required GitHub config (Settings → Secrets and variables → Actions):
|
||||
# Variable VITE_API_BASE_URL — Laravel API base URL baked into the build
|
||||
# Secret CLOUDFLARE_API_TOKEN — token with "Edit Cloudflare Workers" scope
|
||||
# Secret CLOUDFLARE_ACCOUNT_ID — Cloudflare account id
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: Typecheck, test & build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm run generate-routes
|
||||
- run: pnpm run typecheck
|
||||
- run: pnpm test
|
||||
- run: pnpm run build
|
||||
env:
|
||||
VITE_API_BASE_URL: ${{ vars.VITE_API_BASE_URL }}
|
||||
|
||||
deploy:
|
||||
name: Deploy to Cloudflare Workers
|
||||
needs: check
|
||||
if: github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm run generate-routes
|
||||
# cf:build runs `vite build` then copies the TanStack Start SPA shell
|
||||
# (_shell.html) to index.html so Cloudflare's single-page-application
|
||||
# fallback (wrangler.jsonc) returns it for every client route.
|
||||
- name: Build SPA
|
||||
run: pnpm run cf:build
|
||||
env:
|
||||
VITE_API_BASE_URL: ${{ vars.VITE_API_BASE_URL }}
|
||||
- name: Deploy
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
@@ -11,3 +11,5 @@ dist-ssr
|
||||
.vinxi
|
||||
__unconfig*
|
||||
todos.json
|
||||
*.profraw
|
||||
|
||||
|
||||
@@ -31,6 +31,41 @@ ddev exec php artisan tinker storage/app/e2e-admin-seed.php
|
||||
| `pnpm test` | vitest (API client envelope/refresh/error tests) |
|
||||
| `pnpm gen:api` | regenerate `src/api/types.gen.ts` from the backend's scribe-admin OpenAPI spec (`../gig-platform/public/api-docs/admin/openapi.yaml`; run `ddev exec php artisan scribe:generate --config scribe-admin` there first) |
|
||||
|
||||
## Deploy
|
||||
|
||||
The app is a client-rendered SPA served as static assets by a Cloudflare Worker
|
||||
(`wrangler.jsonc`, `not_found_handling: single-page-application`). The build
|
||||
emits `_shell.html`, which is copied to `index.html` so Cloudflare's SPA
|
||||
fallback returns it for every client route.
|
||||
|
||||
**Manual deploy** (needs `wrangler login` or `CLOUDFLARE_API_TOKEN` /
|
||||
`CLOUDFLARE_ACCOUNT_ID` in your env):
|
||||
|
||||
```bash
|
||||
pnpm cf:deploy # vite build → copy shell to index.html → wrangler deploy
|
||||
```
|
||||
|
||||
**CI/CD** — every push & PR runs typecheck + test + build; pushes to `main`
|
||||
build and deploy to Cloudflare. Two mirrored pipelines are provided:
|
||||
|
||||
| Platform | Workflow |
|
||||
| --- | --- |
|
||||
| GitHub Actions | `.github/workflows/ci.yml` |
|
||||
| Gitea Actions | `.gitea/workflows/ci.yml` |
|
||||
|
||||
Configure these on the repo before the first deploy:
|
||||
|
||||
| Type | Name | Value |
|
||||
| --- | --- | --- |
|
||||
| Variable | `VITE_API_BASE_URL` | backend API origin baked into the build |
|
||||
| Secret | `CLOUDFLARE_API_TOKEN` | token with "Edit Cloudflare Workers" scope |
|
||||
| Secret | `CLOUDFLARE_ACCOUNT_ID` | Cloudflare account id |
|
||||
|
||||
- GitHub: *Settings → Secrets and variables → Actions*.
|
||||
- Gitea: *Repo → Settings → Actions → Secrets / Variables*. Actions must be
|
||||
enabled and an `act_runner` registered with the `ubuntu-latest` label (use an
|
||||
image such as `catthehacker/ubuntu:act-22.04`).
|
||||
|
||||
## Architecture notes
|
||||
|
||||
- **Auth**: Bearer tokens in localStorage (zustand persist). `src/api/client.ts`
|
||||
|
||||
+5
-8
@@ -12,7 +12,9 @@
|
||||
"preview": "vite preview",
|
||||
"test": "vitest run",
|
||||
"gen:api": "node scripts/gen-api.mjs",
|
||||
"typecheck": "tsc --noEmit"
|
||||
"typecheck": "tsc --noEmit",
|
||||
"cf:build": "vite build && node -e \"require('fs').copyFileSync('.output/public/_shell.html','.output/public/index.html')\"",
|
||||
"cf:deploy": "pnpm cf:build && wrangler deploy"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hookform/resolvers": "^5.4.0",
|
||||
@@ -58,12 +60,7 @@
|
||||
"openapi-typescript": "^7.13.0",
|
||||
"typescript": "^6.0.2",
|
||||
"vite": "^8.0.0",
|
||||
"vitest": "^4.1.5"
|
||||
},
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
"esbuild",
|
||||
"lightningcss"
|
||||
]
|
||||
"vitest": "^4.1.5",
|
||||
"wrangler": "^4.111.0"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+824
-41
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
||||
allowBuilds:
|
||||
esbuild: true
|
||||
lightningcss: true
|
||||
sharp: true
|
||||
workerd: true
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"$schema": "./node_modules/wrangler/config-schema.json",
|
||||
"name": "gig-admin",
|
||||
"compatibility_date": "2026-07-15",
|
||||
// Assets-only Worker: gig-admin is a client-rendered SPA (see vite.config.ts
|
||||
// `spa: { enabled: true }`), so there is no server to run — Cloudflare just
|
||||
// serves the static build and falls back to the SPA shell for client routes.
|
||||
// `pnpm cf:build` copies the TanStack Start shell to index.html, which
|
||||
// `single-page-application` handling serves for any non-asset request.
|
||||
"assets": {
|
||||
"directory": ".output/public",
|
||||
"not_found_handling": "single-page-application"
|
||||
},
|
||||
"observability": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user