Skip to content

feat(cli): default database workflows to the bundled pg-delta engine - #6102

Merged
avallete merged 58 commits into
developfrom
feat/upgrade-pg-delta-next
Aug 17, 2026
Merged

feat(cli): default database workflows to the bundled pg-delta engine#6102
avallete merged 58 commits into
developfrom
feat/upgrade-pg-delta-next

Conversation

@avallete

@avallete avallete commented Aug 6, 2026

Copy link
Copy Markdown
Member

Bundles @supabase/pg-delta and @supabase/pg-topo into the CLI and makes the in-process engine the default for pg-delta-backed db diff, db pull, and the declarative schema workflows (db schema declarative generate|sync). The legacy edge-runtime implementation remains available as an explicit SUPABASE_USE_PG_DELTA_NEXT=false opt-out; there is no automatic fallback or runtime package download — a next-engine failure propagates instead of silently switching implementations.

This branch is reconciled with the TypeScript database-command port on develop:

  • shared database bootstrap owns shadow-database setup and receives the complete local configuration, including database webhooks
  • pgAdmin uses the native TypeScript differ-container path, while db diff --use-pg-schema remains the sole Go delegation
  • --project-ref resolution stays in the TypeScript command path and is rejected for delegated modes that cannot honor it
  • local diffs target the running local database, while migration and declarative baselines use isolated shadow databases
  • declarative flows repair missing extension prerequisites, scope schema filters, and warn when unsupported object kinds would be omitted
  • when a legacy declarative tree cannot converge on the next engine, sync offers a staged recovery flow: it generates a next-compatible export into a sibling <declarative_schema_path>-next directory (never inside the active tree — trailing separators in the configured path are normalized, and staging into or under the active directory is rejected) and prints adoption commands built from the configured path
  • both compatibility gates (shadow-load failure and plan-refuse) render one shared recovery template: diagnosis, evidence, an explicit do-not-apply hazard line, and the staged-upgrade commands carried as the error suggestion — so a deliberate gate prints actionable guidance instead of the generic "rerun with --debug" footer. Non-interactive runs get exactly one recommended recovery (the staged regenerate); interactive prompts keep in-place extension repair as an advanced choice with a "may surface another gap" hint
  • db pull when already in sync keeps Go's "No schema changes found" message and non-zero exit, but replaces the debug footer with an explanatory suggestion (recorded in go-cli-divergences.md)
  • migration files preserve pg-delta's transaction=false directive so later push, reset, and up operations keep those plans outside CLI-owned transactions
  • migrations that call pg_net while local webhooks are disabled now surface targeted guidance to enable [experimental.webhooks]

Default-engine snapshots, plans, and diagnostics use an isolated v2 artifact layout. Extraction errors are refused; coverage gaps warn by default and can be promoted to failures with --strict-coverage on db diff, db pull, and the declarative commands (a TS-only flag, recorded in docs/go-cli-divergences.md). Generated SQL and file segmentation may differ from the legacy renderer — the compatibility contract is successful execution and convergence on a subsequent diff.

The branch pins published @supabase/pg-delta@1.0.0-alpha.41 and @supabase/pg-topo@1.0.0-alpha.5 from the npm registry, and patches the libpg-query parser packaging so the WASM asset is embedded in compiled Bun binaries (with an integration test verifying the patched asset survives compilation).

A live local-convergence suite (legacy-pgdelta-next.live.test.ts) exercises the next engine against a real Docker stack. It is gated on the configured live environment plus a Docker probe (describeDockerLive), so it runs only under the cli-e2e-ci harness — machines that merely expose Docker stay inert.

The earlier dogfooding playbook, ADR, and glossary documents were trimmed out of this PR to keep it scoped to the engine change. Linked-project, TLS-required, and pooler/SNI acceptance still needs a provisioned data-plane environment because the shared live harness does not create project Postgres.

@avallete
avallete requested a review from a team as a code owner August 6, 2026 07:15
@avallete avallete added the run-live-e2e-ci Execute the supabox live e2e tests and report back label Aug 6, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8078b53b04

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/commands/db/shared/legacy-pgdelta-engine.layer.ts Outdated
Comment thread apps/cli/tests/helpers/live.ts Outdated
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Supabase CLI preview

