Skip to content

chore(drizzle): fail loudly when DATABASE_URL is missing + document migrate workflow - #25

Merged
davidstrouk merged 5 commits into
mainfrom
chore/drizzle-migrate-loud-env
Apr 24, 2026
Merged

davidstrouk merged 5 commits into
mainfrom
chore/drizzle-migrate-loud-env

Conversation

@davidstrouk

Copy link
Copy Markdown
Collaborator

Closes #24.

Context

Part 1 of #24 — back-filling drizzle.__drizzle_migrations for the existing production DB — has been done out of band (the tracking table now has rows for 0000_goofy_sally_floyd and 0001_scans_repo_status_created_idx, verified by a follow-up drizzle-kit migrate run that completed with zero new statements applied). This PR addresses part 2: the workflow gap that caused us to apply #23 manually in the first place.

Summary

  • drizzle.config.ts: throw an explicit error when DATABASE_URL is missing, with an actionable message. Drop the ! non-null assertion that was making a missing var silently fall through to the driver.
  • apps/web/README.md (new): document the local-dev + prod migrate workflows, including the vercel env pull pattern and a note on what to do if __drizzle_migrations drifts out of sync with the file system.

Why

When DATABASE_URL was unset, drizzle-kit migrate would pass undefined to the driver and hang on the "applying migrations..." spinner instead of erroring. No feedback, no exit. The fake non-null assertion didn't help.

The README gives anyone running the migrator an explicit, copy-pasteable path for both dev and prod so the next person doesn't end up staring at a silent spinner.

Test plan

  • pnpm turbo typecheck passes
  • pnpm turbo test passes
  • env -u DATABASE_URL node node_modules/.bin/drizzle-kit migrate prints the guard message and exits non-zero
  • pnpm db:migrate against a dev DB still works unchanged

Out of scope

  • A Vercel-specific convenience script (db:migrate:prod etc.). Kept this repo deployment-agnostic; the README walks through the pattern.

…orkflow

When DATABASE_URL was unset, drizzle-kit migrate would pass `undefined`
to the driver (the `process.env.DATABASE_URL!` non-null bang was a
fiction) and hang with a spinner instead of erroring. Caught while
applying #22 against a prod DB whose .env was stale.

- drizzle.config.ts: throw explicitly if DATABASE_URL is missing, with
  an actionable message pointing at the local/prod paths. Drop the
  misleading non-null assertion.
- Add apps/web/README.md with the local-dev + prod migrate workflows,
  including the vercel env pull pattern and what to do if
  __drizzle_migrations drifts out of sync with the file system.

Closes #24
Copilot AI review requested due to automatic review settings April 24, 2026 17:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens the Drizzle migration workflow for apps/web by failing fast when DATABASE_URL is missing and adding a dedicated apps/web README that documents local and production migration procedures (addressing the workflow gap described in issue #24).

Changes:

  • Add an explicit runtime guard in apps/web/drizzle.config.ts to throw when DATABASE_URL is unset (instead of relying on a non-null assertion).
  • Add apps/web/README.md documenting local dev Postgres setup and a production-safe migration workflow (including guidance for drizzle.__drizzle_migrations drift).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
apps/web/drizzle.config.ts Adds a DATABASE_URL presence check and uses the validated value in dbCredentials.
apps/web/README.md New documentation for local dev DB setup, migration generation/apply workflow, and production env handling.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/web/README.md Outdated
Comment thread apps/web/README.md Outdated
Comment thread apps/web/README.md Outdated
Comment thread apps/web/README.md
Comment thread apps/web/drizzle.config.ts Outdated
Comment thread apps/web/README.md Outdated
Copilot review on #25 flagged six real doc bugs:

- pnpm db:* scripts are in apps/web/package.json, not root — three
  examples told readers to run them from repo root which would fail
  with 'missing script'. Rewrite all invocations to use
  `pnpm --filter @repo/web <script>` (or `cd apps/web` where a
  multi-line flow reads better), and add a note at the top.
- Step 1 mentioned "schema.ts for pro-only tables" — there is no pro
  overlay in this repo, so drop the misleading parenthetical and
  point at schema-core.ts only.
- `node --env-file=` requires Node 20.6+, not just Node 20 — note the
  version and document the `pnpm dlx dotenv-cli` fallback.
- The error message in drizzle.config.ts said `vercel env pull` but
  without `--environment=production`, which defaults to development
  and would point the migrator at the wrong DB.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/web/drizzle.config.ts
Comment thread apps/web/README.md Outdated
Round-two review feedback on #25:

- The previous commit's guard threw at config-load for *all* drizzle-
  kit commands, breaking `db:generate` for anyone without
  DATABASE_URL set (generate is a file-only op that doesn't hit the
  DB). Gate the throw on `process.argv` matching a connection-
  requiring subcommand (migrate, push, pull, studio, introspect).
- Local-dev README used `echo ... >> apps/web/.env`, which accretes
  duplicate lines on repeat runs. Switch to a numbered list with a
  human instruction to create/edit the file and set DATABASE_URL.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/web/README.md Outdated
Round-three review feedback on #25: the backfill snippet wrote
`apps/web/drizzle/<tag>.sql` while the production migrate workflow
just above it has readers run from `apps/web`. Switch to relative
`drizzle/<tag>.sql` and explicitly anchor the backfill to the same
CWD.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/web/README.md Outdated
Round-four review feedback on #25: README claimed '.env*.local is
gitignored' but the repo's .gitignore has '.env*' with an exception
for '.env.example'. Update the wording to match so readers don't
assume only *.local variants are safe.
@davidstrouk
davidstrouk merged commit 98c3305 into main Apr 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reconcile drizzle.__drizzle_migrations so pnpm db:migrate works against prod

2 participants