Skip to content

refactor(deploy): extract deploy target resolution and auto-update rules#1254

Open
gu-stav wants to merge 1 commit into
mainfrom
refactor/deploy-target-resolution
Open

refactor(deploy): extract deploy target resolution and auto-update rules#1254
gu-stav wants to merge 1 commit into
mainfrom
refactor/deploy-target-resolution

Conversation

@gu-stav

@gu-stav gu-stav commented Jun 11, 2026

Copy link
Copy Markdown
Member

Description

Deploy target rules (appId-over-appHost precedence, --url over studioHost, external URL validation) and auto-update deprecation detection lived inside interactive code that prompts, creates applications, and exits the process. The rules couldn't be reused read-only, and were only testable through full command runs.

This pulls them into two rule-owners with side-effect-free interfaces:

  • resolveDeployTarget.ts — returns a verdict (found / would-create / needs-input / invalid / blocked). findUserApplicationForStudio/ForApp become adapters that turn verdicts into prompts, creation, and exits. Transport errors throw; they're not verdicts.
  • resolveAutoUpdates — returns {enabled, issue}. shouldAutoUpdate stays as the printing adapter, so existing callers don't move.

No behavior change intended. This is groundwork for sanity deploy --dry-run (follow-up PR), which consumes the same verdicts without side effects — the rules get one home so the two paths can't drift.

One wording artifact kept on purpose: an unknown appId still reports Error finding user application: Cannot find app with app ID ….

What to review

  • The verdict mapping in both adapters against the old control flow — prompting, hostname creation, and error exits should be indistinguishable from before.
  • The verdict unions have no default branches at consumers, so adding a verdict later fails compilation everywhere it must be handled.

Testing

Existing command-level deploy tests pass unchanged — they pin the prompts, creation flows, error messages, and exit codes this refactor must preserve. New unit tests cover resolveAutoUpdates (precedence, conflict, deprecations).


Note

Medium Risk
Touches studio/app deploy resolution paths and CLI exit/warning behavior; refactor-only with existing deploy tests as the safety net, but mistakes in verdict mapping could change who gets prompted or which host is used.

Overview
Extracts deploy target and auto-update decision logic into side-effect-free helpers so the same rules can power interactive deploy and a future --dry-run, without duplicating precedence or validation.

Deploy targets: New resolveDeployTarget.ts exposes resolveStudioDeployTarget and resolveAppDeployTarget, returning typed verdicts (found, would-create, needs-input, invalid, blocked). Studio rules (--url over studioHost, appId over host, external URL checks) move out of deployStudio’s local resolveAppHost and out of the old findUserApplication* flows. findUserApplicationForStudio and findUserApplicationForApp now call those resolvers and only handle spinners, prompts, creation, and exits.

Auto-updates: New resolveAutoUpdates returns {enabled, issue} for flag/config precedence, deprecations, and conflicts; shouldAutoUpdate becomes a thin layer that prints warnings/errors from issue. Unit tests cover resolveAutoUpdates directly.

Intended behavior for deploy prompts, creation, and error text is unchanged.

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

Deploy target precedence (appId over appHost, --url over studioHost) and
auto-update deprecation detection each lived inside interactive code that
prompts, creates applications, and exits — impossible to reuse read-only.
Extracting them into verdict-returning resolvers gives the rules one home
so consumers can't drift, and makes them testable as data-in/data-out.
@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Stats — @sanity/cli

Compared against main (fbcbace2)

@sanity/cli

Metric Value vs main (fbcbace)
Internal (raw) 2.1 KB -
Internal (gzip) 799 B -
Bundled (raw) 11.13 MB -
Bundled (gzip) 2.10 MB -
Import time 858ms -13ms, -1.5%

bin:sanity

Metric Value vs main (fbcbace)
Internal (raw) 1023 B -
Internal (gzip) 486 B -
Bundled (raw) 9.87 MB -
Bundled (gzip) 1.77 MB -
Import time 1.95s -5ms, -0.3%

🗺️ 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 (fbcbace2)

Metric Value vs main (fbcbace)
Internal (raw) 96.3 KB -
Internal (gzip) 22.7 KB -
Bundled (raw) 21.70 MB -
Bundled (gzip) 3.45 MB -
Import time 764ms -6ms, -0.8%

🗺️ 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 — create-sanity

Compared against main (fbcbace2)

Metric Value vs main (fbcbace)
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.

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit faad45d. Configure here.

reason: 'app-not-found',
type: 'invalid',
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

appId beaten by host validation

Medium Severity

For external studio deploys, resolveStudioDeployTarget normalizes and validates studioHost before it looks up deployment.appId. A stale or invalid studioHost can trigger invalid-host even when appId would resolve an existing application, which breaks the intended appId-over-host precedence.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit faad45d. Configure here.

@github-actions

Copy link
Copy Markdown
Contributor

Coverage Delta

File Statements
packages/@sanity/cli/src/actions/build/shouldAutoUpdate.ts 100.0% (±0%)
packages/@sanity/cli/src/actions/deploy/deployStudio.ts 94.6% (+ 2.1%)
packages/@sanity/cli/src/actions/deploy/findUserApplicationForApp.ts 83.3% (- 9.5%)
packages/@sanity/cli/src/actions/deploy/findUserApplicationForStudio.ts 87.7% (- 9.3%)
packages/@sanity/cli/src/actions/deploy/resolveDeployTarget.ts 94.6% (new)

Comparing 5 changed files against main @ fbcbace2e07a97da5415d6e557c102f8128f0805

Overall Coverage

Metric Coverage
Statements 80.3% (+ 0.5%)
Branches 71.9% (+ 0.3%)
Functions 79.1% (+ 0.4%)
Lines 80.8% (+ 0.5%)

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.

1 participant