@cosmicdrift/kumiko-dev-server 0.21.1 → 0.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-dev-server",
3
- "version": "0.21.1",
3
+ "version": "0.23.1",
4
4
  "description": "Development server bootstrap for Kumiko apps. Bundles the client, mints dev-JWTs, injects the resolved AppSchema, and seeds an admin. Not for production.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -67,6 +67,38 @@ describe("scaffoldDeploy", () => {
67
67
  expect(dockerfile).toContain("exec bun run server.js");
68
68
  });
69
69
 
70
+ it("Dockerfile copies kumiko/migrations and is free of stale drizzle artefacts", () => {
71
+ // Regression guard for PR #167 deploy-template drift: after the drizzle
72
+ // replacement (framework 0.21) + single-bundle server build (0.20), the
73
+ // template kept three dead drizzle references that broke fresh deploys —
74
+ // a COPY for the unbundled drizzle.config.ts, a COPY of /app/drizzle
75
+ // (apps now ship kumiko/), and a KUMIKO_MIGRATION_HOOKS env pointing at
76
+ // a no-longer-bundled migration-hooks.js. The migrate path is now
77
+ // `kumiko schema apply` reading ${INIT_CWD}/kumiko/migrations/*.sql.
78
+ scaffoldDeploy({ appName: "drift-guard", destination: tmp });
79
+ const dockerfile = readFileSync(join(tmp, "deploy", "Dockerfile"), "utf-8");
80
+
81
+ expect(dockerfile).toContain(
82
+ "COPY --from=build --chown=app:app /app/kumiko/migrations ./kumiko/migrations",
83
+ );
84
+
85
+ expect(dockerfile).not.toContain("/app/dist-server/drizzle.config.ts");
86
+ expect(dockerfile).not.toContain("COPY --from=build --chown=app:app /app/drizzle ./drizzle");
87
+ expect(dockerfile).not.toContain("KUMIKO_MIGRATION_HOOKS");
88
+ expect(dockerfile).not.toContain("migration-hooks.js");
89
+ });
90
+
91
+ it("migrate-step.sh invokes the schema-CLI subcommand registered in kumiko.ts", () => {
92
+ // Regression guard for PR #167: the deploy step was calling
93
+ // `bun /app/kumiko.js migrate apply`, but the CLI only registers
94
+ // `schema` (with subcommand `apply`). The pre-deploy migrate step
95
+ // crashed with "Unknown command: migrate" until this was fixed.
96
+ scaffoldDeploy({ appName: "cli-cmd", destination: tmp });
97
+ const migrate = readFileSync(join(tmp, "deploy", "migrate-step.sh"), "utf-8");
98
+ expect(migrate).toContain("bun /app/kumiko.js schema apply");
99
+ expect(migrate).not.toContain("kumiko.js migrate apply");
100
+ });
101
+
70
102
  it("skips existing files by default", () => {
71
103
  const existing = join(tmp, "deploy");
72
104
  scaffoldDeploy({ appName: "first", destination: tmp });
@@ -3,12 +3,11 @@
3
3
  // Symmetrisch zu runDevApp, aber:
4
4
  // - DATABASE_URL / REDIS_URL / JWT_SECRET aus env (fail-fast bei Boot,
5
5
  // keine ephemeralen Test-DBs)
6
- // - Hard Schema-Drift-Gate: prüft drizzle/migrations/_journal vs.
7
- // __drizzle_migrations + tableExists für jede erwartete Tabelle.
8
- // KEIN Auto-CREATE TABLE im Boot — Migration ist ein CI-Step
9
- // (`bun kumiko migrate apply`), Boot validiert nur. Verhindert
10
- // Race-Conditions bei Multi-Replica-Deploys + macht Schema-Stand
11
- // reviewbar in der Pull-Request.
6
+ // - Hard Schema-Drift-Gate: prüft kumiko/migrations vs. _kumiko_migrations
7
+ // + tableExists für jede erwartete Tabelle. KEIN Auto-CREATE TABLE im
8
+ // Boot — Migration ist ein CI-Step (`bun kumiko schema apply`), Boot
9
+ // validiert nur. Verhindert Race-Conditions bei Multi-Replica-Deploys
10
+ // + macht Schema-Stand reviewbar in der Pull-Request.
12
11
  // - Idempotente Seeds: laufen nur wenn DB leer (über `isDbEmpty`-Probe
13
12
  // pro Seed). Re-Boots nach erstem Seed sind no-op.
14
13
  // - HTTP-Server via Bun.serve mit graceful SIGTERM/SIGINT → drain().
@@ -7,10 +7,8 @@
7
7
  #
8
8
  # dist/ ← Client build (kumiko-build)
9
9
  # dist-server/ ← Server bundle (bun build) + minimal package.json
10
- # drizzle/ Migrations
11
- # drizzle.config.ts ← drizzle-kit config (for `bunx drizzle-kit migrate`)
10
+ # kumiko/migrations/ Checked-in SQL migrations applied by `kumiko schema apply`
12
11
  #
13
- # Size: ~250 MB incl. drizzle-kit for the pre-deploy migrate step.
14
12
  # Build context: repository root (monorepo is used in the build stage).
15
13
 
16
14
  ARG BUN_VERSION=1.3.14
@@ -59,12 +57,11 @@ RUN bun install --production
59
57
  # Client build (static assets) — served by runProdApp.staticDir.
60
58
  COPY --from=build --chown=app:app /app/dist ./dist
61
59
 
62
- # Drizzle artefacts for migrate apply: drizzle-kit reads drizzle.config.ts
63
- # (bundled inlined kumikoDrizzleConfig, no dev-server pkg needed) and
64
- # applies the SQL migrations from drizzle/migrations/. schema.ts is NOT
65
- # loaded (apply is SQL-only; generate reads schema).
66
- COPY --from=build --chown=app:app /app/dist-server/drizzle.config.ts ./drizzle.config.ts
67
- COPY --from=build --chown=app:app /app/drizzle ./drizzle
60
+ # Checked-in SQL migrations for the pre-deploy `kumiko schema apply` step.
61
+ # The shipped `kumiko-schema` bin reads `${INIT_CWD}/kumiko/migrations/*.sql`
62
+ # (see ENV INIT_CWD=/app below). kumiko/schema.ts is NOT needed at runtime
63
+ # (only generate reads it; apply is checksum-tracked SQL only).
64
+ COPY --from=build --chown=app:app /app/kumiko/migrations ./kumiko/migrations
68
65
 
69
66
  # Container entrypoint — `infra/pulumi/bun-server.ts` overrides the container
70
67
  # command to inject DATABASE_URL from the init-container's /shared/database-url
@@ -89,18 +86,14 @@ USER app
89
86
 
90
87
  ENV NODE_ENV=production
91
88
  ENV PORT={{port}}
92
- # kumiko.ts migrate path resolves drizzle-kit relative to KUMIKO_REPO_ROOT
93
- # (default is parent-of-import.meta.dir, which in a bundle points to the
94
- # wrong directory). /app is the app root + node_modules parent here.
89
+ # The bundled kumiko.js CLI resolves its repo-relative paths via
90
+ # KUMIKO_REPO_ROOT (default: parent-of-import.meta.dir, which inside the
91
+ # bundle points to the wrong directory). /app is the app root + the
92
+ # node_modules parent here.
95
93
  ENV KUMIKO_REPO_ROOT=/app
96
- # kumiko.ts expects INIT_CWD as the app workspace (drizzle.config.ts +
97
- # drizzle/ live per app). In the bundle container, /app is that workspace.
94
+ # INIT_CWD is the app workspace the schema-CLI runs against — that's where
95
+ # `kumiko/migrations/` lives. In the bundle container, /app is the workspace.
98
96
  ENV INIT_CWD=/app
99
- # kumiko.ts would otherwise load drizzle/migration-hooks.ts as an
100
- # unbundled .ts — that fails because dev-server and framework imports
101
- # can't be resolved from the runtime node_modules. Override to the
102
- # bundled equivalent in /app/migration-hooks.js.
103
- ENV KUMIKO_MIGRATION_HOOKS=/app/migration-hooks.js
104
97
  # Build identity in the runtime env so /api/version returns it.
105
98
  # Built: SHA of the commit at image build time + ISO timestamp.
106
99
  ENV BUILD_VERSION=$BUILD_VERSION
@@ -6,7 +6,7 @@
6
6
  # equivalent). Lives on the server under `/srv/{{appName}}/migrate-step.sh`,
7
7
  # called via `bash migrate-step.sh`.
8
8
  #
9
- # Task: apply drizzle-kit migrations + auto-rebuild for projection-schema
9
+ # Task: apply checked-in SQL migrations + auto-rebuild for projection-schema
10
10
  # changes BEFORE the app container starts — runProdApp's boot gate would
11
11
  # otherwise abort with SchemaDriftError.
12
12
  #
@@ -36,4 +36,4 @@ docker run --rm \
36
36
  --network "$STACK_NETWORK" \
37
37
  -e DATABASE_URL="postgresql://{{appName}}:${DB_PASSWORD}@db:5432/{{appName}}" \
38
38
  ghcr.io/{{githubOrg}}/{{appName}}:latest \
39
- bun /app/kumiko.js migrate apply
39
+ bun /app/kumiko.js schema apply