Skip to content

Conversation

@valentinpalkovic
Copy link
Contributor

@valentinpalkovic valentinpalkovic commented Nov 24, 2025

Closes #32211

What I did

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This pull request has been released as version 0.0.0-pr-33141-sha-42b6c68a. Try it out in a new sandbox by running npx [email protected] sandbox or in an existing project with npx [email protected] upgrade.

More information
Published version 0.0.0-pr-33141-sha-42b6c68a
Triggered by @valentinpalkovic
Repository storybookjs/storybook
Branch valentin/fix-storybook-version-evaluation
Commit 42b6c68a
Datetime Tue Nov 25 08:27:56 UTC 2025 (1764059276)
Workflow run 19663057751

To request a new release of this pull request, mention the @storybookjs/core team.

core team members can create a new canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=33141

Summary by CodeRabbit

  • Bug Fixes

    • Improved package.json resolution when using custom operation directories to reduce lookup errors.
  • Refactor

    • Migration, diagnostic, and tooling flows now use an explicit version specifier and the installed Storybook version instead of an inferred/coerced version.
    • Simplified version handling across package managers and reduced reliance on legacy version APIs.

✏️ Tip: You can customize this high-level summary in your review settings.

@valentinpalkovic valentinpalkovic changed the title CLI: Update package manager proxies and CLI utils; refine main config automigration CLI: Fix 'beforeVersion' evaluation for Storybook package Nov 24, 2025
@valentinpalkovic valentinpalkovic self-assigned this Nov 24, 2025
@nx-cloud
Copy link

nx-cloud bot commented Nov 24, 2025

View your CI Pipeline Execution ↗ for commit 4dcfdc4

Command Status Duration Result
nx run-many -t build --parallel=3 ✅ Succeeded 44s View ↗

☁️ Nx Cloud last updated this comment at 2025-11-25 10:04:23 UTC

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 24, 2025

📝 Walkthrough

Walkthrough

Package manager proxies now resolve module package.json lookups from each package's operationDir instead of cwd. The JsPackageManager abstract method gains an optional cwd parameter. Storybook version handling was split into versionSpecifier and versionInstalled; legacy beforeVersion/getCoercedStorybookVersion usages were removed and doctor/automigrate flows updated accordingly.

Changes

Cohort / File(s) Summary
Package manager proxies
code/core/src/common/js-package-manager/BUNProxy.ts, code/core/src/common/js-package-manager/NPMProxy.ts, code/core/src/common/js-package-manager/Yarn1Proxy.ts, code/core/src/common/js-package-manager/Yarn2Proxy.ts, code/core/src/common/js-package-manager/PNPMProxy.ts
getModulePackageJSON now searches for package.json using this.primaryPackageJson.operationDir as the working directory instead of this.cwd (PnP logic preserved where applicable).
Package manager base API
code/core/src/common/js-package-manager/JsPackageManager.ts
Abstract signature updated: `getModulePackageJSON(packageName: string, cwd?: string): Promise<PackageJson
Storybook version rename / telemetry
code/core/src/common/utils/get-storybook-info.ts, code/core/src/types/modules/core-common.ts, code/core/src/telemetry/storybook-metadata.ts
Renamed versionversionSpecifier in storybook info types/returns and updated telemetry usage to source versionSpecifier.
Main config / storybook data
code/lib/cli-storybook/src/automigrate/helpers/mainConfigFile.ts
Removed cwd param; obtain versionSpecifier from getStorybookInfo and versionInstalled from package manager (getModulePackageJSON('storybook')); resolve relative configDir with process.cwd(); return now includes versionSpecifier and versionInstalled (removed storybookVersion).
Removed utility
code/core/src/common/utils/cli.ts
Removed getCoercedStorybookVersion and related rendererPackages import and usage (public API removed).
Automigrate & fixes
code/lib/cli-storybook/src/automigrate/index.ts, code/lib/cli-storybook/src/automigrate/types.ts, code/lib/cli-storybook/src/automigrate/fixes/remove-essentials.ts
Removed beforeVersion from types and call sites; automigrate callers now use versionInstalled as storybookVersion; remove-essentials run signature no longer accepts storybookVersion.
Doctor flow & types
code/lib/cli-storybook/src/doctor/index.ts, code/lib/cli-storybook/src/doctor/types.ts
storybookVersion in ProjectDoctorData and getDoctorDiagnostics made optional (`string
CLI utilities
code/lib/cli-storybook/src/util.ts
Replaced beforeVersion usages with versionInstalled for validation, canary and upgrade checks, and output mapping.
Tests / minor test changes
code/lib/cli-storybook/src/add.test.ts, code/lib/cli-storybook/src/automigrate/index.test.ts
Removed getCoercedStorybookVersion mock; tightened typings (Fix<any>[]Fix[]), adjusted runFixWrapper signature and doAutomigrate call to include fixes.

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant Main as getStorybookData
    participant Info as getStorybookInfo
    participant PM as PackageManager

    Note over Caller,PM: New flow — split spec vs installed
    Caller->>Main: getStorybookData({ configDir })
    Main->>Info: getStorybookInfo(dirname(configDir || process.cwd()))
    Info-->>Main: { versionSpecifier }
    Main->>PM: getModulePackageJSON('storybook', /* implicit cwd */)
    PM-->>Main: { versionInstalled }
    Main-->>Caller: { versionSpecifier, versionInstalled }
