improve db setups/migrations

This commit is contained in:
Devin Zuczek
2026-06-30 15:41:38 -04:00
parent c911cb8f61
commit c1489ea683
6 changed files with 87 additions and 12 deletions
+8
View File
@@ -71,6 +71,14 @@ preview:
deploy *args: deploy *args:
bun turbo deploy "$@" bun turbo deploy "$@"
# Apply D1 migrations (rooms + auth own them). Defaults to --remote; pass `-- --local`
# for the dev db. Scope with -F, e.g. `just migrate -F rooms`.
[group('2. local dev')]
[positional-arguments]
[no-cd]
migrate *args:
bun turbo migrate "$@"
# =============================== # # =============================== #
# GENERATOR COMMANDS # # GENERATOR COMMANDS #
# =============================== # # =============================== #
+6 -12
View File
@@ -193,22 +193,16 @@ wrangler d1 create recflare
``` ```
Then apply the schema. The `rooms` and `auth` workers own the migrations under Then apply the schema. The `rooms` and `auth` workers own the migrations under
their `apps/<worker>/migrations/` directories. Remote operations need the real id their `apps/<worker>/migrations/` directories. `just migrate` applies them to the
in the config (the committed file only has the `"local"` placeholder), so splice remote database (splicing `RECFLARE_D1` into the `"local"` placeholder the same way
it in the same way the deploy does — from each owning worker, with `RECFLARE_D1` `just deploy` does, so you don't edit any config):
exported:
```bash ```bash
cd apps/rooms # then repeat for apps/auth just migrate # migrate every worker that owns migrations
sed -E "s/\"database_id\": *\"local\"/\"database_id\": \"$RECFLARE_D1\"/" \ just migrate -F rooms # or scope to one worker
wrangler.jsonc >wrangler.generated.jsonc just migrate -- --local # target the local dev db instead of remote
wrangler d1 migrations apply recflare --remote --config wrangler.generated.jsonc
rm wrangler.generated.jsonc
``` ```
For the local dev database no id is needed — it uses the `"local"` placeholder
directly: `wrangler d1 migrations apply recflare --local`.
_KV — two namespaces_ (`RECFLARE_MATCH_PRESENCE` for `match`/`auth`, _KV — two namespaces_ (`RECFLARE_MATCH_PRESENCE` for `match`/`auth`,
`RECFLARE_PLAYER_SETTINGS` for `playersettings`): `RECFLARE_PLAYER_SETTINGS` for `playersettings`):
+1
View File
@@ -12,6 +12,7 @@
"deploy": "run-wrangler-deploy", "deploy": "run-wrangler-deploy",
"dev": "run-wrangler-dev", "dev": "run-wrangler-dev",
"fix:workers-types": "run-wrangler-types", "fix:workers-types": "run-wrangler-types",
"migrate": "run-wrangler-migrate",
"test": "run-vitest" "test": "run-vitest"
}, },
"dependencies": { "dependencies": {
+1
View File
@@ -12,6 +12,7 @@
"deploy": "run-wrangler-deploy", "deploy": "run-wrangler-deploy",
"dev": "run-wrangler-dev", "dev": "run-wrangler-dev",
"fix:workers-types": "run-wrangler-types", "fix:workers-types": "run-wrangler-types",
"migrate": "run-wrangler-migrate",
"test": "run-vitest" "test": "run-vitest"
}, },
"dependencies": { "dependencies": {
+64
View File
@@ -0,0 +1,64 @@
#!/bin/sh
set -eu
# Apply this worker's D1 migrations. Run from a worker directory (e.g. via
# `bun turbo -F rooms migrate`). Defaults to --remote; pass --local to target the
# dev SQLite db. Extra args pass through to `wrangler d1 migrations apply`.
#
# Remote/preview migrations need the real database id, but the committed
# wrangler.jsonc carries a "local" placeholder. This splices the id from
# RECFLARE_D1 (gitignored .env / CI secrets) into a generated config alongside the
# original — exactly like run-wrangler-deploy — so relative paths (migrations_dir)
# still resolve. Local migrations use the placeholder directly and need no id.
if ! grep -q '"database_id": *"local"' wrangler.jsonc 2>/dev/null; then
echo "error: this worker has no D1 database to migrate (no \"local\" placeholder in wrangler.jsonc)" >&2
exit 1
fi
# Target the database by its name from the committed config.
DB_NAME=$(grep '"database_name"' wrangler.jsonc | head -1 |
sed -E 's/.*"database_name": *"([^"]*)".*/\1/')
# Detect a caller-supplied target flag; default to --remote when none is given.
LOCAL=0
HAS_TARGET=0
for arg in "$@"; do
case "$arg" in
--local) LOCAL=1 HAS_TARGET=1 ;;
--remote | --preview) HAS_TARGET=1 ;;
esac
done
if [ "$LOCAL" -eq 1 ]; then
# Local db keys off the "local" placeholder, so the committed config is fine.
exec wrangler d1 migrations apply "$DB_NAME" "$@"
fi
# Load RECFLARE_D1 from the gitignored root .env if not already set (mirrors
# run-wrangler-deploy's handling of RECFLARE_DOMAIN). An already-set value wins.
if [ -z "${RECFLARE_D1:-}" ]; then
ENV_FILE="$(git rev-parse --show-toplevel)/.env"
if [ -f "$ENV_FILE" ]; then
set -a
. "$ENV_FILE"
set +a
fi
fi
DB_ID=${RECFLARE_D1:-}
if [ -z "$DB_ID" ]; then
echo "error: RECFLARE_D1 is not set — add the recflare D1 id to .env (see .env.example)" >&2
exit 1
fi
# Generated alongside the original so its relative paths still resolve. Gitignored;
# removed on exit so `wrangler dev` is unaffected.
trap 'rm -f wrangler.generated.jsonc' EXIT
sed -E 's/("database_id"[[:space:]]*:[[:space:]]*")[^"]*(")/\1'"$DB_ID"'\2/' \
wrangler.jsonc >wrangler.generated.jsonc
# Default to --remote when the caller passed no target flag.
[ "$HAS_TARGET" -eq 1 ] || set -- "$@" --remote
wrangler d1 migrations apply "$DB_NAME" --config wrangler.generated.jsonc "$@"
+7
View File
@@ -41,6 +41,13 @@
"env": ["CLOUDFLARE_ACCOUNT_ID", "CLOUDFLARE_API_TOKEN"], "env": ["CLOUDFLARE_ACCOUNT_ID", "CLOUDFLARE_API_TOKEN"],
"outputLogs": "new-only" "outputLogs": "new-only"
}, },
// Apply D1 migrations. Only workers that own migrations define a `migrate`
// script, so `turbo migrate` runs just those. No build needed.
"migrate": {
"cache": false,
"env": ["CLOUDFLARE_ACCOUNT_ID", "CLOUDFLARE_API_TOKEN"],
"outputLogs": "new-only"
},
// build:wrangler isn't used much, but can be useful for debugging // build:wrangler isn't used much, but can be useful for debugging
"build:wrangler": { "build:wrangler": {
"dependsOn": ["build", "topo"], "dependsOn": ["build", "topo"],