feat: v2.5.0 T4 — Netlify deployment target (#329)

* feat: v2.5.0 T4 — Netlify deployment target

- server/entry-netlify.ts: Netlify Functions v2 (ESM) handler using hono/netlify
  adapter; connects to Turso via @libsql/client; skips in-process migrations
  (workflow applies them before deploy via drizzle-kit)
- deploy/netlify/netlify.toml: build command, functions directory, SPA fallback redirect
- .github/workflows/deploy-netlify.yml: 8-step workflow — secret guard, tag resolve,
  Turso migrations, build, netlify deploy --prod, BETTER_AUTH_SECRET first-deploy, summary
- package.json: add build:netlify script (tsup ESM → netlify/functions)
- docs/deploy/netlify.md: 5-section setup guide covering Turso, site creation,
  secrets, deploy trigger, first-boot storage setup, and cost breakdown

Agent-Profile: https://agent-kanban.dev/agents/a6bb038c4226a87f

* fix: address Netlify deploy review blockers

BLOCKER 1 — move BETTER_AUTH_SECRET step before Deploy in workflow so
the function always has the secret set before its first cold start.

BLOCKER 2 — replace inline platform construction in entry-netlify.ts
with createLibsqlPlatform(); removes duplicated db/schema wiring and
re-unifies with the shared factory. migrate() runs at cold start and
is idempotent (~50–100ms) per the workflow's prior drizzle-kit migrate.

BLOCKER 3 — add --external @libsql/client to build:netlify so tsup
leaves the native-binding package for Netlify to resolve; switch
netlify.toml to node_bundler=esbuild so Netlify bundles @libsql/client
from node_modules. Add included_files=["migrations/**"] so the
migrations folder is available in the function zip for migrate().

Minor — replace 2>/dev/null with 2>&1 in deploy step so netlify-cli
errors surface in CI logs instead of being silently swallowed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Bob <aibob@mails.agent-kanban.dev>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jasper Van
2026-04-22 01:28:08 -04:00
committed by GitHub
co-authored by Claude Sonnet 4.6 Bob
parent b5be4c5ebd
commit 0f403f8081
5 changed files with 291 additions and 0 deletions
+19
View File
@@ -0,0 +1,19 @@
[build]
# Build the React SPA then compile the Netlify Function.
command = "npm run build && npm run build:netlify"
publish = "dist"
[functions]
directory = "netlify/functions"
# esbuild bundler resolves @libsql/client (external in tsup) from node_modules.
node_bundler = "esbuild"
# Include migration SQL files so createLibsqlPlatform can run migrate() at cold start.
included_files = ["migrations/**"]
# SPA fallback — must come last; Netlify applies the first matching rule.
# /api/* and /r/* are handled by the Netlify Function (entry-netlify.ts config.path).
# /.netlify/functions/* is excluded from [[redirects]] automatically by Netlify.
[[redirects]]
from = "/*"
to = "/index.html"
status = 200