Skip to content

Conversation

@JReinhold
Copy link
Contributor

@JReinhold JReinhold commented Dec 22, 2025

Originally proposed by @cdedreuille

What I did

Refactored the way the manifest logic filters entries by the manifest tag, so that now the manifest tag actually exists in the index instead of being synthetically applied during manifest creation. This enables support for users disabling manifests globally with the !manifest tag in a preview file, and then selectively opting-in stories/docs afterwards, instead of the default worklfow of opting-out stories/docs.

It also includes a small change to the API of the experimental_manifests preset. It no longer takes in the raw index as input, but instead a pre-filtered list of entries, as I assume all manifest generators will want to filter by the manifest tag anyway.

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 PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

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

Summary by CodeRabbit

  • New Features

    • Added a default "manifest" tag to project/story tags to mark entries for manifest processing.
  • Refactor

    • Centralized manifest retrieval so all manifest endpoints use a single source of truth, reducing duplication.
  • Tests

    • Updated and added tests and snapshots to cover manifest-tagged entries and manifest filtering behavior.

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

…fest preset now takes a pre-filtered list of entries, support users globally disabling manifest with '!manifest' in preview.js
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the manifest tag filtering mechanism to enable users to globally disable manifests with !manifest in preview files and then selectively opt-in specific stories/docs. Previously, the manifest tag was synthetically applied during manifest generation; now it exists directly in the story index.

Key Changes:

  • Added 'manifest' to default tags in StoryIndexGenerator, making it combinable with user-defined tags including negations
  • Modified experimental_manifests preset API to receive pre-filtered manifestEntries instead of the full index
  • Updated manifest generation logic to filter by the 'manifest' tag upstream before passing to preset implementations

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
code/core/src/core-server/utils/StoryIndexGenerator.ts Adds 'manifest' to the default project tags, enabling tag combination and negation support
code/core/src/core-server/utils/manifests/manifests.ts Introduces getManifests helper that filters entries by 'manifest' tag before passing to presets; updates API signature
code/core/src/core-server/utils/manifests/manifests.test.ts Adds test coverage for manifest tag filtering and validates the new API signature
code/renderers/react/src/componentManifest/generator.ts Updates to receive manifestEntries instead of index; removes local combineTags logic; updates extractStories to filter against pre-filtered entries
code/renderers/react/src/componentManifest/generator.test.ts Updates test setup to provide manifestEntries instead of index; adds manifest tag to test fixtures and updates snapshots
code/renderers/react/src/componentManifest/fixtures.ts Adds 'manifest' tag to all test fixture entries and includes missing 'title' properties in meta objects
@JReinhold JReinhold added maintenance User-facing maintenance tasks ci:normal manifest Component manifest generation labels Dec 22, 2025
@JReinhold JReinhold self-assigned this Dec 22, 2025
@nx-cloud
Copy link

nx-cloud bot commented Dec 22, 2025

View your CI Pipeline Execution ↗ for commit 6d43e7a

Command Status Duration Result
nx run-many -t compile,check,knip,test,pretty-d... ✅ Succeeded 3m 26s View ↗

☁️ Nx Cloud last updated this comment at 2025-12-22 10:34:36 UTC

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 22, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Centralizes manifest extraction and propagation: StoryIndexGenerator now includes a default "manifest" tag; server-side manifests logic filters index entries for that tag via a new getManifests helper; the React component manifest generator now accepts an explicit list of manifestEntries instead of a full story index.

Changes

Cohort / File(s) Summary
StoryIndexGenerator default tags
code/core/src/core-server/utils/StoryIndexGenerator.ts
Added 'manifest' to the default project tags array (from ['dev','test'] to ['dev','test','manifest']).
Core server manifest generation
code/core/src/core-server/utils/manifests/manifests.ts, code/core/src/core-server/utils/manifests/manifests.test.ts
Added internal getManifests(presets) that resolves the story index, filters entries tagged 'manifest', and applies the experimental_manifests preset. Updated writeManifests and registerManifests to use getManifests. Added/updated tests to assert only 'manifest'-tagged entries are passed to the preset.
React component manifest generator
code/renderers/react/src/componentManifest/generator.ts, code/renderers/react/src/componentManifest/generator.test.ts, code/renderers/react/src/componentManifest/fixtures.ts
Switched generator API to accept manifestEntries: IndexEntry[] instead of a full index: StoryIndex; removed tag-combine filtering from generator and use membership in manifestEntries to select stories. Updated fixtures/tests to include manifest tags and explicit titles and to pass filtered manifestEntries.
Test snapshots / JSON expectations
code/core/src/core-server/utils/StoryIndexGenerator.test.ts, code/core/src/core-server/utils/index-json.test.ts
Updated snapshots/inline expectations to include the new "manifest" tag on many story/docs entries.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Dev Server / Caller
    participant GM as getManifests (manifests.ts)
    participant SI as StoryIndexGenerator
    participant PM as experimental_manifests preset
    participant CG as React Component Manifest Generator

    Note over Client,SI: Server requests manifest data

    Client->>GM: request manifests (presets)
    GM->>SI: resolve storyIndexGenerator
    SI-->>GM: return index { entries: ... }

    rect rgba(120,180,120,0.12)
      Note over GM: Filter entries by 'manifest' tag
      GM->>GM: select entries with tag 'manifest' -> manifestEntries[]
    end

    GM->>PM: call experimental_manifests({ manifestEntries })
    PM-->>GM: return manifests object
    GM-->>Client: return manifests

    Note over Client,CG: Component generator now consumes manifestEntries
    Client->>CG: pass manifestEntries[]
    CG->>CG: process only manifestEntries to build component manifests
    CG-->>Client: component manifests
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas needing extra attention:
    • Call-sites and presets wiring to ensure all callers of the manifests preset now receive { manifestEntries } (type/shape changes).
    • Tests and fixtures updated to include the new manifest tag and explicit titles — verify coverage and snapshot consistency.
    • Centralized getManifests behavior (early-return, empty/default shapes) and endpoints that previously fetched per-endpoint manifests.

