Skip to content

Commit 48218f3

Browse files
avalleteclaudejgoux
authored
fix(cli): skip pg_dump in db pull when using pg-delta diff engine (#5255)
## What Switches `supabase db pull --diff-engine pg-delta` to drive its initial pull from pg-delta's catalog diff instead of `pg_dump`, and lands the supporting plumbing (remote TLS handling, debug bundles, and a local pg-delta dev workflow) needed to make that path reliable against Cloud. Closes CLI-1472. ## Why The legacy initial-pull pipeline is `pg_dump` → restore into a local shadow → diff. That round-trip silently destroys ownership for any object the local `postgres` role can't assume: `pg_dump` emits `ALTER ... OWNER TO supabase_admin` (etc.), the restore runs as a non-superuser so the owner is dropped, and every restored object then reports `owner = postgres`. pg-delta's supabase integration filter drops platform-managed objects by `owner ∈ SUPABASE_SYSTEM_ROLES`, so once the owner signal is gone those objects leak into the user's migration file and break `supabase db reset` (CLI-1469 FDW ACLs, CLI-1470 Wasm wrappers). pg-delta already speaks `pg_catalog` directly via `extractCatalog`, preserving ownership, so diffing the remote catalog against an empty shadow produces a clean initial migration without `pg_dump` in the loop. ## What changed ### Initial-pull routing - `db pull` no longer runs `dumpRemoteSchema` on the initial pull when the pg-delta diff engine is selected; the shadow diff is the sole producer of the migration file (`internal/db/pull/pull.go`, `cmd/db.go`). - `shouldUseDeclarativePgDeltaPull` makes explicit `--diff-engine pg-delta` keep the migration-file workflow even when `[experimental.pgdelta] enabled = true` would otherwise default to the declarative export path. - New `swallowInitialInSync` / `ensureMigrationWritten` helpers distinguish "pg-delta produced no statements" from "pg_dump already wrote content", so an empty pg-delta result still surfaces `No schema changes found` correctly. ### Diff plumbing - `DiffDatabase` now returns a `DatabaseDiff` struct (`SQL` plus an optional debug capture) rather than a bare string; callers in `diff.go` and `pull.go` updated accordingly. - Removed the now-unused `diffWithStream` and its golangci exclusion. - The diff template (`templates/pgdelta.ts`) sets `skipDefaultPrivilegeSubtraction: true` and emits structured diagnostics under `PGDELTA_DEBUG`. ### Remote TLS handling for pg-delta - New `internal/gen/types/pgdelta_conn.go`: `PreparePgDeltaPostgresRef` writes the CA bundle into the workspace, forces `sslmode=verify-ca` + `sslrootcert`, and always uses the embedded bundle for Supabase-hosted hosts even when the SSL probe is skipped (e.g. `--debug`). Source/target now use distinct `PGDELTA_SOURCE_SSLROOTCERT` / `PGDELTA_TARGET_SSLROOTCERT` env vars. `pgdelta.go` and `pgcache/cache.go` refactored onto this helper. ### Debug bundles for empty pulls - New `PGDELTA_DEBUG` flag (separate from `--debug`; keeps SSL on). When a pg-delta pull returns zero statements, the CLI writes a bundle under `supabase/.temp/pgdelta/debug/<timestamp>/`: `source-catalog.json`, `target-catalog.json`, `pgdelta-stderr.txt`, `connection.txt` (redacted), and `error.txt`, plus a per-schema catalog object summary to stderr (`internal/db/diff/pgdelta_debug.go`, `internal/db/pull/pgdelta_pull_debug.go`). - `DiffPgDeltaRefDetailed` surfaces edge-runtime stderr; `declarative.DebugBundle` gains inline-catalog, stderr, and connection-info fields. ### Local pg-delta dev workflow - `PGDELTA_NPM_REGISTRY` (`pkg/config/pgdelta_local.go`, `internal/utils/pgdelta_local.go`) routes Deno's `npm:@supabase/pg-delta` resolution through a local Verdaccio registry. The edge-runtime helper gained composable `WithExtraFile` / `WithExtraEnv` options to drop a scoped `.npmrc` and forward `NPM_CONFIG_REGISTRY`; all pg-delta edge-runtime calls now pass `PgDeltaNpmRegistryOption()`. Documented in `CONTRIBUTING.md`. ### Version, build, and docs - `DefaultPgDeltaNpmVersion` bumped to `1.0.0-alpha.27`. - `apps/cli/package.json` adds a `build:go-sidecar` step that copies the Go binary into `dist/`. - `docs/supabase/db/pull.md` documents the new initial-pull behavior, the experimental declarative default, the direct-connection recommendation for `--db-url`, and the `PGDELTA_DEBUG` workflow. ## Reviewer notes - The FDW/server ACL and `CREATE FOREIGN DATA WRAPPER` suppression rules in `@supabase/pg-delta` become defense-in-depth on this path rather than load-bearing. - Scope is schema-only / migration generation: `supabase db dump` and the declarative export path still use `pg_dump` / the existing flows. https://claude.ai/code/session_016o7U7hiut6dkkhfbSJgKv4 --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Julien Goux <hi@jgoux.dev>
1 parent ec23369 commit 48218f3

27 files changed

Lines changed: 1155 additions & 129 deletions

apps/cli-go/.golangci.yml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ linters:
1616
exclusions:
1717
generated: lax
1818
rules:
19-
- text: 'ST1003:'
19+
- text: "ST1003:"
2020
linters:
2121
- staticcheck
2222
- path: _test\.go
@@ -27,10 +27,7 @@ linters:
2727
linters:
2828
- gosec
2929
text: G117
30-
- path: internal/db/diff/diff\.go
31-
linters:
32-
- unused
33-
text: diffWithStream is unused
30+
3431
presets:
3532
- comments
3633
- common-false-positives

apps/cli-go/CONTRIBUTING.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,52 @@ go test ./... -race -v -count=1 -failfast
4141
## API client
4242

4343
The Supabase API client is generated from OpenAPI spec. See [our guide](api/README.md) for updating the client and types.
44+
45+
## Testing local pg-delta builds
46+
47+
To exercise unpublished `@supabase/pg-delta` changes inside CLI edge-runtime scripts (`db pull`, `db diff`, `db push`, etc.), publish a local build via Verdaccio in [pg-toolbelt](https://github.com/supabase/pg-toolbelt) and point the CLI at that registry.
48+
49+
### 1. Start Verdaccio (pg-toolbelt)
50+
51+
```sh
52+
cd pg-toolbelt
53+
bun run verdaccio:start
54+
```
55+
56+
Verdaccio listens on `http://localhost:4873`. `@supabase/*` packages you publish locally are served from local storage; other `@supabase/*` dependencies (for example `@supabase/pg-topo`) are proxied to npmjs.
57+
58+
### 2. Publish a local pg-delta build
59+
60+
After changing `packages/pg-delta`:
61+
62+
```sh
63+
bun run pg-delta:publish-local \
64+
--write-version-to=/path/to/test-project/supabase/.temp/pgdelta-version
65+
```
66+
67+
This publishes a fresh `0.0.0-local.<timestamp>` version and restores `package.json` afterward. The version file tells the CLI which npm version to request (`EffectivePgDeltaNpmVersion`).
68+
69+
Re-run whenever you change pg-delta source.
70+
71+
### 3. Run the CLI against the local registry
72+
73+
Set `PGDELTA_NPM_REGISTRY` to a URL reachable **from inside the edge-runtime Docker container**:
74+
75+
```sh
76+
# Docker Desktop (macOS / Windows)
77+
export PGDELTA_NPM_REGISTRY=http://host.docker.internal:4873
78+
79+
# Linux (Docker 20.10+)
80+
export PGDELTA_NPM_REGISTRY=http://host.docker.internal:4873
81+
# or: export PGDELTA_NPM_REGISTRY=http://172.17.0.1:4873
82+
```
83+
84+
Then run any pg-delta-backed command, for example:
85+
86+
```sh
87+
supabase db pull --db-url "$DATABASE_URL" --diff-engine pg-delta
88+
```
89+
90+
When set, the CLI injects a scoped `.npmrc` and forwards `NPM_CONFIG_REGISTRY` into the edge-runtime container (`PgDeltaNpmRegistryOption` in `internal/utils/pgdelta_local.go`).
91+
92+
Unset `PGDELTA_NPM_REGISTRY` to return to the npmjs version pinned in config / `supabase/.temp/pgdelta-version`.

apps/cli-go/cmd/db.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ var (
181181
if usePgDeltaDiff {
182182
pullDiffer = diff.DiffPgDelta
183183
}
184-
useDeclarativePgDelta := shouldUsePgDelta()
184+
useDeclarativePgDelta := shouldUseDeclarativePgDeltaPull(usePgDeltaDiff)
185185
return pull.Run(cmd.Context(), schema, flags.DbConfig, name, useDeclarativePgDelta, usePgDeltaDiff, pullDiffer, afero.NewOsFs())
186186
},
187187
PostRun: func(cmd *cobra.Command, args []string) {
@@ -358,6 +358,13 @@ func shouldUsePgDelta() bool {
358358
return utils.IsPgDeltaEnabled() || usePgDelta || viper.GetBool("EXPERIMENTAL_PG_DELTA")
359359
}
360360

361+
func shouldUseDeclarativePgDeltaPull(usePgDeltaDiff bool) bool {
362+
if usePgDeltaDiff {
363+
return false
364+
}
365+
return shouldUsePgDelta()
366+
}
367+
361368
func init() {
362369
// Build branch command
363370
dbBranchCmd.AddCommand(dbBranchCreateCmd)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package cmd
2+
3+
import (
4+
"testing"
5+
6+
"github.com/spf13/viper"
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestShouldUseDeclarativePgDeltaPull(t *testing.T) {
11+
t.Run("diff-engine pg-delta keeps the migration-file workflow", func(t *testing.T) {
12+
usePgDelta = false
13+
t.Cleanup(func() { usePgDelta = false })
14+
assert.False(t, shouldUseDeclarativePgDeltaPull(true))
15+
})
16+
17+
t.Run("no flag and no config means not declarative", func(t *testing.T) {
18+
usePgDelta = false
19+
t.Cleanup(func() { usePgDelta = false })
20+
assert.False(t, shouldUseDeclarativePgDeltaPull(false))
21+
})
22+
23+
t.Run("experimental config enables declarative", func(t *testing.T) {
24+
usePgDelta = false
25+
viper.Set("EXPERIMENTAL_PG_DELTA", true)
26+
t.Cleanup(func() {
27+
usePgDelta = false
28+
viper.Set("EXPERIMENTAL_PG_DELTA", false)
29+
})
30+
assert.True(t, shouldUseDeclarativePgDeltaPull(false))
31+
})
32+
33+
t.Run("use-pg-delta flag forces declarative", func(t *testing.T) {
34+
usePgDelta = true
35+
t.Cleanup(func() { usePgDelta = false })
36+
assert.True(t, shouldUseDeclarativePgDeltaPull(false))
37+
})
38+
}

apps/cli-go/docs/supabase/db/pull.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,30 @@ Requires your local project to be linked to a remote database by running `supaba
88
99
Optionally, a new row can be inserted into the migration history table to reflect the current state of the remote database.
1010

11-
If no entries exist in the migration history table, `pg_dump` will be used to capture all contents of the remote schemas you have created. Otherwise, this command will only diff schema changes against the remote database, similar to running `db diff --linked`.
11+
If no entries exist in the migration history table, the default diff engine uses `pg_dump` to capture all contents of the remote schemas you have created. Otherwise, this command will only diff schema changes against the remote database, similar to running `db diff --linked`.
1212

13-
Pass `--diff-engine pg-delta` to keep the migration-file `db pull` workflow while using pg-delta for the shadow diff step. Pass `--use-pg-delta` to switch to the declarative pg-delta export workflow instead.
13+
Pass `--diff-engine pg-delta` to keep the migration-file `db pull` workflow while using pg-delta for the shadow diff step. On initial pull, pg-delta replaces `pg_dump` and produces the full migration from the shadow diff alone. Pass `--use-pg-delta` to switch to the declarative pg-delta export workflow instead.
14+
15+
When `[experimental.pgdelta] enabled = true` is set in `config.toml`, `db pull` defaults to the declarative export path. Explicit `--diff-engine pg-delta` still selects the migration-file workflow.
16+
17+
When pulling from a remote database with `--db-url`, prefer a direct connection (`db.<project-ref>.supabase.co:5432`) over the connection pooler so pg-delta can introspect the full catalog reliably.
18+
19+
## Debugging empty pg-delta pulls
20+
21+
If `db pull --diff-engine pg-delta` reports `No schema changes found` but you expect schema output, set `PGDELTA_DEBUG=1` before running the command. Unlike `--debug`, this keeps SSL enabled for remote Supabase connections.
22+
23+
```sh
24+
PGDELTA_DEBUG=1 supabase db pull --db-url "$DATABASE_URL" --diff-engine pg-delta
25+
```
26+
27+
When pg-delta returns zero statements, the CLI writes a debug bundle under `supabase/.temp/pgdelta/debug/<timestamp>/`:
28+
29+
- `source-catalog.json` — shadow database baseline pg-delta extracted
30+
- `target-catalog.json` — remote database pg-delta extracted
31+
- `pgdelta-stderr.txt` — pg-delta script diagnostics (statement count, schemas)
32+
- `connection.txt` — redacted connection metadata
33+
- `error.txt` — error summary
34+
35+
Catalog files are not written during normal `db pull` runs. The `.temp/pgdelta` directory is also used by migration catalog caching (`db push`, local `db start`) when `[experimental.pgdelta] enabled = true`.
36+
37+
For TLS tracing without disabling SSL, use `SUPABASE_SSL_DEBUG=true` alongside `PGDELTA_DEBUG=1`.

apps/cli-go/internal/db/declarative/debug.go

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,16 @@ const (
1818

1919
// DebugBundle collects diagnostic artifacts when a declarative operation fails.
2020
type DebugBundle struct {
21-
ID string // timestamp-based unique ID (e.g. "20240414-044403")
22-
SourceRef string // path to source catalog
23-
TargetRef string // path to target catalog
24-
MigrationSQL string // generated migration (if available)
25-
Error error // the error that occurred
26-
Migrations []string // list of local migration files
21+
ID string // timestamp-based unique ID (e.g. "20240414-044403")
22+
SourceRef string // path to source catalog
23+
TargetRef string // path to target catalog
24+
SourceCatalog string // inline source catalog JSON (optional)
25+
TargetCatalog string // inline target catalog JSON (optional)
26+
MigrationSQL string // generated migration (if available)
27+
PgDeltaStderr string // edge-runtime stderr from pg-delta scripts
28+
ConnectionInfo string // redacted connection metadata
29+
Error error // the error that occurred
30+
Migrations []string // list of local migration files
2731
}
2832

2933
// SaveDebugBundle writes diagnostic artifacts to .temp/pgdelta/debug/<ID>/ and
@@ -38,14 +42,18 @@ func SaveDebugBundle(bundle DebugBundle, fsys afero.Fs) (string, error) {
3842
}
3943

4044
// Copy source catalog if available
41-
if len(bundle.SourceRef) > 0 {
45+
if len(bundle.SourceCatalog) > 0 {
46+
_ = utils.WriteFile(filepath.Join(debugDir, "source-catalog.json"), []byte(bundle.SourceCatalog), fsys)
47+
} else if len(bundle.SourceRef) > 0 {
4248
if data, err := afero.ReadFile(fsys, bundle.SourceRef); err == nil {
4349
_ = utils.WriteFile(filepath.Join(debugDir, "source-catalog.json"), data, fsys)
4450
}
4551
}
4652

4753
// Copy target catalog if available
48-
if len(bundle.TargetRef) > 0 {
54+
if len(bundle.TargetCatalog) > 0 {
55+
_ = utils.WriteFile(filepath.Join(debugDir, "target-catalog.json"), []byte(bundle.TargetCatalog), fsys)
56+
} else if len(bundle.TargetRef) > 0 {
4957
if data, err := afero.ReadFile(fsys, bundle.TargetRef); err == nil {
5058
_ = utils.WriteFile(filepath.Join(debugDir, "target-catalog.json"), data, fsys)
5159
}
@@ -61,6 +69,14 @@ func SaveDebugBundle(bundle DebugBundle, fsys afero.Fs) (string, error) {
6169
_ = utils.WriteFile(filepath.Join(debugDir, "error.txt"), []byte(bundle.Error.Error()), fsys)
6270
}
6371

72+
if len(bundle.PgDeltaStderr) > 0 {
73+
_ = utils.WriteFile(filepath.Join(debugDir, "pgdelta-stderr.txt"), []byte(bundle.PgDeltaStderr), fsys)
74+
}
75+
76+
if len(bundle.ConnectionInfo) > 0 {
77+
_ = utils.WriteFile(filepath.Join(debugDir, "connection.txt"), []byte(bundle.ConnectionInfo), fsys)
78+
}
79+
6480
// Copy migration files
6581
if len(bundle.Migrations) > 0 {
6682
migrationsDir := filepath.Join(debugDir, "migrations")

apps/cli-go/internal/db/diff/diff.go

Lines changed: 32 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package diff
22

33
import (
4-
"bytes"
54
"context"
65
"fmt"
76
"io"
@@ -22,7 +21,6 @@ import (
2221
"github.com/jackc/pgconn"
2322
"github.com/jackc/pgx/v4"
2423
"github.com/spf13/afero"
25-
"github.com/spf13/viper"
2624
"github.com/supabase/cli/internal/db/start"
2725
"github.com/supabase/cli/internal/pgdelta"
2826
"github.com/supabase/cli/internal/utils"
@@ -33,10 +31,11 @@ import (
3331
type DiffFunc func(context.Context, pgconn.Config, pgconn.Config, []string, ...func(*pgx.ConnConfig)) (string, error)
3432

3533
func Run(ctx context.Context, schema []string, file string, config pgconn.Config, differ DiffFunc, usePgDelta bool, fsys afero.Fs, options ...func(*pgx.ConnConfig)) (err error) {
36-
out, err := DiffDatabase(ctx, schema, config, os.Stderr, fsys, differ, usePgDelta, options...)
34+
result, err := DiffDatabase(ctx, schema, config, os.Stderr, fsys, differ, usePgDelta, options...)
3735
if err != nil {
3836
return err
3937
}
38+
out := result.SQL
4039
branch := utils.GetGitBranch(fsys)
4140
fmt.Fprintln(os.Stderr, "Finished "+utils.Aqua("supabase db diff")+" on branch "+utils.Aqua(branch)+".\n")
4241
if err := SaveDiff(out, file, fsys); err != nil {
@@ -161,18 +160,18 @@ func MigrateShadowDatabase(ctx context.Context, container string, fsys afero.Fs,
161160
return migration.ApplyMigrations(ctx, migrations, conn, afero.NewIOFS(fsys))
162161
}
163162

164-
func DiffDatabase(ctx context.Context, schema []string, config pgconn.Config, w io.Writer, fsys afero.Fs, differ DiffFunc, usePgDelta bool, options ...func(*pgx.ConnConfig)) (string, error) {
163+
func DiffDatabase(ctx context.Context, schema []string, config pgconn.Config, w io.Writer, fsys afero.Fs, differ DiffFunc, usePgDelta bool, options ...func(*pgx.ConnConfig)) (DatabaseDiff, error) {
165164
fmt.Fprintln(w, "Creating shadow database...")
166165
shadow, err := CreateShadowDatabase(ctx, utils.Config.Db.ShadowPort)
167166
if err != nil {
168-
return "", err
167+
return DatabaseDiff{}, err
169168
}
170169
defer utils.DockerRemove(shadow)
171170
if err := start.WaitForHealthyService(ctx, utils.Config.Db.HealthTimeout, shadow); err != nil {
172-
return "", err
171+
return DatabaseDiff{}, err
173172
}
174173
if err := MigrateShadowDatabase(ctx, shadow, fsys, options...); err != nil {
175-
return "", err
174+
return DatabaseDiff{}, err
176175
}
177176
shadowConfig := pgconn.Config{
178177
Host: utils.Config.Hostname,
@@ -189,20 +188,20 @@ func DiffDatabase(ctx context.Context, schema []string, config pgconn.Config, w
189188
declDir := utils.GetDeclarativeDir()
190189
if exists, _ := afero.DirExists(fsys, declDir); exists {
191190
if err := pgdelta.ApplyDeclarative(ctx, config, fsys); err != nil {
192-
return "", err
191+
return DatabaseDiff{}, err
193192
}
194193
} else {
195194
if err := migrateBaseDatabase(ctx, config, declared, fsys, options...); err != nil {
196-
return "", err
195+
return DatabaseDiff{}, err
197196
}
198197
}
199198
} else {
200199
if err := migrateBaseDatabase(ctx, config, declared, fsys, options...); err != nil {
201-
return "", err
200+
return DatabaseDiff{}, err
202201
}
203202
}
204203
} else if err != nil {
205-
return "", err
204+
return DatabaseDiff{}, err
206205
}
207206
}
208207
// Load all user defined schemas
@@ -211,7 +210,28 @@ func DiffDatabase(ctx context.Context, schema []string, config pgconn.Config, w
211210
} else {
212211
fmt.Fprintln(w, "Diffing schemas...")
213212
}
214-
return differ(ctx, shadowConfig, config, schema, options...)
213+
if IsPgDeltaDebugEnabled() && usePgDelta {
214+
// Capture the shadow baseline catalog and edge-runtime stderr so an
215+
// empty diff can be inspected later. DiffPgDeltaRefDetailed mirrors the
216+
// pg-delta differ but additionally surfaces stderr, which differ() drops.
217+
debugCapture := &PgDeltaDebugCapture{}
218+
if snapshot, exportErr := exportCatalogPgDelta(ctx, utils.ToPostgresURL(shadowConfig), "postgres", options...); exportErr == nil {
219+
debugCapture.SourceCatalog = snapshot
220+
} else {
221+
fmt.Fprintf(w, "Warning: failed to export shadow pg-delta catalog: %v\n", exportErr)
222+
}
223+
result, err := DiffPgDeltaRefDetailed(ctx, utils.ToPostgresURL(shadowConfig), utils.ToPostgresURL(config), schema, pgDeltaFormatOptions(), options...)
224+
if err != nil {
225+
return DatabaseDiff{}, err
226+
}
227+
debugCapture.Stderr = result.Stderr
228+
return DatabaseDiff{SQL: result.SQL, Debug: debugCapture}, nil
229+
}
230+
output, err := differ(ctx, shadowConfig, config, schema, options...)
231+
if err != nil {
232+
return DatabaseDiff{}, err
233+
}
234+
return DatabaseDiff{SQL: output}, nil
215235
}
216236

217237
func migrateBaseDatabase(ctx context.Context, config pgconn.Config, migrations []string, fsys afero.Fs, options ...func(*pgx.ConnConfig)) error {
@@ -228,37 +248,3 @@ func migrateBaseDatabase(ctx context.Context, config pgconn.Config, migrations [
228248
defer conn.Close(context.Background())
229249
return migration.SeedGlobals(ctx, migrations, conn, afero.NewIOFS(fsys))
230250
}
231-
232-
func diffWithStream(ctx context.Context, env []string, script string, stdout io.Writer) error {
233-
cmd := utils.EdgeRuntimeStartCmd()
234-
if viper.GetBool("DEBUG") {
235-
cmd = append(cmd, "--verbose")
236-
}
237-
cmdString := strings.Join(cmd, " ")
238-
entrypoint := []string{"sh", "-c", `cat <<'EOF' > index.ts && ` + cmdString + `
239-
` + script + `
240-
EOF
241-
`}
242-
var stderr bytes.Buffer
243-
if err := utils.DockerRunOnceWithConfig(
244-
ctx,
245-
container.Config{
246-
Image: utils.Config.EdgeRuntime.Image,
247-
Env: env,
248-
Entrypoint: entrypoint,
249-
},
250-
container.HostConfig{
251-
Binds: []string{utils.EdgeRuntimeId + ":/root/.cache/deno:rw"},
252-
NetworkMode: network.NetworkHost,
253-
},
254-
network.NetworkingConfig{},
255-
"",
256-
stdout,
257-
&stderr,
258-
// The "main worker has been destroyed" message may not appear at the start of stderr
259-
// (e.g. preceded by other Deno runtime output), so use Contains instead of HasPrefix.
260-
); err != nil && !strings.Contains(stderr.String(), "main worker has been destroyed") {
261-
return errors.Errorf("error diffing schema: %w:\n%s", err, stderr.String())
262-
}
263-
return nil
264-
}

0 commit comments

Comments
 (0)