fix(cli): port db diff --use-pgadmin to a native differ-container invocation (CLI-1968) - #6150
Conversation
…ocation (CLI-1968)
Supabase CLI previewnpx --yes https://pkg.pr.new/supabase/cli/supabase@b37dc5eeca04bfbde1af643060dce6ece445030ePreview package for commit |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b42eaed583
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b1111ab283
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 09f0ec0363
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fbe84e1d2b
ℹ️ 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".
## What changed
Rewrites `migration squash` from a Go-proxy wrapper into native
TypeScript — the last `LegacyGoProxy` use in the migration family:
- **`squash.handler.ts`** (full rewrite): version validation (bare
`invalid version number`, Go's non-repair-wrapped form) → shadow DB
(create → health-wait → connect → `SetupDatabase`, deliberately
*without* the `contrib_regression` template, matching Go) → before/after
`auth`+`storage` schema dumps → apply migrations → full-schema dump
rewritten into the last migration file (single `O_TRUNC` open, Go
parity) + separator + line-by-line diff → merged-file deletion
(non-fatal per file) → local suggestion / remote prompt + history
baseline (`DELETE version <= $1` + `INSERT` in one transaction, matching
`migration repair`'s established shape).
- **`squash.diff.ts`** (new): byte-exact port of Go's `lineByLineDiff` +
`bufio.ScanLines`, unit-tested against Go's own `testdata/` fixtures.
**`squash.dump.ts`**, **`squash.errors.ts`** (error-actionability
taxonomy) round it out.
- **Promotions** per "Hoist Before You Duplicate":
`legacy-pg-dump.{env,run,scripts}.ts` moved `commands/db/shared/` →
`legacy/shared/` (squash is the first cross-family consumer; the
Go-script byte-equality test moved with them), and
`legacyShadowRunInputFromLocalContainerInputs` hoisted into
`shared/db-bootstrap/shadow-database.ts` (re-export shim removed;
diff/pull/pgdelta-cache call sites repointed).
- TS-only additive surface: `--output-format json`/`stream-json` payload
`{ squashedInto, removed, removeFailures, alreadyEarliest, isLocal,
baselinedVersion }` (Go owns no machine output here; `removed` =
successful deletions, `removeFailures` = the rest).
## Why
Part of M9 (Go removal). `migration squash` was the last wrapped
migration command; every building block became available once CLI-1956
(supabase#6027) landed. Going native also dissolves the go-parity-audit §3.4
caveat — the proxy couldn't distinguish "`--local` unset" from
"`--local=false`"; the native command models `--local` with
`Flag.withDefault(true)` exactly like `migration up`.
## Reviewer-relevant context
- **Go-parity audit verdict: parity OK.** Highlights it verified: the
decline-prompt-is-**success** path (exit 0 — opposite of
repair/fetch/down), `Baselining migration history to <v>` printing
*before* `Connecting to remote database...`, resolve-before-validate
ordering, the single-migration no-op with zero Docker work,
leak-on-create-failure parity, the exact three-container pg_dump env
matrix (`EXTRA_FLAGS=--schema=auth|storage` vs `EXCLUDED_SCHEMAS`,
`EXTRA_SED=/^--/d`), and `lineByLineDiff` byte-exact against Go's
goldens plus throwaway `bufio` runs. The explicit baseline transaction
was adjudicated equivalent to Go's `pgx.Batch` (single implicit
transaction either way).
- Engineer review found no production bugs; all its items are applied —
including an ordered `BEGIN/DELETE/INSERT/COMMIT` assertion (an
INSERT-before-DELETE mutation previously shipped green),
workdir-relativized error paths via `legacyRelativizeErrorMessage`, and
the `dbConnection` classification matching `repair`'s identical failure.
- Tests: 16 unit (Go testdata read directly from `apps/cli-go`) + 48
integration + 2 Docker-free e2e; 100% branch coverage on the squash
files; key assertions mutation-tested.
- `go-cli-porting-status.md`: both squash rows flipped to `ported`, and
pre-existing aggregate drift corrected (Database family was recorded
5/19 ported, actually 43/43; Project/Stack Lifecycle 2→4; grand summary
now 51/118 fully ported, 59/118 partial).
- Merge-order note: this PR moves `legacy-pg-dump.env.ts`, which supabase#6150
(CLI-1968) imports from the old path — whichever merges second needs a
one-line import-path fix (both also touch
`tests/helpers/legacy-mocks.ts`, trivially).
Fixes CLI-1969
What changed
Ports the
db diff --use-pgadminengine from delegating the whole invocation to the bundled Go binary to a native TypeScript implementation:legacy-pgadmin-diff.ts(new): the differ-container loop (onesupabase/pgadmin-schema-diff:cli-0.0.5run, or one per--schema, with Go's exact argv/env/network/labels/extraHosts) plus pure ports of Go'sProcessDiffOutput(JSON diff filtering: type whitelist, extension-dependency skip,InternalSchemasexclusion, pgAdmin header assembly) andProcessDiffProgress(stderr%-regex → status lines, including Go's greedy-submatch and.-matches-\rsemantics via thesflag).diff.handler.ts: the pgadmin branch now runs natively —AssertSupabaseDbIsRunningparity check → native shadow (CLI-1956 primitives,acquireUseRelease) → differ run → the shared SaveDiff tail (No schema changes foundatlen < 2,--filemigration write + warning, stdout print).rebuildDelegateArgsbecame the pg-schema-onlyrebuildPgSchemaDelegateArgs:--use-pg-schemais now the sole remaining Go delegation ondb diff(CLI-1960).Why
Part of M9 (Go removal). Unlike
--use-pg-schema(in-processstripe/pg-schema-diffGo library — documented keep-in-Go exception), the pgAdmin engine was never Go-bound: it is a plain container invocation plus pure output post-processing. Its only real blocker was native shadow provisioning, which landed in CLI-1956 (#6027).Reviewer-relevant context
DiffStreamuses value receivers (internal/utils/container_output.go:79,87), soCollect()always reads an empty buffer: the Go CLI's--use-pgadminhas always printedNo schema changes found(exit 0), never written a migration file, and can never hit a JSON parse error (verified empirically against Go 1.26). This port implements the intended algorithm instead; the ruling is recorded inSIDE_EFFECTS.md("Deliberate divergence") and as a comment on CLI-1968.127.0.0.1URLs is reachable from the differ container — identically in both implementations (same argv/network → same outcome).--network-id hostalone doesn't rescue it either (it also rewires the shadow, discarding its port publication); both databases are reachable only with host networking plus a contrivedshadow_port = 5432override — identically on both binaries — which is exactly where the divergence above becomes user-visible. A gated live scenario was added todiff.live.test.ts(not executed in CI).encoding/jsonacceptance rules andstrings.TrimSpaceUnicode semantics) and an engineer review; all findings applied — notably:/sregex flag, type predicates instead of anascast, a 3-way docker error-reason mapping (image_inspect), machine-mode status lines redirected to stderr instead of dropped, restored child-telemetry assertions on the surviving pg-schema delegation, andlegacyTrimGoSpacehoisted tocommands/db/shared/legacy-go-string.ts.legacy-pg-dump.env.ts(this PR importsLEGACY_INTERNAL_SCHEMASfrom its current path) — whichever merges second needs a one-line import-path fix.Fixes CLI-1968