Uh oh!
There was an error while loading. Please reload this page.
fix(cli): match Go bundler env and deploy path anchoring (CLI-1985) - #6005
Conversation
Two functions deploy parity fixes against the pinned Go CLI: - Stop forwarding NPM_AUTH_TOKEN into the eszip Docker bundler container; Go forwards only NPM_CONFIG_REGISTRY (bundle.go:68-70). This reverts the TS-only forwarding from #5645 (the Go-side #4933 was closed unmerged). BREAKING for private-registry users whose .npmrc expands NPM_AUTH_TOKEN during --use-docker deploys: inline the token in .npmrc or deploy via --use-api instead. - Anchor API-deploy uploaded file names and the server-recorded entrypoint_path/import_map_path/static_patterns at the workdir, matching Go's toRelPath (relative to os.Getwd(), forward slashes). The git-root import-walk boundary from #5755 is kept, so monorepo imports outside the workdir still deploy, now with Go-style ../-relative names.
Coly010
commented
Jul 30, 2026
@codex review |
Codex Review: Didn't find any major issues. Breezy! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
…5-functions-deploy-rulings-npm_auth_token-forwarding-and-git
Supabase CLI previewnpx --yes https://pkg.pr.new/supabase/cli/supabase@e1b18f3d479f1fca5f2a6a21bdbb9e61f7fe9850Preview package for commit |
kanadgupta
left a comment
There was a problem hiding this comment.
Claude discovered a potential issue where the server might reject the file name and suggests trying this yourself — I think this would be better suited for the e2e tests I'm hoping to work on soon. Will defer to you on the best course of action here — LGTM otherwise!
Uh oh!
There was an error while loading. Please reload this page.
…ir (CLI-1985) Go's writeForm/addFile opens every uploaded path through an fs.FS, which rejects any path containing a ".." element via fs.ValidPath before the read (and thus the upload) happens. A workdir≠git-root layout could make the TS deploy path anchoring produce a multipart File name like "../packages/shared/src/index.ts" that escapes the workdir and reaches the server for the first time from any CLI. Hard-fail with the same Go-parity error before any upload is attempted, and update the deploy integration tests that had been asserting the escaping upload succeeded.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:e1b18f3d47
ℹ️ 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".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…audit (CLI-1967) (supabase#6074) ## What Doc/comment-accuracy sweep from `apps/cli/docs/go-parity-audit-2026-07-24.md` §6 (untracked locally, not part of this repo). No runtime behavior changes — every item below was independently re-verified against current Go (`apps/cli-go/`) and TS source before fixing, since the audit is 12 days old and several items had drifted further in that time (in both directions). ## Fixed - **`docs/go-cli-porting-status.md`** — `functions list` legacy-shell status `wrapped` → `ported` (verified: zero `LegacyGoProxy` refs). `functions download` status corrected the other way, `ported` → `wrapped` (its handler still delegates wholesale via `LegacyGoProxy` for the default `--use-docker` path; only `--use-api` is native — noted as a hybrid in the row). Added a `ported` definition to the legacy-status legend (it only defined `wrapped`/`missing`, despite `ported` being ~90% of rows) and retitled that section from "Legacy Shell Wrapping Status" to "Legacy Shell Command Status" to match. Fixed the adjacent `functions delete/deploy/list/new/serve` legacy-shell notes, which all still said "Wrapped in legacy shell" despite being natively ported. - **`legacy-pgdelta.seam.service.ts`** — fixed two stale doc comments (`execInherit`, `ensureLocalDatabaseStarted`) that referenced things as "not yet ported" when they now are (`db reset`, `start`/`db start`). Did **not** touch `exportCatalog`'s doc comment / `LegacyCatalogMode`, which the audit also flagged — that exact hunk is already being rewritten more completely by the in-flight CLI-1959 PR (supabase#6061, open); fixing it here would guarantee a conflict with a strictly better version. `legacy-db-bootstrap.seam.service.ts` (the audit's other named file) was checked and found already accurate — CLI-1954/1955 (native `db start`/`db reset --local`) are still unmerged, so its "not yet ported" claim is currently true. - **`network-restrictions/{get,update}/SIDE_EFFECTS.md`** — the `-o {json,yaml,toml,env}` sections previously implied Go itself produces distinct byte-identical output per format. Verified against Go source: `restrictions/get`/`update` never read `OutputFormat` at all — they always print the same 3-line `fmt.Printf` template regardless of `-o`. Corrected both docs to state this plainly, documented that TS's format-specific output here is a deliberate TS-only enhancement with no real Go behavior to match (including no Go casing convention, since TS uses the map-shaped encoders rather than CLI-1975's struct-spec ones), and trimmed the resulting repetition. - **`inspect/report/SIDE_EFFECTS.md`** — added the empty/no-file divergence on `COPY` failure: Go's `copyToCSV` opens the output file with `O_TRUNC` before running the query, so a failing query still leaves a file (empty or partial); TS buffers in memory and only writes on success, leaving no file on a fresh run — and leaving the *previous* run's stale CSV in place on a same-day re-run (the more consequential case). Cross-referenced from `legacy-db-connection.errors.ts`'s `LegacyDbCopyError` doc comment, which already covered the message-text angle of the same divergence. - **`domains.cname.ts`** — the comment describing Go's CNAME "failed to locate" error dump wrongly implied Go embeds readable JSON. Verified against Go source and empirically (compiled the equivalent locally): Go JSON-marshals the answers to a `[]byte`, then formats that `[]byte` with `%+v`, which Go's `fmt` renders as an uncapped decimal byte-value array, not the JSON text — a `%+v`-on-`[]byte` footgun, not an intended format. Fixed both the function's JSDoc and the inline comment (they'd contradicted each other after an earlier pass), and cross-referenced the divergence from `domains/SIDE_EFFECTS.md`. - **`branches/orgs/projects/secrets` SIDE_EFFECTS `-o toml`/`-o yaml` claims**, **`functions deploy`'s `NPM_AUTH_TOKEN` env table entry**, and **`update-root-key.handler.ts`'s color comment** — all already fixed by CLI-1975 (supabase#6002), CLI-1985 (supabase#6005), and CLI-1990 (supabase#5978) respectively, which merged after the audit ran. Verified current state matches; no changes needed. - **`start/SIDE_EFFECTS.md`'s `--ignore-health-check` ruling** — already fully handled by CLI-1987 (supabase#6007, merged), whose own description explicitly says CLI-1967 should not re-document it. Left untouched. ## Left as noted, not fixed (out of scope for a docs-only pass) - The `network-restrictions get`/`update` TS-only `-o` support is a real, pre-existing behavioral divergence from Go (Go has no such behavior at all for these two commands) — documented accurately here, but whether it should be *removed* to enforce strict parity is a ruling this PR doesn't make. - `docs/go-cli-porting-status.md`'s "Functions" section (next/-shell table) has a larger, pre-existing inaccuracy discovered while fixing the adjacent legacy-shell notes: it claims there's "still no dedicated `functions` CLI surface" in `next/`, but `next/commands/functions/` already exists (list/delete/deploy/download/new/dev, registered in `next/cli/root.ts`). Added command-path links and flagged the section as needing its own flag-by-flag parity audit rather than silently reclassifying rows without one. Fixes CLI-1967
Verified every bullet against the actual v2.111.0..v2.112.0 tree diff (the range came from a rebased develop rollup, so commit subjects alone were misleading) and applied the Codex review feedback: - Drop #6072 and #6080: packages/next-only, not in the stable shell - Drop #6003 and #6057: the stable CLI does not exercise the stack binary cache; #6057's "rollup" was the develop->main rollup PR, not the Rollup bundler - Add breaking-change section for NPM_AUTH_TOKEN no longer being forwarded by functions deploy (#6005, ships in this tag) - Note the one-time stop/start needed for already-stuck stacks (#6093) - Scope #5956 to functions download path traversal - Point db pull --experimental users at --declarative (#6028) - Fix#6065 and #6066 descriptions to match the shipped changes - Recount the internal tail (33 uncited commits in the compare range) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018h8krKpNet85649nqtj95b
…tudio E2E `Start supabase` flake) (#49198) <!-- ccr-slack-attribution --> _Requested by **Ivan Vasilov** · [Slack thread](https://supabase.slack.com/archives/C063LNYJJKS/p1787058646458219?thread_ts=1787058646.458219&cid=C063LNYJJKS)_ **Before:** the root `package.json` pins the Supabase CLI at `supabase: ^2.76.10`, and `pnpm-lock.yaml` resolves it to `2.76.14`. **After:** it pins `supabase: ^2.114.0`. This bumps the Supabase CLI that `pnpm run e2e:setup:cli` and `pnpm run setup:cli` shell out to, so local dev and the E2E workflows boot the local stack with a CLI from this month instead of one from ~38 minor releases ago. **How:** a one-line version change to the `supabase` devDependency in the root `package.json`. Nothing else in the repo changes — no workflow, config, or test changes. ###⚠️ This PR is incomplete: `pnpm-lock.yaml` still needs regenerating `pnpm-lock.yaml` is **not** updated in this PR, so `pnpm install --frozen-lockfile` will fail until someone runs: ```bash pnpm install --lockfile-only ``` and pushes the result to this branch. The lockfile could not be regenerated in the environment this PR was authored in: pnpm re-resolves `apps/studio`'s `"@std/path": "npm:@jsr/std__path@^1.0.8"` on every install, and `npm.jsr.io` is not reachable from there (`ERR_PNPM_FETCH_403`). Treat this PR as needing one extra commit before it can go green. ### Why `^2.114.0` and not `^2.115.0` `2.115.0` is the current `latest` on npm, but it was published only hours ago, and `pnpm-workspace.yaml` sets `minimumReleaseAge: 4320` (3 days) with `supabase` not in `minimumReleaseAgeExclude`. Pinning `2.115.0` today would fail the repo's own supply-chain check. `2.114.0` (2026-08-12) is the newest release that satisfies that policy. ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Dependency bump. **Speculative** — this is an experiment, not a confirmed fix. ## What is the current behavior? The `Selfhosted Studio E2E Tests` workflow has been failing on `master` at the `Start supabase` step. Recent runs: - https://github.com/supabase/supabase/actions/runs/32092940311 - https://github.com/supabase/supabase/actions/runs/32131961447 In the Slack thread, Ivan Vasilov suggested trying a newer CLI and Alaister Young endorsed giving it a go. ## What is the new behavior? The workflow runs `supabase start` with CLI 2.114.0 instead of 2.76.14. The question this PR is trying to answer is simply **"does a newer CLI help this flake?"** It is not a diagnosis and not a claimed fix. If CI still fails at `Start supabase` on this branch, the bump can be kept or dropped on its own merits and the investigation continues elsewhere. ## Additional context **Verification status:** none locally. The bump was not exercised locally — this repo checkout has no `node_modules` (see the lockfile note above), so `pnpm typecheck`, `pnpm lint`, and `pnpm test:studio` were not run, and neither was `supabase start`. CI on this PR is the only signal. **Call-site compatibility check.** CLI 2.99/2.100 moved to a new TypeScript shell with a stricter argument parser: command-specific flags must now come *after* the subcommand. Both call sites in the root `package.json` already use that order, so no script changes are needed: ``` supabase stop --all --no-backup --workdir ./e2e/studio supabase start --exclude studio,mailpit --workdir ./e2e/studio ``` **Changelog entries between 2.76.14 and 2.114.0 that touch `supabase start` or local config.** Listed so reviewers know what changed in the range — **not** as a claim about what is failing in CI: - **2.112.0** — `supabase start` no longer hangs when analytics migrations fail; the analytics container exits and retries instead of booting against an unmigrated database ([#6093](supabase/cli#6093)). - **2.112.0** — `supabase start` reuses existing volumes instead of failing when they already exist ([#6037](supabase/cli#6037)); Kong reloads after `supabase db reset` ([#6017](supabase/cli#6017)); custom auth email templates survive `db reset` ([#6065](supabase/cli#6065)); `supabase start` works on SELinux-enforcing hosts ([#6000](supabase/cli#6000)). - **2.106.0 — behavior change worth watching.** `[api].auto_expose_new_tables` now resolves to `false` when unset, and local start/reset revokes default Data API privileges for newly created `public` tables, sequences, and functions ([#5524](supabase/cli#5524)). Neither `supabase/config.toml` nor `e2e/studio/supabase/config.toml` sets this key, so this default applies. If E2E specs create `public` objects and then read them through the Data API, they may need explicit `GRANT`s (the deprecated escape hatch is `auto_expose_new_tables = true`). - **2.106.0** — when the CLI detects a coding-agent environment, or `--agent yes` is passed, commands default to JSON output ([#5532](supabase/cli#5532)). `e2e:setup:cli` already passes `--output json` to `supabase status` explicitly, so this should be a no-op here. - **2.100.0** — stricter flag ordering, covered above. - **2.112.0** — `functions deploy` no longer forwards `NPM_AUTH_TOKEN` into Docker bundling ([#6005](supabase/cli#6005)). Not used by these workflows. - **2.107.0** — pg-delta is the default schema diff engine for `db diff` / `db pull` on new projects ([#5511](supabase/cli#5511)). - Many bundled Docker image bumps across the range (`supabase/postgres` 17.6.1.087 → later patches, `postgres-meta`, `vector` 0.28.1 → 0.53.0, Studio image), plus `fix(analytics): wait for logflare before starting vector` (2.84.3) and `fix: use correct docker.sock binding with vector` (2.84.7). Full comparison: supabase/cli@v2.76.14...v2.114.0 --- _Generated by [Claude Code](https://claude.ai/code/session_0143DrDMGnSSwuHebTPJv7ZY)_ --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
Two
functions deploydivergences from the pinned Go CLI (apps/cli-go), resolved per the CLI-1985 ruling (Colum, 2026-07-30: take each point's documented recommended option).Fixes CLI-1985
⚖ Parity ruling applied
Point 1 —
NPM_AUTH_TOKENis no longer forwarded into the Docker bundler (strict parity; breaking for private-registry users)Decision: remove the forwarding. The eszip bundler container now receives only
NPM_CONFIG_REGISTRYfrom the host, exactly matching Go (apps/cli-go/internal/functions/deploy/bundle.go:68-70).Evidence:
NPM_AUTH_TOKENat any point in its history — onlyNPM_CONFIG_REGISTRY(added in8e17f033).functions deployfails to read.npmrcenvironment variables for private npm registry auth (workspacedeno.json) #4927) was closed unmerged on 2026-06-22 ("The command is now ported in TypeScript so I'm closing this PR").User-visible change (flagging prominently): users whose
.npmrcexpands${NPM_AUTH_TOKEN}for private npm registries will find--use-docker/--legacy-bundledeploys failing registry auth again (the pre-#5645 and Go CLI behavior; re-opens the CI/CD-host case of #4927). Workarounds: inline the token in.npmrc, or deploy via the default--use-apipath. Per the strict-parity contract (stderr bytes included), no TS-only warning was added when the variable is set — a DX reviewer requested one and it was rejected on parity grounds; the breaking impact is documented here and in the commit message instead.Shared-code caveat (per the ruling):
dockerNpmEnvlives inapps/cli/src/shared/functions/deploy.tsand serves both shells —next/(functions deploy) andlegacy/. The removal therefore applies to the next/ shell too. The strict-parity contract only binds the legacy shell, but keeping one code path is the simplest correct design per repo policy, so next/ loses the forwarding as well — stated here explicitly.functions serveis unaffected (it has its own env handling, matching Go's serve which loadssupabase/functions/.env).Point 2 — API-deploy upload paths re-anchored at the workdir (align to the pinned oracle; behaviour change)
Directive: confirm the intended reference point first, then align or record.
Evidence found:
pkg/function/deploy.go(pre- and post-monorepo move) showstoRelPathanchored atos.Getwd()since29021998("convert all paths to relative for deploy", fix: convert all paths to relative for deploy #3403), unchanged since. The Go CLI chdirs to the workdir (internal/utils/misc.go:238), soos.Getwd()≡ the workdir.failed to read file: open ../common/index.ts) — not a port of newer upstream Go behavior. There is no newer upstream Go reference to record against.Decision (per the ruling's matrix — upstream never did this → align): uploaded multipart file names and the server-recorded
entrypoint_path/import_map_path/static_patternsare now anchored at the workdir with Go's exacttoRelPathsemantics (relative toos.Getwd(), forward slashes,../-relative when the file lies outside the workdir).Scope note:#5755's import-walk containment boundary (which files may be uploaded at all) is intentionally kept at the nearest git root. The boundary is a TS-only safeguard with no Go equivalent — Go's walker uploads any reachable import unbounded (and then hard-fails opening
..paths throughafero.NewIOFS, which is exactly bug #3467). Reverting the boundary would re-break #3467 and is outside CLI-1985's anchoring scope.User-visible change: in monorepos where the git root is an ancestor of the workdir, redeploys now record
supabase/functions/<slug>/index.ts(matching what the Go CLI records and the dashboard shows for Go deploys) instead ofapps/myapp/supabase/functions/<slug>/index.ts. Imports outside the workdir but inside the git root still deploy, uploading with Go-style../-relative names — the same name shape Go'stoRelPathemits, so nothing new is required of the server. Non-monorepo projects (git root == workdir, the common case) are byte-for-byte unchanged.What changed
apps/cli/src/shared/functions/deploy.ts—dockerNpmEnvNamestrimmed toNPM_CONFIG_REGISTRY;deployViaApinow threads the workdir as the path anchor throughuploadFunctionSource/writeSourceDeployForm/createSourceMetadatawhile the git-rootsourceRootremains the containment boundary; ENOENT warn display paths follow the workdir anchor (matching Go's workdir-relative walker paths). Docker bind construction is untouched.apps/cli/src/legacy/commands/functions/deploy/deploy.integration.test.ts— new regression test: workdir≠git-root monorepo deploy asserts workdir-anchored metadata,../-relative upload names, and the Go-parityUploading assetstderr line.apps/cli/src/next/commands/functions/deploy/deploy.integration.test.ts— the two git-root upload tests updated to the workdir anchoring; the npm env test now assertsNPM_CONFIG_REGISTRYis forwarded andNPM_AUTH_TOKENis not.apps/cli/src/legacy/commands/functions/deploy/SIDE_EFFECTS.md— env table states onlyNPM_CONFIG_REGISTRYis forwarded; new note documents the workdir anchoring and the TS-only git-root boundary.All four changed/added tests fail against the previous implementation and pass with this change.