Skip to content

fix(storybook): disable Vite publicDir to stop static copy race#6482

Open
blunteshwar wants to merge 2 commits into
mainfrom
fix-flaky-docs-deployment
Open

fix(storybook): disable Vite publicDir to stop static copy race#6482
blunteshwar wants to merge 2 commits into
mainfrom
fix-flaky-docs-deployment

Conversation

@blunteshwar

Copy link
Copy Markdown
Contributor

Description

The 2nd-gen Build second-gen Storybook step (yarn workspace @adobe/spectrum-wc storybook:build) fails intermittently with:

Error: EEXIST: file already exists, mkdir
'./storybook-static/.well-known/agent-skills/spectrum-web-components/references/guides'
  at async mkDirAndCopy (node:internal/fs/cp/cp)

Root cause: storybook build copies public/ into storybook-static/ twice, concurrently:

  1. Storybook's own staticDirs: ['../public'] copy (copyAllStaticFilesRelativeToMain).
  2. Vite's default publicDir. builder-vite sets Vite root = resolve(configDir, '..') (the package dir) and never sets publicDir, so Vite defaults to <root>/public — the same folder.

Both copies run inside a single Promise.all([viteBuild, staticDirsCopy]). Node's cp recurses sequentially and issues a non-recursive await mkdir(dest) per directory, so when the two copiers reach the same nested directory the loser throws EEXIST. Timing-dependent, hence flaky. The large generated .well-known/agent-skills tree (yarn generate:skills, added in #6423) widened the collision window, which is why the failures started appearing.

The fix sets publicDir: false in viteFinal, so Storybook's staticDirs copy is the single writer of public/ and there is no second, racing copier.

Motivation and context

Intermittent red builds on the docs-deployment path (preview-docs.yml and publish-2ndgen-docs.yml, both of which call storybook:build) block unrelated PRs and force manual reruns. This removes the race at its source rather than papering over it with a retry.

Reproduction (two concurrent copies of public/ into one destination) throws EEXIST 40/40 on Node v24.11.1; a single copy never does.

Related issue(s)

  • No linked issue; surfaced by a failing preview-docs run.

Screenshots (if appropriate)

n/a — build configuration change, no visual output.

Author's checklist

  • I have read the CONTRIBUTING and PULL_REQUESTS documents.
  • I have reviewed the Accessibility Practices for this feature, see: Aria Practices
  • I have added automated tests to cover my changes. (Not applicable: this is a Storybook build-configuration flake with no unit-test surface. Verified with a full storybook:build run on Node 24.11.1, see below.)
  • I have included a well-written changeset if my change needs to be published. (Not applicable: .storybook/main.ts is build tooling and is not published.)
  • I have included updated documentation if my change required it. (Not applicable.)

Reviewer's checklist

  • Includes a Github Issue with appropriate flag or Jira ticket number without a link
  • Includes thoughtfully written changeset if changes suggested include patch, minor, or major features
  • Automated tests cover all use cases and follow best practices for writing
  • Validated on all supported browsers
  • All VRTs are approved before the author can update Golden Hash

Manual review test cases

  • 2nd-gen Storybook builds cleanly and serves generated statics

    1. Check out this branch and run yarn workspace @adobe/spectrum-wc storybook:build on Node 24.11.1.
    2. Confirm the build exits 0 with no EEXIST error.
    3. Confirm 2nd-gen/packages/swc/storybook-static/.well-known/agent-skills/index.json and .well-known/agent-skills/spectrum-web-components/references/guides/ exist in the output.
  • Dev server still serves statics

    1. Run yarn workspace @adobe/spectrum-wc storybook (dev).
    2. Open /.well-known/agent-skills/index.json and confirm it is served (dev statics come from middleware, not Vite's publicDir, so this path is unaffected).

Device review

  • Did it pass in Desktop?
  • Did it pass in (emulated) Mobile?
  • Did it pass in (emulated) iPad?

Accessibility testing checklist

This change only affects how Storybook copies static files during the build; it renders no component markup and changes no DOM.

  • Keyboard

    • No focusable parts are added or changed by this PR. Confirm there is no regression in the built Storybook: tab order and focus behavior of existing stories are unchanged.
  • Screen reader

    • No roles, names, or live regions are introduced or modified. Confirm the built docs site announces existing content as before (no new or duplicate announcements).

Verification

Verified locally on Node v24.11.1 (repo .nvmrc):

  • storybook:build completes with exit 0 and zero EEXIST errors.
  • storybook-static/index.html is present (preview build intact).
  • storybook-static/.well-known/agent-skills/…/references/guides/ is fully populated (statics still copied via staticDirs).

`storybook build` copied `public/` into `storybook-static/` twice
concurrently: once via Storybook's `staticDirs: ['../public']` and again
via Vite's default `publicDir` (builder-vite sets Vite `root` to the
package dir and never sets `publicDir`, so it defaults to `<root>/public`,
the same folder). Both copies run in one `Promise.all`, and node's `cp`
recurses with a non-recursive `mkdir(dest)` per directory, so the two
copiers race and the loser throws `EEXIST` on a nested dir (e.g.
`.well-known/agent-skills/.../guides`). The large generated agent-skills
tree widened the window, making the "Build second-gen Storybook" step
fail intermittently in preview-docs and publish-2ndgen-docs.

Set `publicDir: false` in `viteFinal` so Storybook's `staticDirs` copy is
the single writer. Dev serving is unaffected (statics are served via
middleware, not Vite's publicDir). Verified locally on Node 24.11.1:
build succeeds, no EEXIST, and `.well-known/agent-skills` is present in
the output.
@blunteshwar blunteshwar requested a review from a team as a code owner July 8, 2026 12:33
@changeset-bot

changeset-bot Bot commented Jul 8, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 0abb1b5

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

📚 Branch Preview Links

🔍 Gen1 Visual Regression Test Results

When a visual regression test fails (or has previously failed while working on this branch), its results can be found in the following URLs:

Deployed to Azure Blob Storage: pr-6482

If the changes are expected, update the current_golden_images_cache hash in the circleci config to accept the new images. Instructions are included in that file.
If the changes are unexpected, you can investigate the cause of the differences and update the code accordingly.

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.

1 participant