Loading
sequenceDiagram
    participant Caller
    participant PMBase as JsPackageManager
    participant Proxy as Proxy (BUN/NPM/Yarn/PNPM)

    Note over Caller,Proxy: Old lookup used `this.cwd`
    PMBase->>Proxy: getModulePackageJSON('pkg')
    Proxy->>Proxy: find.up('package.json', { cwd: this.cwd })
    Proxy-->>PMBase: PackageJson | null

    Note over Caller,Proxy: New lookup uses `operationDir`
    PMBase->>Proxy: getModulePackageJSON('pkg', cwd?)
    Proxy->>Proxy: find.up('package.json', { cwd: this.primaryPackageJson.operationDir })
    Proxy-->>PMBase: PackageJson | null
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Attention areas:
    • Verify distinction and propagation of versionSpecifier vs versionInstalled across automigrate, doctor, and telemetry.
    • Confirm operationDir replacement preserves intended resolution semantics for all proxy implementations (including PnP fallbacks).
    • Check callers of getModulePackageJSON updated for the optional cwd parameter and that no call sites assume the old cwd behavior.
    • Ensure optional storybookVersion handling does not break early-exit or validation logic.

Possibly related PRs

✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 42b6c68 and 4dcfdc4.

📒 Files selected for processing (1)
  • code/core/src/common/js-package-manager/PNPMProxy.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use camelCase for variable and function names

Files:

  • code/core/src/common/js-package-manager/PNPMProxy.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Enable TypeScript strict mode
Export functions from modules for testing purposes

