Skip to content

fix(init): respect --project and --dataset flags for app templates#1015

Merged
binoy14 merged 1 commit intomainfrom
pr-999
Apr 28, 2026
Merged

fix(init): respect --project and --dataset flags for app templates#1015
binoy14 merged 1 commit intomainfrom
pr-999

Conversation

@binoy14
Copy link
Copy Markdown
Contributor

@binoy14 binoy14 commented Apr 24, 2026

Description

Fixes SDK-1314

Previously, running sanity init --template app-quickstart --project <id> --dataset <name> still prompted the user to select an organization and showed a
redundant "Configure a project for this app?" prompt. Unattended mode (--yes) also required --organization even when --project already supplied enough
context to derive it.

The fix:

  • promptForAppTemplateSetup now takes a flag-driven path whenever --project or --project-name is provided — in both interactive and unattended modes. This
    matches the behavior of the non-app template flow and stops the spurious "Configure a project for this app?" prompt.
  • getProjectDetails no longer prompts for the organization when --project/--project-name is provided for app templates — the org is derived from the
    resolved project instead.
  • getOrCreateProject and promptForProjectCreation now return organizationId so callers can propagate it.
  • checkFlagsInUnattendedMode relaxes the --organization requirement for app templates when --project/--project-name provides enough context (still
    required for --project-name since creation needs it).
  • Tightens getOrCreateProject: an explicit --project=<not-in-list> now errors in unattended mode too, instead of silently proceeding with a bogus projectId.
    The separate API-failure catch block still handles transient failures.

What to review

  • packages/@sanity/cli/src/actions/init/project/getOrCreateProject.ts — the removed !unattended guard on the project-not-found branch, plus the
    organizationId now threaded through all return sites.
  • packages/@sanity/cli/src/actions/init/project/getProjectDetails.ts — the hasProjectFlag gate that skips promptUserForOrganization and derives the org from
    the resolved project.
  • packages/@sanity/cli/src/actions/init/project/promptForAppTemplateSetup.ts — the flag-driven early path now triggers in interactive mode too.
  • packages/@sanity/cli/src/actions/init/initAction.ts — the relaxed checkFlagsInUnattendedMode for app templates.
  • Confirm the UX: we silently use the project's org rather than asking the user to confirm it when --project is set.

Testing

Four new tests added in init.get-project-details.test.ts:

  1. Interactive + --project + --dataset — neither the org selection nor the "Configure a project" prompt fires; existing dataset is reused.
  2. SDK-1314 reproducer: unattended + --project + --dataset without --organization — succeeds with no prompts, org derived from the project.
  3. Unattended + --project=<not-in-list> — errors with "not found" instead of silently proceeding.
  4. Unattended without --project nor --organization — still errors, with an updated message mentioning --project / --project-name as alternatives.

pnpm check:types, pnpm check:lint, and the full init test suite (106 tests) all pass. Manual testing against a real project would be appreciated before merge.


Note

Medium Risk
Changes init’s app-template flag handling and unattended validation, which can affect CLI UX and CI/bootstrap flows; mis-threading organizationId or the new project fast path could cause init failures for some flag combinations.

Overview
Fixes sanity init for app templates so --project/--project-name and --dataset drive a no-prompt setup path (interactive and unattended), skipping organization selection and the redundant “Configure a project for this app?” prompt.

Threads organizationId through project selection/creation (getOrCreateProject, promptForProjectCreation, promptForAppTemplateSetup) so app-template init can derive the org from the resolved project, and tightens behavior to error when an explicit --project is not found (instead of silently continuing).

Relaxes unattended app-template requirements to allow --project without --organization (while still requiring --organization for --project-name), and updates/extends tests accordingly while removing now-unneeded /organizations mocks.

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

@binoy14
Copy link
Copy Markdown
Contributor Author

binoy14 commented Apr 24, 2026

This change is part of the following stack:

Change managed by git-spice.

@claude
Copy link
Copy Markdown

claude Bot commented Apr 24, 2026

Claude finished @binoy14's task in 3m 43s —— View job


Review

  • Gather context
  • Read changed files
  • Review changeset
  • Identify issues
  • Post findings

1. Unattended --project=<not-in-list> now always throws — transient failures may surface differently

getOrCreateProject.ts:72–78 — the removed !unattended guard means a project ID that isn't in the list now throws in both modes. The catch block (line 51–58) still returns 'Unknown project' when listProjects() itself throws (transient API failure), so real network errors are still graceful. However, the --project-name flow calls this after createProjectFromName and relies on the new project appearing immediately in listProjects. If there's any eventual-consistency lag, users would see an error instead of the previous silent fallback. This is a deliberate trade-off stated in the PR, but worth a manual test for that path specifically.