npx --yes https://pkg.pr.new/supabase/cli/supabase@509f6a9d23e83d2e88d459b746c522752c7c49e2

Preview package for commit 509f6a9.

@avallete

avallete commented Aug 6, 2026

Copy link
Copy Markdown
Member Author

Provisioned validation against exact head 4b697a2e5e0d5090ece6b319e6a1498db91afbcf: internal PG17 run.

  • Project provisioning reached the data plane, and the direct database endpoint connected over TLS with sslmode=require (SUPABASE_LIVE_DB_URL was set).
  • legacy-pgdelta-next.live.test.ts passed both tests: the full convergence scenario (260.2s) and explicit legacy opt-out smoke (25.8s).
  • The aggregate live project finished 19/22 tests. Its three failures were outside this PR's diff: an existing start-status timing assertion, an existing db-pull assertion, and an existing db-diff test colliding on host port 54320 while live files ran concurrently.

The labeled dispatch check itself cannot reach the internal repository because its GitHub App is not installed there, so this run was dispatched manually against the same SHA.

@avallete
avallete marked this pull request as draft August 6, 2026 08:12
@avallete
avallete marked this pull request as ready for review August 7, 2026 17:06
@avallete
avallete marked this pull request as draft August 7, 2026 17:07
Comment thread apps/cli/package.json Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

