Skip to content

Fix app deploy including stale dist files in the extension bundle - #8236

Open
alfonso-noriega wants to merge 1 commit into
mainfrom
fix-stale-dist-files-in-deploy-bundle
Open

Fix app deploy including stale dist files in the extension bundle#8236
alfonso-noriega wants to merge 1 commit into
mainfrom
fix-stale-dist-files-in-deploy-bundle

Conversation

@alfonso-noriega

@alfonso-noriega alfonso-noriega commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

WHY are these changes introduced?

Related to #6069.

Since 3.94.0 (0986095), executeBundleUIStep builds the UI extension into the extension's local dist/ directory and then copies the whole directory into the deploy bundle. Any stale file sitting in dist/ (a script built under an old handle, a dev's own bundler output, old sourcemaps/metafiles) ships inside the module.

For web pixel extensions this is fatal: core's FetchScriptContent rejects modules whose uploaded files contain more than one .js, so appVersionCreate fails with a generic "Version couldn't be created" even though every prior step (build, GCS upload) succeeds. dist/ is gitignored, so reverting source changes doesn't clear it — which is why "the same source deployed fine before and now fails".

Root cause analysis in this Slack thread. Server-side error message improvement in https://github.com/shop/world/pull/967972.

WHAT is this pull request doing?

  • bundle-ui-step.ts: instead of copying the entire local output directory, copy only the artifacts produced by the build — <output-name>.* for the main entry and each extra asset (which also covers their sourcemaps and .metafile.json). Stale files next to the built ones no longer ship.
  • Adds two tests: a stale .js in the local dist/ is excluded from the bundle; extra built assets (e.g. -conditions.js) are still copied.

How to test your changes?

  1. Create an app with a web pixel extension and deploy it once.
  2. Rename the extension handle in shopify.extension.toml (leaving the old extensions/<pixel>/dist/<old-handle>.js in place) and run shopify app deploy.
  3. Without this fix, appVersionCreate fails ("Version couldn't be created"); with it, only the freshly built script is included and the deploy succeeds.

Checklist

  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've considered possible documentation changes
  • I've considered analytics changes to measure impact
  • The change is user-facing — I've identified the correct bump type (patch for bug fixes · minor for new features · major for breaking changes) and added a changeset with pnpm changeset add

…ist files

Assisted-By: devx/5fc43aa0-53a8-47e0-94e5-0f1620777a6c
@alfonso-noriega
alfonso-noriega requested a review from a team as a code owner August 3, 2026 08:24
@github-actions github-actions Bot added the Area: @shopify/app @shopify/app package issues label Aug 3, 2026
@isaacroldan

Copy link
Copy Markdown
Contributor

The fix restores the pre-3.94 contract (only build artifacts reach the bundle), but two risks with the glob approach:

  1. The glob can drift from what esbuild actually emits. Today outfile with no splitting/file loaders means every output is named <entry-name>.*, so the enumeration is complete. If we ever enable code splitting, a file loader, or CSS extraction, those outputs silently disappear from the bundle and the extension breaks at runtime. The tests mock buildUIExtension, so nothing would catch it.

  2. The glob is prefix-loose. handle.* also matches stale files like handle.old.js, which would still ship and still fail a web pixel deploy.

Recommendation: copy the exact file list from esbuild's build result instead of globbing — bundleExtension already generates a metafile in production, and result.metafile.outputs lists every file written. Same cost, and both risks go away.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: @shopify/app @shopify/app package issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants