diff --git a/packages/app/src/cli/services/deploy/bundle.test.ts b/packages/app/src/cli/services/deploy/bundle.test.ts index e30d3e091fc..78aa958d5fa 100644 --- a/packages/app/src/cli/services/deploy/bundle.test.ts +++ b/packages/app/src/cli/services/deploy/bundle.test.ts @@ -256,7 +256,7 @@ describe('bundleAndBuildExtensions', () => { }) }) - test('runs web build command concurrently with extensions when build command is defined', async () => { + test('runs web build before extensions when build command is defined', async () => { await file.inTemporaryDirectory(async (tmpDir: string) => { // Given const bundlePath = joinPath(tmpDir, 'bundle.zip') diff --git a/packages/app/src/cli/services/deploy/bundle.ts b/packages/app/src/cli/services/deploy/bundle.ts index 5811ff368a9..c071d12e1b0 100644 --- a/packages/app/src/cli/services/deploy/bundle.ts +++ b/packages/app/src/cli/services/deploy/bundle.ts @@ -68,8 +68,16 @@ export async function bundleAndBuildExtensions(options: BundleOptions) { }, })) + // Web builds must complete before extension builds start. Extensions like + // the admin module copy output from web builds (e.g. dist/) into the bundle + // via include_assets. Running them in parallel causes a race condition where + // dist/ is empty or missing when the admin extension tries to copy it. + if (webBuildProcesses.length > 0) { + await renderConcurrent({processes: webBuildProcesses, showTimestamps: false}) + } + await renderConcurrent({ - processes: [webBuildProcesses, extensionBuildProcesses].flat(), + processes: extensionBuildProcesses, showTimestamps: false, })