From 5ee7e9aa5c21ea4bdc3a40a9b5153d43f0843a05 Mon Sep 17 00:00:00 2001 From: mukunda katta Date: Fri, 15 May 2026 01:25:49 -0700 Subject: [PATCH 1/2] fix: ignore story-like directories in indexer --- .../utils/StoryIndexGenerator.test.ts | 23 +++++++++++++++++++ .../core-server/utils/StoryIndexGenerator.ts | 10 +++++++- .../Button.stories.tsx/Primary.png | 1 + 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 code/core/src/core-server/utils/__mockdata__/src/__screenshots__/Button.stories.tsx/Primary.png diff --git a/code/core/src/core-server/utils/StoryIndexGenerator.test.ts b/code/core/src/core-server/utils/StoryIndexGenerator.test.ts index 4c3bb0817bd6..82f12b110064 100644 --- a/code/core/src/core-server/utils/StoryIndexGenerator.test.ts +++ b/code/core/src/core-server/utils/StoryIndexGenerator.test.ts @@ -1,3 +1,4 @@ +import { existsSync } from 'node:fs'; import { join } from 'node:path'; import { beforeEach, describe, expect, it, vi } from 'vitest'; @@ -1997,6 +1998,28 @@ describe('StoryIndexGenerator', () => { }); describe('warnings', () => { + it('does not match directories that have story-like names', async () => { + const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry( + './src/**/*.stories.tsx', + options + ); + + const files = await StoryIndexGenerator.findMatchingFiles( + specifier, + options.workingDir, + true + ); + const storyLikeDirectory = join( + options.workingDir, + './src/__screenshots__/Button.stories.tsx' + ); + const storyLikeDirectoryFile = join(storyLikeDirectory, 'Primary.png'); + + expect(existsSync(storyLikeDirectoryFile)).toBe(true); + expect(Object.keys(files)).not.toContain(storyLikeDirectory); + expect(Object.keys(files)).not.toContain(storyLikeDirectoryFile); + }); + it('when entries do not match any files', async () => { const generator = new StoryIndexGenerator( [normalizeStoriesEntry('./src/docs2/wrong.js', options)], diff --git a/code/core/src/core-server/utils/StoryIndexGenerator.ts b/code/core/src/core-server/utils/StoryIndexGenerator.ts index 3848861d4fa5..fe2d074bc6b2 100644 --- a/code/core/src/core-server/utils/StoryIndexGenerator.ts +++ b/code/core/src/core-server/utils/StoryIndexGenerator.ts @@ -168,10 +168,18 @@ export class StoryIndexGenerator { const { globby } = await import('globby'); // Execute globby within the new CWD to ensure `ignore` patterns work correctly. + const globOptions = commonGlobOptions(globPattern); + const ignore = [ + ...(('ignore' in globOptions && globOptions.ignore) || []), + `${globPattern}/**`, + ]; + const files = await globby(globPattern, { absolute: true, cwd: globCwd, - ...commonGlobOptions(globPattern), + ...globOptions, + ignore, + onlyFiles: true, }); if (files.length === 0 && !ignoreWarnings) { diff --git a/code/core/src/core-server/utils/__mockdata__/src/__screenshots__/Button.stories.tsx/Primary.png b/code/core/src/core-server/utils/__mockdata__/src/__screenshots__/Button.stories.tsx/Primary.png new file mode 100644 index 000000000000..b97e4a75e2ca --- /dev/null +++ b/code/core/src/core-server/utils/__mockdata__/src/__screenshots__/Button.stories.tsx/Primary.png @@ -0,0 +1 @@ +mock screenshot fixture From c7958d62a043e11bd9d26345240994b43cbe008e Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 19 May 2026 15:39:54 +0200 Subject: [PATCH 2/2] Fix: remove broken ignore pattern that excluded all story files The original PR added `${globPattern}/**` as a globby ignore pattern to prevent story-like directories from being indexed. However, micromatch's `/**` suffix can match zero-length trailing paths, causing the pattern to also match the story files themselves. This caused ALL stories to be ignored, resulting in 44 test failures and all sandbox dev/e2e/chromatic CI failures. The correct fix is to rely on globby's `onlyFiles: true` option (which is the fast-glob default but is now explicit) to prevent directories from being returned. This correctly excludes the `Button.stories.tsx` directory from being indexed while keeping all legitimate story files. Note: A secondary attempt with `${globPattern}/**/*` also failed because globby tries to stat() the ignore pattern path and throws ENOTDIR when the pattern resolves through an actual file (e.g., errors/A.mdx/**/*). Co-Authored-By: Claude Sonnet 4.6 --- code/core/src/core-server/utils/StoryIndexGenerator.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/code/core/src/core-server/utils/StoryIndexGenerator.ts b/code/core/src/core-server/utils/StoryIndexGenerator.ts index fe2d074bc6b2..2cab59229dc5 100644 --- a/code/core/src/core-server/utils/StoryIndexGenerator.ts +++ b/code/core/src/core-server/utils/StoryIndexGenerator.ts @@ -167,18 +167,10 @@ export class StoryIndexGenerator { // eslint-disable-next-line depend/ban-dependencies const { globby } = await import('globby'); - // Execute globby within the new CWD to ensure `ignore` patterns work correctly. - const globOptions = commonGlobOptions(globPattern); - const ignore = [ - ...(('ignore' in globOptions && globOptions.ignore) || []), - `${globPattern}/**`, - ]; - const files = await globby(globPattern, { absolute: true, cwd: globCwd, - ...globOptions, - ignore, + ...commonGlobOptions(globPattern), onlyFiles: true, });