Skip to content

Commit 397d638

Browse files
authored
Merge pull request #7388 from Shopify/vchu/fix-bundle-ui-step-path-normalization
Normalize paths in bundle-ui-step same-path guard
2 parents ff230db + 35deef9 commit 397d638

3 files changed

Lines changed: 16 additions & 2 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@shopify/app': patch
3+
---
4+
5+
Fix `shopify app build` intermittently failing with "Source and destination must not be the same" on UI extensions when the local esbuild output directory and the bundle output directory resolve to the same path but differ as strings (e.g. due to `.` segments, trailing slashes, or path joining quirks). The same-path guard now normalizes both paths via `resolvePath` before comparison.

packages/app/src/cli/services/build/steps/bundle-ui-step.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,13 @@ describe('executeBundleUIStep', () => {
5757
// Then
5858
expect(fs.copyFile).toHaveBeenCalledWith('/test/extension/dist', '/bundle/handle')
5959
})
60+
61+
test('skips the copy when local and bundle output directories resolve to the same path but differ as strings', async () => {
62+
mockContext.extension.outputPath = '/test/./extension/dist/handle.js'
63+
vi.mocked(buildExtension.buildUIExtension).mockResolvedValue('/test/extension/dist/handle.js')
64+
65+
await executeBundleUIStep(step, mockContext)
66+
67+
expect(fs.copyFile).not.toHaveBeenCalled()
68+
})
6069
})

packages/app/src/cli/services/build/steps/bundle-ui-step.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {createOrUpdateManifestFile} from './include-assets/generate-manifest.js'
22
import {buildUIExtension} from '../extension.js'
33
import {BuildManifest} from '../../../models/extensions/specifications/ui_extension.js'
44
import {copyFile} from '@shopify/cli-kit/node/fs'
5-
import {dirname, joinPath} from '@shopify/cli-kit/node/path'
5+
import {dirname, joinPath, resolvePath} from '@shopify/cli-kit/node/path'
66
import type {BundleUIStep, BuildContext} from '../client-steps.js'
77

88
interface ExtensionPointWithBuildManifest {
@@ -27,7 +27,7 @@ export async function executeBundleUIStep(step: BundleUIStep, context: BuildCont
2727
const bundleOutputDir = step.config?.bundleFolder
2828
? joinPath(dirname(context.extension.outputPath), step.config.bundleFolder)
2929
: dirname(context.extension.outputPath)
30-
if (localOutputDir !== bundleOutputDir) {
30+
if (resolvePath(localOutputDir) !== resolvePath(bundleOutputDir)) {
3131
await copyFile(localOutputDir, bundleOutputDir)
3232
}
3333

0 commit comments

Comments
 (0)