Skip to content

fix(cli): honor --yes/SUPABASE_YES and Go prompt semantics consistently across confirmation prompts - #5947

Merged
Coly010 merged 3 commits into
developfrom
columferry/cli-1974-honor-yessupabase_yes-and-go-prompt-semantics-consistently
Jul 27, 2026
Merged

fix(cli): honor --yes/SUPABASE_YES and Go prompt semantics consistently across confirmation prompts#5947
Coly010 merged 3 commits into
developfrom
columferry/cli-1974-honor-yessupabase_yes-and-go-prompt-semantics-consistently

Conversation

@Coly010

@Coly010 Coly010 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Routes every legacy-parity confirmation through the single Go-faithful helper legacyPromptYesNo (Go's PromptYesNo, apps/cli-go/internal/utils/console.go:38-107) and deletes the per-command shortcuts, so all three Go prompt properties hold everywhere:

  1. --yes OR SUPABASE_YES auto-confirms (viper AutomaticEnv; project .env consulted exactly where Go's loadNestedEnv runs before the prompt).
  2. Auto-confirm echoes <label> [y/N] y to stderr (console.go:70-72) instead of being silent.
  3. Non-TTY runs read piped stdin: the label is printed, one line is scanned (100 ms), a parsed y/n wins, and only empty/unparseable input falls back to the default (console.go:38-61,96-102).

Fixes CLI-1974 — https://linear.app/supabase/issue/CLI-1974/honor-yessupabase-yes-and-go-prompt-semantics-consistently-across

⚖ Flagged decision: item 3 (non-TTY piped stdin) is IMPLEMENTED

The issue left it open whether to match Go's non-TTY piped-stdin reads; this PR takes the recommended option and implements them. Concretely, commands that previously hardcoded a non-TTY default now consume one stdin line per confirmation and honor it:

  • echo y | supabase projects delete <ref> now deletes (previously silently cancelled — verified against develop with a from-source differential smoke test).
  • echo n | supabase secrets unset now declines (previously proceeded unconditionally).
  • echo n | supabase branches create (git-branch auto-name) now cancels; empty stdin keeps Go's Yes default.
  • Scripts that pipe unrelated data into these commands should redirect < /dev/null or pass --yes. Veto here if this should be documented-divergence instead — the infrastructure (Stdin.readLine) was already in place from db push/reset, so no architectural cost either way.

Per-site changes

Site Go ref (default) Gaps fixed
logout logout.go:16 (N) --yes short-circuited before the stderr echo
projects delete delete.go:22 (N) flag-only yes (no SUPABASE_YES); non-TTY hardcoded cancel, no piped read, no label echo; title now aqua like Go
branches create (auto-name) create.go:21 (Y) --yes/env ignored entirely (blocked a TTY); no piped read; no echo; title now aqua
secrets unset unset.go:34 (Y) non-TTY hardcoded confirm, no piped read (env-aware yes + echo already existed)
bootstrap overwrite bootstrap.go:48 (Y) no echo under --yes; non-TTY went through clack
functions deploy --prune deploy.go:190 (N) legacy passed flag-only yes; no echo; no piped read; label now byte-matches confirmPruneAll ( + bold + trailing blank line, both shells)
init -i IDE prompts init.go:63,68 (Y/N) prompted anyway under --yes; --yes now also lifts the stdout-TTY gate (Go only requires stdin TTY)
functions new IDE prompts new.go:99init.go:62 flag-only yes; non-TTY hardcoded default, no piped read
db schema declarative generate/sync/smart-target db_schema_declarative.go:269,321,381 + declarative.go:234 (N/N/Y/N) flag-only yes (Go reads viper YES after loadNestedEnv → now legacyResolveYesWithProjectEnv); no echo under yes. The sync apply-decision (:452-460) and post-fail reset gate (:478) were already faithful 1:1 ports of Go's own short-circuits and are unchanged

Already-correct sites (unchanged): config push, db pull, db push ×3, db reset, gen signing-key, storage rm, seed buckets ×3 (via the helper), migration fetch/down/repair (via legacyMigrationConfirm).

Mechanics

  • legacyPromptYesNo + legacyParseYesNo moved from src/legacy/shared/ to src/shared/legacy/ (same home as legacyResolveYes in global-flags.ts) because two shared files (shared/functions/deploy.ts, shared/init/project-init.ts) now confirm through it. Semantics unchanged; importers updated path-only.
  • ProjectInitOptions gains yes (legacy init passes legacyResolveYes; next init passes false — next exposes no --yes on init, so next behavior is unchanged; bootstrap passes its resolved yes with interactive: false).
  • stdinLayer added to the layer composition of every command whose confirmation can now read stdin; verified in the real composition by from-source smoke tests (piped y/n/--yes/SUPABASE_YES differentials vs develop).
  • migration.prompt.ts now reuses the shared legacyParseYesNo and both helpers cross-reference why they intentionally diverge (see below).

Judgement calls deliberately left open (reviewer input welcome)

  • Machine mode (--output-format json|stream-json) without --yes: legacyPromptYesNo keeps its pre-existing contract — never prompt, silently take the call site's Go default. Routing more sites through it changes a few narrow machine-mode cells: secrets unset json+TTY now proceeds (default Y) instead of cancelling; bootstrap overwrite json now proceeds instead of failing with a prompt error; declarative generate --local json with existing files now skips (exit 0) instead of erroring. Go has no json mode; its script-mode analog (non-TTY) is exactly this default-through behavior, and this matches the helper's 7 pre-existing users (config push, db pull/push/reset, storage rm, signing-key, seed buckets). logout deliberately keeps its documented fail-loud json contract. A stricter "fail loudly in machine mode when the default is destructive" rule was proposed in internal review — it would change already-shipped behavior of the pre-existing helper users, so it is left as a follow-up decision. New regression test locks the secrets unset json contract either way.
  • legacyMigrationConfirm not consolidated: the migration family's helper intentionally prompts regardless of output format and uses a raw TTY read (both arguably more Go-faithful); merging the two requires deciding the machine-mode question above first. Both files now carry cross-referencing comments so the divergence is explicit.
  • shared/functions/deploy.tslegacy/shared/legacy-colors.ts import (for the bold prune slugs) deepens a pre-existing shared→legacy edge in that file (spawnContainerCli, legacy-docker-registry already do this); hoisting the color primitives is left as a cleanup follow-up.
  • Next-shell visible change: next functions deploy --prune inherits Go's exact prompt bytes ( bullets, bold slugs, stderr echo under --yes, piped-stdin reads) via the shared file — deliberate, covered by new next-shell tests.

Expected overlap with #5946

#5946 (CLI-1973, open) replaces "context canceled" literals with CONTEXT_CANCELED_MESSAGE and suppresses the --debug hint on declined prompts, touching many of the same handlers (logout, projects delete, secrets unset, branches create, bootstrap, db push/reset, migration *, signing-key, shared/functions/deploy.ts, shared/output/*). This branch is based on develop without it and avoids rewriting those exact lines; expect small, mechanical merge overlap in import blocks and around the cancellation branches whichever lands second.

…firmation sites (CLI-1974)

Route every legacy-parity confirmation through the Go-faithful
legacyPromptYesNo helper (moved to shared/legacy/ so shared files can use
it) instead of per-command shortcuts, matching Go's PromptYesNo
(apps/cli-go/internal/utils/console.go:38-107):

- viper YES (--yes flag OR SUPABASE_YES env, project .env where Go loads
  it) auto-confirms everywhere, echoing '<label> [y/N] y' to stderr
- non-TTY runs print the label and scan one piped stdin line (100ms),
  honoring y/n answers instead of hardcoding the default
- declined/default paths unchanged

Fixed sites: logout (missing echo), projects delete (flag-only yes, no
piped read), branches create (yes ignored entirely), secrets unset
(hardcoded non-TTY default), bootstrap overwrite (missing echo),
functions deploy --prune (flag-only yes, missing echo, Go label bytes),
init -i IDE prompts (prompted despite --yes), functions new IDE prompts
(flag-only yes, no piped read), db schema declarative generate/sync/
smart-target (flag-only yes, missing echo).
@Coly010

Coly010 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: c5a430fcd4

ℹ️ 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".

@Coly010 Coly010 self-assigned this Jul 27, 2026
@Coly010
Coly010 marked this pull request as ready for review July 27, 2026 11:59
@Coly010
Coly010 requested a review from a team as a code owner July 27, 2026 11:59

@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: c5a430fcd4

ℹ️ 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".

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Supabase CLI preview

npx --yes https://pkg.pr.new/supabase/cli/supabase@4f241f0271c0386993e011cfdf5c793fa3589d8b

Preview package for commit 4f241f0.

…e to match godotenv.Load (review: #3656892831)

Go's loadNestedEnv uses godotenv.Load, which never overwrites a key already
present in the shell env — even one set to false, empty, or an unparsable
value — so shell presence must suppress the project .env value entirely
instead of OR-ing the two parsed booleans. Applies to both SUPABASE_YES and
SUPABASE_EXPERIMENTAL resolvers; unit tests cover the full godotenv/viper
truth table.
@Coly010

Coly010 commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: 51089491ae

ℹ️ 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".

@Coly010

Coly010 commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: 51089491ae

ℹ️ 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".

@Coly010
Coly010 added this pull request to the merge queue Jul 27, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Jul 27, 2026
…4-honor-yessupabase_yes-and-go-prompt-semantics-consistently

# Conflicts:
#	apps/cli/src/legacy/commands/bootstrap/bootstrap.handler.ts
#	apps/cli/src/legacy/commands/branches/create/create.handler.ts
#	apps/cli/src/legacy/commands/logout/logout.handler.ts
#	apps/cli/src/legacy/commands/projects/delete/delete.handler.ts
#	apps/cli/src/legacy/commands/secrets/unset/unset.handler.ts
#	apps/cli/src/shared/functions/deploy.ts
@Coly010
Coly010 enabled auto-merge July 27, 2026 20:21
@Coly010
Coly010 added this pull request to the merge queue Jul 27, 2026
Merged via the queue into develop with commit c4b4587 Jul 27, 2026
13 checks passed
@Coly010
Coly010 deleted the columferry/cli-1974-honor-yessupabase_yes-and-go-prompt-semantics-consistently branch July 27, 2026 20:35
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.

2 participants