Possibly related PRs

✨ Finishing touches
  • 📝 Generate docstrings

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

Copy link
Contributor

@kasperpeulen kasperpeulen left a comment

Choose a reason for hiding this comment

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

Looks great to me!

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 (1)
code/core/src/core-server/utils/index-json.test.ts (1)

18-27: Consider adding spy: true to mocks for consistency with coding guidelines.

The coding guidelines specify using spy: true for all package and file mocks. While line 19 follows this pattern, lines 18 and 20 don't.

🔎 Suggested refactor
-vi.mock('watchpack');
+vi.mock('watchpack', { spy: true });
 vi.mock('es-toolkit/function', { spy: true });
-vi.mock('storybook/internal/node-logger');
+vi.mock('storybook/internal/node-logger', { spy: true });

Note: If these mocks require custom implementations in beforeEach, those can still be applied via vi.mocked().

Based on coding guidelines for Vitest test files.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 22c240e and 6d43e7a.

📒 Files selected for processing (2)
  • code/core/src/core-server/utils/StoryIndexGenerator.test.ts
  • code/core/src/core-server/utils/index-json.test.ts
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{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/core/src/core-server/utils/index-json.test.ts
  • code/core/src/core-server/utils/StoryIndexGenerator.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/core/src/core-server/utils/index-json.test.ts
  • code/core/src/core-server/utils/StoryIndexGenerator.test.ts
**/*.{js,jsx,json,html,ts,tsx,mjs}

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

Use ESLint and Prettier configurations that are enforced in the codebase

Files:

  • code/core/src/core-server/utils/index-json.test.ts
  • code/core/src/core-server/utils/StoryIndexGenerator.test.ts
**/*.{ts,tsx}

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

Enable TypeScript strict mode

Files:

  • code/core/src/core-server/utils/index-json.test.ts
  • code/core/src/core-server/utils/StoryIndexGenerator.test.ts
code/**/*.{ts,tsx,js,jsx,mjs}

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

code/**/*.{ts,tsx,js,jsx,mjs}: Use server-side logger from 'storybook/internal/node-logger' for Node.js code
Use client-side logger from 'storybook/internal/client-logger' for browser code
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/core-server/utils/index-json.test.ts
  • code/core/src/core-server/utils/StoryIndexGenerator.test.ts
code/**/*.{ts,tsx,js,jsx}

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

Export functions that need to be tested from their modules

Files:

  • code/core/src/core-server/utils/index-json.test.ts
  • code/core/src/core-server/utils/StoryIndexGenerator.test.ts
code/**/*.{test,spec}.{ts,tsx,js,jsx}

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

code/**/*.{test,spec}.{ts,tsx,js,jsx}: Write meaningful unit tests that actually import and call the functions being tested
Mock external dependencies using vi.mock() for file system, loggers, and other external dependencies in tests
Aim for high test coverage of business logic (75%+ for statements/lines) using coverage reports

Files:

  • code/core/src/core-server/utils/index-json.test.ts
  • code/core/src/core-server/utils/StoryIndexGenerator.test.ts
code/**/*.{js,jsx,json,html,ts,tsx,mjs}

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

code/**/*.{js,jsx,json,html,ts,tsx,mjs}: Run Prettier with --write flag to format code before committing
Run ESLint with yarn lint:js:cmd to check for linting issues and fix errors before committing

Files:

  • code/core/src/core-server/utils/index-json.test.ts
  • code/core/src/core-server/utils/StoryIndexGenerator.test.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). (3)
  • GitHub Check: normal
  • GitHub Check: nx
  • GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (2)
code/core/src/core-server/utils/index-json.test.ts (1)

113-491: LGTM! Snapshot correctly reflects the new manifest tag behavior.

The inline snapshot has been consistently updated across all 25 index entries (docs and stories) to include the "manifest" tag. This aligns with the PR objective of adding the manifest tag by default to support !manifest filtering in preview files.

code/core/src/core-server/utils/StoryIndexGenerator.test.ts (1)

82-2379: LGTM! Test snapshots correctly updated to reflect new manifest tagging behavior.

The systematic addition of the "manifest" tag to all test snapshots aligns with the PR's objective to include manifest tags on index entries by default. The changes are consistent throughout, and the intentional omission in test cases where projectTags is explicitly overridden (e.g., lines 1330, 1024) demonstrates proper handling of edge cases.

@JReinhold JReinhold changed the title Manifests: support !manifest tag in preview files Dec 22, 2025
@JReinhold JReinhold merged commit 0fcdf47 into next Dec 22, 2025
70 checks passed
@JReinhold JReinhold deleted the jeppe/support-manifest-tag-in-preview branch December 22, 2025 22:04
@github-actions github-actions bot mentioned this pull request Dec 22, 2025
22 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:normal maintenance User-facing maintenance tasks manifest Component manifest generation

3 participants