Files:

  • code/core/src/common/js-package-manager/PNPMProxy.ts
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • code/core/src/common/js-package-manager/PNPMProxy.ts
code/**/!(*.test).{ts,tsx,js,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

code/**/!(*.test).{ts,tsx,js,mjs}: Use 'logger' from 'storybook/internal/node-logger' for server-side (Node.js) logging, not console.log/console.warn/console.error
Use 'logger' from 'storybook/internal/client-logger' for client-side (browser) logging, not console.log/console.warn/console.error
Do not use console.log, console.warn, or console.error directly unless in isolated files where importing loggers would significantly increase bundle size

Files:

  • code/core/src/common/js-package-manager/PNPMProxy.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: JReinhold
Repo: storybookjs/storybook PR: 32607
File: code/package.json:243-243
Timestamp: 2025-10-02T09:22:13.215Z
Learning: The Storybook repository uses Yarn v^4 (any 4.x version) as the package manager, configured via .yarnrc.yml and package.json packageManager field. Specific patch versions within v4 can be upgraded as needed.
🧬 Code graph analysis (1)
code/core/src/common/js-package-manager/PNPMProxy.ts (1)
code/core/src/common/js-package-manager/JsPackageManager.ts (2)
  • packageJsonPath (706-716)
  • packageJsonPath (749-757)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: normal
  • GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (1)
code/core/src/common/js-package-manager/PNPMProxy.ts (1)

161-164: Now let me examine the actual test file to understand the current test coverage:

Let me check the actual test file and the full context of the change:Perfect! Issue #32211 confirms the bug: when upgrading from 9.0.15 to 9.1.1, the upgrade command reported "Upgrading from 9.1.1 to 9.1.1" instead of the correct version. This validates the PR's purpose to fix version detection.

Now I have enough context to generate the final response. The verification confirms:

  1. The issue [Bug]: Storybook update reports wrong "from" version #32211 exists and matches the described problem
  2. The change from this.cwd to this.primaryPackageJson.operationDir is correct for searching from the proper directory
  3. The find-up library's cwd option properly controls the search starting point
  4. Similar changes have been made consistently across other package managers

Improved package resolution for non-PnP mode.

The find.up function accepts a cwd option to specify the directory to start searching from. This change correctly searches for module package.json from operationDir (where the primary package.json with Storybook dependencies is located) instead of cwd, which handles scenarios where the current working directory differs from the Storybook installation directory. This fixes issue #32211 where the upgrade command incorrectly reported the same version as both "from" and "to" versions, particularly in monorepos or nested project structures.

The change aligns with similar updates across other package manager proxies and should resolve version detection issues during CLI upgrade operations.


Comment @coderabbitai help to get the list of available commands and usage tips.

@valentinpalkovic valentinpalkovic force-pushed the valentin/fix-storybook-version-evaluation branch from 528d942 to 9f09c7e Compare November 24, 2025 20:22
@storybook-app-bot
Copy link

storybook-app-bot bot commented Nov 24, 2025

Package Benchmarks

Commit: 4dcfdc4, ran on 25 November 2025 at 09:54:57 UTC

No significant changes detected, all good. 👏

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
code/lib/cli-storybook/src/doctor/index.ts (1)

194-204: Optional storybookVersion is handled safely, but consider simplifying the error path

  • Declaring storybookVersion as string | undefined and making the parameter to getDoctorDiagnostics optional is consistent with ProjectDoctorData and is safely guarded by the early if (!storybookVersion) { … return results; } check, so the new typing is sound.
  • Independently of this change, doctor()’s try/catch currently pushes a configuration error into diagnosticResults but then proceeds to call collectDoctorResultsByProject with potentially uninitialized configDir/packageManager/mainConfig. Because getDoctorDiagnostics returns early when storybookVersion is falsy, this doesn’t crash, but it does ignore the more specific configuration error you built.

You might want to early-return from doctor() inside the catch (or route diagnosticResults into displayDoctorResults) to avoid carrying partially initialized state and to surface the more precise configuration error.

Also applies to: 243-268

code/lib/cli-storybook/src/automigrate/fixes/remove-essentials.ts (1)

129-139: Updated destructuring matches actual usage; consider cleaning up unused fields

Restricting the destructuring in run() to { hasEssentials, hasDocsDisabled, additionalAddonsToRemove, essentialsOptions } matches what the function actually uses and avoids unused locals.

Given that AddonDocsOptions still includes hasDocsAddon and allDeps that run() never reads, you might either:

  • Use them to avoid re-adding @storybook/addon-docs when it’s already present, or
  • Remove them from AddonDocsOptions and the check result if they’re intentionally unused.

Not urgent, but tightening the options shape would make this migration easier to follow.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9f09c7e and bfd4d07.

📒 Files selected for processing (8)
  • code/core/src/common/utils/cli.ts (0 hunks)
  • code/lib/cli-storybook/src/add.test.ts (0 hunks)
  • code/lib/cli-storybook/src/automigrate/fixes/remove-essentials.ts (1 hunks)
  • code/lib/cli-storybook/src/automigrate/helpers/mainConfigFile.ts (2 hunks)
  • code/lib/cli-storybook/src/automigrate/index.test.ts (3 hunks)
  • code/lib/cli-storybook/src/automigrate/index.ts (0 hunks)
  • code/lib/cli-storybook/src/doctor/index.ts (2 hunks)
  • code/lib/cli-storybook/src/doctor/types.ts (1 hunks)
💤 Files with no reviewable changes (3)
  • code/lib/cli-storybook/src/add.test.ts
  • code/lib/cli-storybook/src/automigrate/index.ts
  • code/core/src/common/utils/cli.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • code/lib/cli-storybook/src/automigrate/helpers/mainConfigFile.ts
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use camelCase for variable and function names

Files:

  • code/lib/cli-storybook/src/doctor/types.ts
  • code/lib/cli-storybook/src/automigrate/index.test.ts
  • code/lib/cli-storybook/src/automigrate/fixes/remove-essentials.ts
  • code/lib/cli-storybook/src/doctor/index.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Enable TypeScript strict mode
Export functions from modules for testing purposes

Files:

  • code/lib/cli-storybook/src/doctor/types.ts
  • code/lib/cli-storybook/src/automigrate/index.test.ts
  • code/lib/cli-storybook/src/automigrate/fixes/remove-essentials.ts
  • code/lib/cli-storybook/src/doctor/index.ts
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • code/lib/cli-storybook/src/doctor/types.ts
  • code/lib/cli-storybook/src/automigrate/index.test.ts
  • code/lib/cli-storybook/src/automigrate/fixes/remove-essentials.ts
  • code/lib/cli-storybook/src/doctor/index.ts
code/**/!(*.test).{ts,tsx,js,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

code/**/!(*.test).{ts,tsx,js,mjs}: Use 'logger' from 'storybook/internal/node-logger' for server-side (Node.js) logging, not console.log/console.warn/console.error
Use 'logger' from 'storybook/internal/client-logger' for client-side (browser) logging, not console.log/console.warn/console.error
Do not use console.log, console.warn, or console.error directly unless in isolated files where importing loggers would significantly increase bundle size

Files:

  • code/lib/cli-storybook/src/doctor/types.ts
  • code/lib/cli-storybook/src/automigrate/fixes/remove-essentials.ts
  • code/lib/cli-storybook/src/doctor/index.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{test,spec}.{ts,tsx}: Test files should follow the naming pattern *.test.ts, *.test.tsx, *.spec.ts, or *.spec.tsx
Follow the spy mocking rules defined in .cursor/rules/spy-mocking.mdc for consistent mocking patterns with Vitest

Files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.test.{ts,tsx}: Write meaningful unit tests that import and call functions being tested, not just verify syntax patterns
Use 'yarn vitest run --coverage ' to run tests with coverage reports and aim for 75%+ coverage of statements/lines
Focus test coverage on all branches, conditions, edge cases, error paths, and different input variations
Use 'vi.mock()' to mock external dependencies like file system and loggers in unit tests

Files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/spy-mocking.mdc)

**/*.test.{ts,tsx,js,jsx}: Use vi.mock() with the spy: true option for all package and file mocks in Vitest tests
Place all mocks at the top of the test file before any test cases
Use vi.mocked() to type and access the mocked functions in Vitest tests
Implement mock behaviors in beforeEach blocks in Vitest tests
Mock all required dependencies that the test subject uses
Each mock implementation should return a Promise for async functions in Vitest
Mock implementations should match the expected return type of the original function
Mock all required properties and methods that the test subject uses in Vitest tests
Avoid direct function mocking without vi.mocked() in Vitest tests
Avoid mock implementations outside of beforeEach blocks in Vitest tests
Avoid mocking without the spy: true option in Vitest tests
Avoid inline mock implementations within test cases in Vitest tests
Avoid mocking only a subset of required dependencies in Vitest tests
Mock at the highest level of abstraction needed in Vitest tests
Keep mock implementations simple and focused in Vitest tests
Use type-safe mocking with vi.mocked() in Vitest tests
Document complex mock behaviors in Vitest tests
Group related mocks together in Vitest tests

Files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
🧠 Learnings (9)
📚 Learning: 2025-11-05T09:38:47.712Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/components/components/Select/Select.tsx:200-204
Timestamp: 2025-11-05T09:38:47.712Z
Learning: Repo: storybookjs/storybook — Guidance: Until Storybook 11 is released, do not suggest using React.useId anywhere (e.g., in code/core/src/components/components/Select/Select.tsx) to maintain compatibility with React 17 runtimes. Prefer advising: accept a caller-provided props.id and, if needed, generate a client-only fallback id to minimize SSR hydration issues — but avoid useId. Resume prompting for useId after Storybook 11.

Applied to files:

  • code/lib/cli-storybook/src/doctor/types.ts
  • code/lib/cli-storybook/src/automigrate/fixes/remove-essentials.ts
  • code/lib/cli-storybook/src/doctor/index.ts
📚 Learning: 2025-10-02T09:22:13.215Z
Learnt from: JReinhold
Repo: storybookjs/storybook PR: 32607
File: code/package.json:243-243
Timestamp: 2025-10-02T09:22:13.215Z
Learning: The Storybook repository uses Yarn v^4 (any 4.x version) as the package manager, configured via .yarnrc.yml and package.json packageManager field. Specific patch versions within v4 can be upgraded as needed.

Applied to files:

  • code/lib/cli-storybook/src/doctor/types.ts
  • code/lib/cli-storybook/src/doctor/index.ts
📚 Learning: 2025-11-24T17:49:47.649Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.649Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory

Applied to files:

  • code/lib/cli-storybook/src/doctor/types.ts
  • code/lib/cli-storybook/src/doctor/index.ts
📚 Learning: 2025-11-24T17:49:59.268Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.268Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mocking only a subset of required dependencies in Vitest tests

Applied to files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
📚 Learning: 2025-11-24T17:49:59.268Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.268Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mock implementations outside of `beforeEach` blocks in Vitest tests

Applied to files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
📚 Learning: 2025-11-24T17:49:59.268Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.268Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Implement mock behaviors in `beforeEach` blocks in Vitest tests

Applied to files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
📚 Learning: 2025-11-24T17:49:59.268Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.268Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid inline mock implementations within test cases in Vitest tests

Applied to files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
📚 Learning: 2025-09-18T20:51:06.618Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/viewport/components/Tool.tsx:38-39
Timestamp: 2025-09-18T20:51:06.618Z
Learning: The useGlobals hook from storybook/manager-api returns a tuple where the third element (storyGlobals) is typed as Globals, not Globals | undefined. This means TypeScript guarantees it's always defined, making the `in` operator safe to use without additional null checks.

Applied to files:

  • code/lib/cli-storybook/src/doctor/index.ts
📚 Learning: 2025-09-18T20:51:06.618Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/viewport/components/Tool.tsx:38-39
Timestamp: 2025-09-18T20:51:06.618Z
Learning: In viewport tool code, when using the `useGlobals` hook from storybook/manager-api, the third returned value `storyGlobals` is guaranteed by TypeScript to be defined (not undefined/null), making the `in` operator safe to use without additional null checks.

Applied to files:

  • code/lib/cli-storybook/src/doctor/index.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: normal
  • GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (2)
code/lib/cli-storybook/src/doctor/types.ts (1)

9-14: Optional storybookVersion on ProjectDoctorData is correct

Making storybookVersion optional matches how getDoctorDiagnostics handles missing versions and allows callers to represent “version unknown” without casting. No issues from this change alone.

code/lib/cli-storybook/src/automigrate/index.test.ts (1)

116-121: Test wrapper now correctly relies on detected “from” version instead of passing beforeVersion

Updating runFixWrapper to accept only storybookVersion and adjusting the call sites to pass { storybookVersion: '7.0.0' } aligns the tests with the new runFixes contract, where the “from” version is derived via getModulePackageJSON (mocked to beforeVersion). This matches the desired behavior for upgrade flows and avoids reintroducing the old mis-threaded beforeVersion parameter.

Also applies to: 156-183

…er and update related references across utils, telemetry, and automigration modules.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
code/lib/cli-storybook/src/util.ts (1)

285-352: Using versionInstalled to drive beforeVersion/upgrade logic correctly fixes the “from 9.1.1 to 9.1.1” bug

Switching processProject to:

  • read versionInstalled from getStorybookData,
  • validate and compare against currentCLIVersion, and
  • surface beforeVersion: versionInstalled,

means the upgrade flow now reflects the project’s actual installed Storybook version when computing isUpgrade and when displaying the “from → to” message. This directly addresses the misreported “from” version in the linked issue.

Two follow‑ups to consider:

  1. Robustness when storybook meta package is missing

    versionInstalled currently comes from packageManager.getModulePackageJSON('storybook')?.version. In projects that only depend on view‑layer packages (e.g. @storybook/react) and not the storybook meta package, this may be undefined, causing validateVersion to throw UpgradeStorybookUnknownCurrentVersionError. If such setups are still meant to be supported by upgrade, you may want to:

    // Sketch only; adapt to existing helpers
    const versionInstalled =
      (await packageManager.getModulePackageJSON('storybook'))?.version ??
      (await getInstalledStorybookVersion(packageManager));

    so you fall back to the more generic resolution logic when the meta package isn’t present.

  2. Clarify the meaning of beforeVersion

    Now that beforeVersion is always derived from versionInstalled, its semantics are “installed version before running this CLI”, not “CLI’s own version”. That seems desired, but it may be worth double‑checking any downstream consumers (logging/UI, doctor, automigrate) for assumptions about beforeVersion being a CLI version rather than a project version.

To verify behavior across edge cases (meta package absent, canary installs), you can run targeted upgrades in a few minimal projects (with and without storybook in dependencies) and confirm that:

  • the CLI prints the correct “Upgrading from X to Y” message, and
  • non‑canary flows don’t unexpectedly throw UpgradeStorybookUnknownCurrentVersionError.
code/lib/cli-storybook/src/automigrate/index.test.ts (1)

51-193: Tests correctly adapted to versionInstalled flow and cleaner Fix typing

The updates in this block look sound:

  • const fixes: Fix[] = [...] relies on Fix’s default generic and removes the explicit any, improving type safety without changing behavior.
  • PackageManager implementing getModulePackageJSON(packageName, basePath?) and the cast new PackageManager() as unknown as JsPackageManager remain compatible with the updated JsPackageManager signature and keep the mock simple for these tests.
  • runFixWrapper now only takes { storybookVersion }, reflecting that beforeVersion is derived from the mocked getModulePackageJSON rather than being passed explicitly.
  • runAutomigrateWrapper’s getStorybookData.mockResolvedValue({ ...common, beforeVersion, versionInstalled: storybookVersion, isLatest: true }) aligns with the real getStorybookData return shape after the refactor, while doAutomigrate({ configDir, fixes }) exercises the new fixes‑injection path.

Optionally, you might move more of the mock configuration into beforeEach (e.g. the getStorybookData.mockResolvedValue for specific scenarios) to more closely follow the repo’s spy‑mocking conventions, but the current structure is functionally correct.

code/core/src/common/utils/get-storybook-info.ts (1)

75-100: New getStorybookVersionSpecifier cleanly exposes the dependency range, with a small path refinement to consider

The new flow:

  • scans all package.json files under dirname(configDir) via JsPackageManager.listAllPackageJsonPaths,
  • finds the first storybook dependency across dependencies/devDependencies/peerDependencies, and
  • threads the resulting version string through getStorybookInfo as versionSpecifier,

nicely decouples the declared Storybook range (specifier) from the installed version used elsewhere. This aligns with the type change on CoreCommon_StorybookInfo and the telemetry update.

One small improvement to consider: getConfigInfo(configDir) may adjust the effective config directory (e.g. by parsing the storybook script), but getStorybookVersionSpecifier is still called with the original configDir. Using the resolved path would make the lookup more robust in non‑standard setups:

const configInfo = getConfigInfo(configDir);
const versionSpecifier = getStorybookVersionSpecifier(configInfo.configDir);

This keeps behavior unchanged for the common case while better matching how the rest of getStorybookInfo already respects configInfo.configDir.

Also applies to: 153-159, 181-187

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bfd4d07 and 9751b81.

📒 Files selected for processing (9)
  • code/core/src/common/utils/get-storybook-info.ts (2 hunks)
  • code/core/src/telemetry/storybook-metadata.ts (1 hunks)
  • code/core/src/types/modules/core-common.ts (1 hunks)
  • code/lib/cli-storybook/src/automigrate/helpers/mainConfigFile.ts (3 hunks)
  • code/lib/cli-storybook/src/automigrate/index.test.ts (6 hunks)
  • code/lib/cli-storybook/src/automigrate/index.ts (3 hunks)
  • code/lib/cli-storybook/src/automigrate/types.ts (0 hunks)
  • code/lib/cli-storybook/src/doctor/index.ts (3 hunks)
  • code/lib/cli-storybook/src/util.ts (3 hunks)
💤 Files with no reviewable changes (1)
  • code/lib/cli-storybook/src/automigrate/types.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • code/lib/cli-storybook/src/automigrate/helpers/mainConfigFile.ts
  • code/lib/cli-storybook/src/doctor/index.ts
  • code/lib/cli-storybook/src/automigrate/index.ts
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use camelCase for variable and function names

Files:

  • code/core/src/telemetry/storybook-metadata.ts
  • code/core/src/types/modules/core-common.ts
  • code/lib/cli-storybook/src/util.ts
  • code/core/src/common/utils/get-storybook-info.ts
  • code/lib/cli-storybook/src/automigrate/index.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Enable TypeScript strict mode
Export functions from modules for testing purposes

Files:

  • code/core/src/telemetry/storybook-metadata.ts
  • code/core/src/types/modules/core-common.ts
  • code/lib/cli-storybook/src/util.ts
  • code/core/src/common/utils/get-storybook-info.ts
  • code/lib/cli-storybook/src/automigrate/index.test.ts
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • code/core/src/telemetry/storybook-metadata.ts
  • code/core/src/types/modules/core-common.ts
  • code/lib/cli-storybook/src/util.ts
  • code/core/src/common/utils/get-storybook-info.ts
  • code/lib/cli-storybook/src/automigrate/index.test.ts
code/**/!(*.test).{ts,tsx,js,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

code/**/!(*.test).{ts,tsx,js,mjs}: Use 'logger' from 'storybook/internal/node-logger' for server-side (Node.js) logging, not console.log/console.warn/console.error
Use 'logger' from 'storybook/internal/client-logger' for client-side (browser) logging, not console.log/console.warn/console.error
Do not use console.log, console.warn, or console.error directly unless in isolated files where importing loggers would significantly increase bundle size

Files:

  • code/core/src/telemetry/storybook-metadata.ts
  • code/core/src/types/modules/core-common.ts
  • code/lib/cli-storybook/src/util.ts
  • code/core/src/common/utils/get-storybook-info.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{test,spec}.{ts,tsx}: Test files should follow the naming pattern *.test.ts, *.test.tsx, *.spec.ts, or *.spec.tsx
Follow the spy mocking rules defined in .cursor/rules/spy-mocking.mdc for consistent mocking patterns with Vitest

Files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.test.{ts,tsx}: Write meaningful unit tests that import and call functions being tested, not just verify syntax patterns
Use 'yarn vitest run --coverage ' to run tests with coverage reports and aim for 75%+ coverage of statements/lines
Focus test coverage on all branches, conditions, edge cases, error paths, and different input variations
Use 'vi.mock()' to mock external dependencies like file system and loggers in unit tests

Files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/spy-mocking.mdc)

**/*.test.{ts,tsx,js,jsx}: Use vi.mock() with the spy: true option for all package and file mocks in Vitest tests
Place all mocks at the top of the test file before any test cases
Use vi.mocked() to type and access the mocked functions in Vitest tests
Implement mock behaviors in beforeEach blocks in Vitest tests
Mock all required dependencies that the test subject uses
Each mock implementation should return a Promise for async functions in Vitest
Mock implementations should match the expected return type of the original function
Mock all required properties and methods that the test subject uses in Vitest tests
Avoid direct function mocking without vi.mocked() in Vitest tests
Avoid mock implementations outside of beforeEach blocks in Vitest tests
Avoid mocking without the spy: true option in Vitest tests
Avoid inline mock implementations within test cases in Vitest tests
Avoid mocking only a subset of required dependencies in Vitest tests
Mock at the highest level of abstraction needed in Vitest tests
Keep mock implementations simple and focused in Vitest tests
Use type-safe mocking with vi.mocked() in Vitest tests
Document complex mock behaviors in Vitest tests
Group related mocks together in Vitest tests

Files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
🧠 Learnings (10)
📓 Common learnings
Learnt from: JReinhold
Repo: storybookjs/storybook PR: 32607
File: code/package.json:243-243
Timestamp: 2025-10-02T09:22:13.215Z
Learning: The Storybook repository uses Yarn v^4 (any 4.x version) as the package manager, configured via .yarnrc.yml and package.json packageManager field. Specific patch versions within v4 can be upgraded as needed.
📚 Learning: 2025-11-05T09:38:47.712Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/components/components/Select/Select.tsx:200-204
Timestamp: 2025-11-05T09:38:47.712Z
Learning: Repo: storybookjs/storybook — Guidance: Until Storybook 11 is released, do not suggest using React.useId anywhere (e.g., in code/core/src/components/components/Select/Select.tsx) to maintain compatibility with React 17 runtimes. Prefer advising: accept a caller-provided props.id and, if needed, generate a client-only fallback id to minimize SSR hydration issues — but avoid useId. Resume prompting for useId after Storybook 11.

Applied to files:

  • code/core/src/telemetry/storybook-metadata.ts
  • code/lib/cli-storybook/src/util.ts
📚 Learning: 2025-10-02T09:22:13.215Z
Learnt from: JReinhold
Repo: storybookjs/storybook PR: 32607
File: code/package.json:243-243
Timestamp: 2025-10-02T09:22:13.215Z
Learning: The Storybook repository uses Yarn v^4 (any 4.x version) as the package manager, configured via .yarnrc.yml and package.json packageManager field. Specific patch versions within v4 can be upgraded as needed.

Applied to files:

  • code/lib/cli-storybook/src/util.ts
📚 Learning: 2025-11-24T17:49:59.268Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.268Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mocking only a subset of required dependencies in Vitest tests

Applied to files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
📚 Learning: 2025-11-24T17:49:47.649Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.649Z
Learning: Applies to **/*.test.{ts,tsx} : Focus test coverage on all branches, conditions, edge cases, error paths, and different input variations

Applied to files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
📚 Learning: 2025-11-24T17:49:47.649Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.649Z
Learning: Applies to **/*.test.{ts,tsx} : Write meaningful unit tests that import and call functions being tested, not just verify syntax patterns

Applied to files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
📚 Learning: 2025-11-24T17:49:59.268Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.268Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Implement mock behaviors in `beforeEach` blocks in Vitest tests

Applied to files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
📚 Learning: 2025-11-24T17:49:59.268Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.268Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Mock all required dependencies that the test subject uses

Applied to files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
📚 Learning: 2025-11-24T17:49:59.268Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.268Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mock implementations outside of `beforeEach` blocks in Vitest tests

Applied to files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
📚 Learning: 2025-11-24T17:49:59.268Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.268Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Each mock implementation should return a Promise for async functions in Vitest

Applied to files:

  • code/lib/cli-storybook/src/automigrate/index.test.ts
🧬 Code graph analysis (2)
code/lib/cli-storybook/src/util.ts (1)
code/lib/cli-storybook/src/automigrate/helpers/mainConfigFile.ts (1)
  • getStorybookData (102-159)
code/lib/cli-storybook/src/automigrate/index.test.ts (3)
code/lib/cli-storybook/src/automigrate/types.ts (1)
  • Fix (52-60)
code/lib/cli-storybook/src/automigrate/helpers/mainConfigFile.ts (1)
  • getStorybookData (102-159)
code/lib/cli-storybook/src/automigrate/index.ts (1)
  • doAutomigrate (43-102)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: normal
  • GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (2)
code/core/src/types/modules/core-common.ts (1)

685-693: CoreCommon_StorybookInfo field rename aligns with new versionSpecifier semantics

Renaming version to versionSpecifier here matches how getStorybookInfo and telemetry now expose Storybook’s dependency range, not the installed version. This keeps the types consistent across the codepaths using CoreCommon_StorybookInfo.

code/core/src/telemetry/storybook-metadata.ts (1)

238-249: Telemetry now pulls storybookVersionSpecifier from getStorybookInfo

Wiring storybookVersionSpecifier to storybookInfo.versionSpecifier ?? '' correctly aligns telemetry with the new CoreCommon_StorybookInfo shape and ensures you report the user’s dependency specifier (e.g. ^9.0.0 or workspace:*) rather than the CLI’s own version, while preserving a safe empty‑string fallback.

@valentinpalkovic valentinpalkovic merged commit 358240c into next Nov 25, 2025
66 of 67 checks passed
@valentinpalkovic valentinpalkovic deleted the valentin/fix-storybook-version-evaluation branch November 25, 2025 11:01
@github-actions github-actions bot mentioned this pull request Nov 25, 2025
10 tasks
@coderabbitai coderabbitai bot mentioned this pull request Nov 25, 2025
8 tasks
@coderabbitai coderabbitai bot mentioned this pull request Dec 4, 2025
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Storybook update reports wrong "from" version

3 participants