Skip to content

feat(cli): add unattended mode support to undeploy command#1504

Merged
jonahsnider merged 4 commits into
mainfrom
aigro-5168/unattended-undeploy
Jul 17, 2026
Merged

feat(cli): add unattended mode support to undeploy command#1504
jonahsnider merged 4 commits into
mainfrom
aigro-5168/unattended-undeploy

Conversation

@jonahsnider

@jonahsnider jonahsnider commented Jul 13, 2026

Copy link
Copy Markdown
Member

Description

Adds unattended-mode support to the undeploy command.

What to review

Review the flags, prompt handling, and automated coverage.

Testing


Note

Medium Risk
Changes destructive undeploy behavior for CI/scripts that relied on --json or non-TTY auto-consent; callers must add --yes, but interactive flows and explicit --yes paths are unchanged.

Overview
Breaking behavior change: sanity undeploy no longer treats non-interactive or --json runs as implicit consent. Unattended runs without --yes fail with a usage error (Pass --yes to continue, exit 2) instead of deleting; scripts and CI must pass --yes explicitly.

The command stops auto-setting yes: true when isUnattended() is true and passes isUnattended into runUndeploy, which blocks deletion before any prompt when unattended and yes is false.

Exit codes and messaging are aligned with @sanity/cli-core conventions: user decline and Ctrl+C on the prompt use USER_ABORT (3) with Undeploy cancelled; missing confirmation in unattended mode uses USAGE_ERROR (2). With --json, the same confirmation requirement surfaces as { undeployed: false, error: { message } } on stdout.

Tests cover unattended --yes requirement, rejected prompts, and the updated --json without --yes case (no delete, machine-readable error).

Reviewed by Cursor Bugbot for commit b7c8918. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Stats — @sanity/cli

Compared against main (abece333)

@sanity/cli

Metric Value vs main (abece33)
Internal (raw) 2.2 KB -
Internal (gzip) 838 B -
Bundled (raw) 11.16 MB -
Bundled (gzip) 2.10 MB -
Import time 859ms -11ms, -1.3%

bin:sanity

Metric Value vs main (abece33)
Internal (raw) 782 B -
Internal (gzip) 423 B -
Bundled (raw) 9.87 MB -
Bundled (gzip) 1.78 MB -
Import time 2.22s -70ms, -3.1%

🗺️ View treemap · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

📦 Bundle Stats — @sanity/cli-core

Compared against main (abece333)

Metric Value vs main (abece33)
Internal (raw) 108.1 KB -
Internal (gzip) 27.0 KB -
Bundled (raw) 21.72 MB -
Bundled (gzip) 3.46 MB -
Import time 773ms -19ms, -2.4%

🗺️ View treemap · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

📦 Bundle Stats — @sanity/cli-build

Compared against main (abece333)

@sanity/cli-build/_internal/build

Metric Value vs main (abece33)
Internal (raw) 110.9 KB -
Internal (gzip) 27.9 KB -
Bundled (raw) 17.94 MB -
Bundled (gzip) 3.60 MB -
Import time 1.37s +10ms, +0.7%

@sanity/cli-build/_internal/env

Metric Value vs main (abece33)
Internal (raw) 1.8 KB -
Internal (gzip) 644 B -
Bundled (raw) 1.31 MB -
Bundled (gzip) 332.9 KB -
Import time 126ms -1ms, -0.4%

@sanity/cli-build/_internal/extract

Metric Value vs main (abece33)
Internal (raw) 8.6 KB -
Internal (gzip) 2.7 KB -
Bundled (raw) 151.2 KB -
Bundled (gzip) 38.3 KB -
Import time 247ms +4ms, +1.5%

🗺️ ./_internal/env · ./_internal/extract · @sanity/cli-build:./_internal/build treemap too large to embed · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

📦 Bundle Stats — create-sanity

Compared against main (abece333)

Metric Value vs main (abece33)
Internal (raw) 908 B -
Internal (gzip) 483 B -
Bundled (raw) 931 B -
Bundled (gzip) 491 B -
Import time ❌ ChildProcess denied: node -
Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Coverage Delta

File Statements
packages/@sanity/cli/src/actions/undeploy/runUndeploy.ts 98.7% (+ 0.0%)
packages/@sanity/cli/src/commands/undeploy.ts 100.0% (±0%)

Comparing 2 changed files against main @ 29fb5779a0115de922ebbb4f8c2529fa90ccfb59

Overall Coverage

Metric Coverage
Statements 76.7% (±0%)
Branches 67.7% (+ 0.0%)
Functions 72.3% (±0%)
Lines 77.2% (+ 0.0%)

@jonahsnider
jonahsnider marked this pull request as ready for review July 15, 2026 16:49
@jonahsnider
jonahsnider requested a review from a team as a code owner July 15, 2026 16:49
const {target} = resolution
if (!flags.yes && options.isUnattended) {
throw new CLIError('Undeploy requires confirmation. Pass --yes to continue.', {
exit: exitCodes.USAGE_ERROR,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, i left a comment on one of the related PRs in this unattended change set about possibly standardizing bare integer exit code use on the exitCodes enum, looks like that's doable given this use case 🚀

def a fast follow / nit

@jonahsnider
jonahsnider merged commit e55f659 into main Jul 17, 2026
57 of 58 checks passed
@jonahsnider
jonahsnider deleted the aigro-5168/unattended-undeploy branch July 17, 2026 15:45
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