2. checkFlagsInUnattendedMode reorder changes error message for --project-name without --organization on app templates

initAction.ts:285 — moving the --project-name requires --organization check to the top means that for app templates with --project-name but no --organization, the error message is now the generic one ('--project-name' requires '--organization <id> in unattended mode') instead of the app-template-specific message. The old code would also have hit the same check at the bottom, so behavior is identical, but the message priority changes. This is probably fine, but test 4 in the PR (unattended without --project nor --organization) only covers the case where neither flag is provided — there's no test for isAppTemplate=true + --project-name + no --organization hitting the new top check.

3. getOrCreateProject: organizations initialized to [] but never assigned in the else branch when projectId is falsy

Wait — re-reading: the else branch does assign organizations = allOrgs. The let organizations: ProjectOrganization[] declaration (line 37) is uninitialized, but TypeScript would catch any use-before-assign. No issue here.

4. Changeset

.changeset/fix-app-quickstart-flags.md — bump type (patch) and one-sentence summary are appropriate. No issues.


Nothing blocking. The core logic is correct, test coverage for the four new scenarios is good, and the organization mock removals across test files correctly track the new "skip org fetch when projectId is known" behavior.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 24, 2026

📦 Bundle Stats — @sanity/cli

Compared against main (cb1e19a5)

@sanity/cli

Metric Value vs main (cb1e19a)
Internal (raw) 2.1 KB -
Internal (gzip) 799 B -
Bundled (raw) 10.94 MB -
Bundled (gzip) 2.05 MB -
Import time 835ms -11ms, -1.3%

bin:sanity

Metric Value vs main (cb1e19a)
Internal (raw) 975 B -
Internal (gzip) 460 B -
Bundled (raw) 9.84 MB -
Bundled (gzip) 1.77 MB -
Import time 2.00s +4ms, +0.2%

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

Metric Value vs main (cb1e19a)
Internal (raw) 93.1 KB -
Internal (gzip) 21.9 KB -
Bundled (raw) 21.62 MB -
Bundled (gzip) 3.42 MB -
Import time 801ms +3ms, +0.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 — create-sanity

Compared against main (cb1e19a5)

Metric Value vs main (cb1e19a)
Internal (raw) 976 B -
Internal (gzip) 507 B -
Bundled (raw) 50.7 KB -
Bundled (gzip) 12.6 KB -
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
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 24, 2026

Coverage Delta

File Statements
packages/@sanity/cli/src/actions/init/initAction.ts 97.1% (+ 0.0%)
packages/@sanity/cli/src/actions/init/project/getOrCreateProject.ts 95.8% (+ 0.5%)
packages/@sanity/cli/src/actions/init/project/getProjectDetails.ts 90.0% (+ 0.5%)
packages/@sanity/cli/src/actions/init/project/promptForAppTemplateSetup.ts 95.7% (+ 0.4%)
packages/@sanity/cli/src/actions/init/project/promptForProjectCreation.ts 44.4% (±0%)

Comparing 5 changed files against main @ cb1e19a5755dc28e70e5415eb46df9598b8d32a2

Overall Coverage

Metric Coverage
Statements 84.1% (+ 0.0%)
Branches 74.1% (+ 0.1%)
Functions 84.0% (+ 0.0%)
Lines 84.5% (+ 0.0%)

@binoy14 binoy14 force-pushed the pr-999 branch 2 times, most recently from f83cfaa to 42079e3 Compare April 27, 2026 15:18
@binoy14 binoy14 marked this pull request as ready for review April 28, 2026 00:49
@binoy14 binoy14 requested a review from a team as a code owner April 28, 2026 00:49
@binoy14 binoy14 requested review from somerandomdude and removed request for a team April 28, 2026 00:49
Copy link
Copy Markdown
Member

@cngonzalez cngonzalez left a comment

Choose a reason for hiding this comment

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

one DX / consistency question, otherwise LGTM

return {
displayName: 'Unknown project',
isFirstProject: false,
organizationId: organization,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

are we ok with organizationId being possibly undefined here or do we want to check for project existence / derive it from the project API response as happens below?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is in the error scenario so the only solve would be to refetch but that could theoretically also fail. This makes it so that it just keep moving and it can manually fixed later in a rare case

@binoy14 binoy14 merged commit 737ab0b into main Apr 28, 2026
57 checks passed
@binoy14 binoy14 deleted the pr-999 branch April 28, 2026 16:20
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