const exists = yield* fs.exists(w.path).pipe(

P2 Badge Detect collisions by migration version, not full path

When a multi-segment pg-delta plan is generated in the same second as an existing migration with a different name—or overlaps future-dated segments from a prior run—checking only w.path misses the collision because the filenames differ. This writes multiple files with the same 14-digit version; local migration loading accepts both, but schema_migrations.version is a primary key, so a pull can fail while repairing history and later push/reset operations can fail while applying the duplicate version. Check every candidate version against all existing migration filenames rather than only the generated pathname.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/commands/db/shared/legacy-pgdelta-engine.next.layer.ts Outdated
Comment thread apps/cli-go/internal/db/diff/shadow.go Outdated
@blacksmith-sh

This comment has been minimized.

@avallete
avallete marked this pull request as ready for review August 7, 2026 18:33
@avallete avallete removed the run-live-e2e-ci Execute the supabox live e2e tests and report back label Aug 7, 2026
Comment thread apps/cli/package.json Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d4861957ee

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/commands/db/shared/legacy-pgdelta-files.ts Outdated
Comment thread apps/cli/src/legacy/commands/db/shared/legacy-pgdelta-engine.next.layer.ts Outdated
@avallete
avallete marked this pull request as draft August 8, 2026 06:46
@avallete
avallete marked this pull request as ready for review August 8, 2026 10:22

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

for (const w of set) {
const exists = yield* fs.exists(w.path).pipe(
Effect.mapError(
(cause) =>

P1 Badge Check migration version collisions across all filenames

When a multi-unit plan assigns a version already used by another migration with a different name, this exact-path check reports no collision and writes a second <same-version>_*.sql file. This can occur when a migration was created in the same second as the pull/diff, or when a later plan unit's future-dated timestamp overlaps an existing file; db pull then upserts that version in schema_migrations, replacing the existing history row while both local files remain. Check for any ${version}_*.sql entry before accepting the generated set, rather than only each proposed pathname.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e912767ba6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/commands/db/schema/declarative/declarative.flow.ts Outdated
Comment thread apps/cli/src/legacy/shared/db-bootstrap/db-setup.ts
- Warn when a declarative tree still lives under the former
  supabase/database default while declarative_schema_path is unset and the
  new supabase/schemas default is empty, so upgraded projects are told how
  to keep their existing tree instead of silently regenerating elsewhere.
- Rename db schema declarative generate --output/-o to --output-dir (no
  short alias): the legacy root reserves --output/-o for the global
  machine-format flag, and the leaf string flag shadowed it, turning
  'generate -o json' into a write to a directory named json. Recorded in
  docs/go-cli-divergences.md.
- Render the staged-upgrade recovery commands for the host platform:
  single-line PowerShell (Remove-Item/Move-Item) on Windows, unchanged
  rm -rf/mv elsewhere, so the printed destructive commands run as printed.
- The interactive staged export now states it snapshots the running local
  database and offers the same reset-to-migrations prompt as the
  smart-target local path before exporting.
- Align the skipped-statement diagnostics comment with actual behavior:
  the raw statement is deliberately carried verbatim (user-local content);
  no redaction is claimed or attempted.
- Document the pg_net/[experimental.webhooks] convergence tradeoffs in the
  start/db start SIDE_EFFECTS and the divergence ledger, including the
  accepted Studio-installed-pg_net edge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ELeyDSbDjNbFzQ6kLKdxnQ

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b63da43e73

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/commands/db/diff/diff.handler.ts Outdated
avallete and others added 4 commits August 17, 2026 09:37
…layer

The production engine layer reimplemented the tested generic selector
inline via a private helper with a hand-maintained requirement union.
Generify the selector over its layers' requirements and delegate, so
one code path resolves and logs the implementation choice.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nary

The fixture imported @supabase/pg-topo eagerly, but production only
reaches it through the literal dynamic import inside pg-delta's
dist/frontends/sql-order.js. Route the fixture through analyzeForShadow
so the compile test proves Bun traces that dynamic import and embeds
the WASM asset for the real import shape.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ec1fb8b7b2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/commands/db/schema/declarative/declarative.flow.ts Outdated
Comment thread apps/cli/src/legacy/shared/legacy-db-push-core.ts
…hadow

Explicit-mode endpoint resolution is left-to-right and stateful: a
linked endpoint re-merges [remotes.<ref>] into the mutable cfg. The
migrations endpoint already honored that order for projectRef but
diffExplicit received the final cfg, so --from migrations --to linked
built the migrations shadow/catalog with the remote-merged webhooks,
vault, API-expose, and password baseline. Snapshot cfg when the first
migrations endpoint resolves and pass that snapshot as toml, covering
both engines at the handler seam.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a9421d96bb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

avallete and others added 3 commits August 17, 2026 10:33
The previous drift fix ran against a stale oxfmt install; the pinned
0.61.0 (and CI) want the original formatting.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The engine layer treats an empty shell SUPABASE_USE_PG_DELTA_NEXT as
present (godotenv parity), but push and the db-setup warmup resolved
the same flag through envLookup, which treats an empty shell value as
unset — so one project could warm the legacy catalog on push while
diff/pull/generate/sync ran the next engine. Hoist the presence-aware
combinator into legacy-pgdelta-next-flag.ts as the single source of
truth and use it at every call site.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Remove-Item errors are non-terminating, so the printed PowerShell
recovery line would still run Move-Item after a failed removal and
could move the staged export inside the still-existing active tree.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9f06ab1038

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/shared/legacy-migration-apply.ts
Explicit --from/--to URL endpoints on the next engine parsed against
process.env only, so PGPASSWORD/PGSSLMODE/PGPASSFILE kept in
supabase/.env worked with --db-url but failed with an explicit URL.
Hoist the shell-over-project lookup into legacyLayeredParseEnv, adopt
it in the --db-url resolver, and thread context.projectEnv through
acquireDatabase into endpoint parsing. Shadow URLs keep the plain
process env: they are CLI-generated with embedded credentials.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adopts the new default flat export layout: one directory per schema at
the declarative root with cluster-level objects under _cluster/, so the
default tree becomes supabase/schemas/public/... instead of the doubled
supabase/schemas/schemas/public/... The writer was already
layout-agnostic, so only next-engine fixtures, docs, and the pins
change; the legacy opt-out engine stays on the pinned alpha.33 nested
layout, recorded in go-cli-divergences.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b32909a9b5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/shared/legacy-db-push-core.ts
The legacy Edge Runtime catalog warmup after push, start, db start, and
reset is additionally gated on SUPABASE_USE_PG_DELTA_NEXT resolving to
the legacy engine; the default next engine skips it. The four
SIDE_EFFECTS.md checklists still said the catalog is written whenever
pg-delta is enabled and omitted the env var.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@avallete
avallete added this pull request to the merge queue Aug 17, 2026
@avallete
avallete removed this pull request from the merge queue due to a manual request Aug 17, 2026
@avallete
avallete added this pull request to the merge queue Aug 17, 2026
Merged via the queue into develop with commit d63a7db Aug 17, 2026
21 checks passed
@avallete
avallete deleted the feat/upgrade-pg-delta-next branch August 17, 2026 11:33
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.

4 participants