fix(db,ci): make migration 0119 online-safe and bound production migrations
Summary
Unblocks production deploys after the 17 September API outage. Deploy Production is still disabled; this PR is what has to merge before it is turned back on.
- Migration 0119 no longer rewrites
ingest.webhook_events. The enum to text change onproviderwas a full rewrite of the largest table in production, run while the same transaction held ACCESS EXCLUSIVE locks onauth.users,auth.organizationsandintegration_connections. 0119 is regenerated withdrizzle-kit generateand is identical to the original minus that one statement. It rolled back during the incident and never applied in production. providerstays theintegration_providerenum. Every writer passeslinear,github,notionorslack, all already in the enum.recordWebhookDeliverygoes back to the enum type, so a non-enum provider is a compile error.- Production migrate job is bounded. A
concurrencygroup (three migrators ran at once during the incident) andPGOPTIONS: -c lock_timeout=5s -c statement_timeout=60s. drizzle applies every pending migration in one transaction, so splitting files does not isolate locks; timeouts are what make a blocked migration fail and roll back instead of stalling traffic. - Preview migrate step gets the same timeouts, so the preview database check runs what production will run.
Testing
Rehearsed with the exact CI command on a Neon branch of production (122 migrations applied, 540 GB webhook_events, 2 CU):
| Scenario | Result |
|---|---|
No timeouts, one held read lock on auth.users | Migrator still waiting on DROP TABLE ... CASCADE after 12s, killed |
| With timeouts, same blocker | Exit 1 after 7.0s, canceling statement due to lock timeout, clean rollback, still 122 applied |
| Clean run | Exit 0 in 2.3s, new tables present, old table and FK gone, provider still the enum |
| Re-run | No-op, exit 0 |
PGOPTIONS confirmed to reach the session through Neon's direct endpoint with the @neondatabase/serverless driver. db and api typecheck, ingest tests, lint and drizzle-kit check pass. The Deploy Database (Neon) check on this PR applies 0119 to a fresh branch of production with the same timeouts.
Notes
- The journal timestamp for 0119 is kept, so a dev database that already applied the old 0119 skips this one. Its
providercolumn stays text until the branch is reset; inserts still work. - #7589 carries its own
0119_slack_agent_launches.sqland needs a rebase and regenerate. - The concurrency group gets its first real exercise on the first merge after the workflow is re-enabled.
Summary by cubic
Fixes the 17 September production outage by regenerating migration 0119 without the webhook_events table rewrite and ordering its locks to match the application. Unblocks production deploys; Deploy Production stays disabled until this merges. Production migration runs are now bounded and retried.
Bug Fixes
- 0119 no longer changes
providerto text; the column stays theintegration_providerenum, andrecordWebhookDeliverytypes it as the enum so invalid providers fail compilation. - The
automation_eventsforeign key is dropped beforeplugin_connections, child table first like inserts, avoiding the deadlock seen under traffic. - The journal timestamp for 0119 is kept, so dev databases that already applied the old 0119 skip this one.
Reliability
- Production migrations run under a
concurrencygroup withlock_timeout=5sandstatement_timeout=60sviaPGOPTIONS; preview gets the same timeouts. - Because drizzle applies pending migrations in one transaction, those timeouts make a blocked migration roll back instead of holding traffic.
- The production migrate step makes up to eight attempts, retrying only on deadlock or lock timeout.
Summary by CodeRabbit
-
Bug Fixes
- Webhook delivery records now accept only supported integration providers, preventing invalid values.
- Webhook event data now consistently enforces the supported provider set at the database level.
-
Reliability
- Database deployments now apply lock and execution time limits to reduce stalled migrations.
- Production migrations run one at a time and retry select transient failures automatically.
- Migration ordering has been adjusted to reduce deployment conflicts.