diff --git a/config/electron-builder.config.cjs b/config/electron-builder.config.cjs index 4b1e1c36653..11e8df74bb9 100644 --- a/config/electron-builder.config.cjs +++ b/config/electron-builder.config.cjs @@ -264,6 +264,8 @@ module.exports = { '!out/runtimes{,/**/*}', '!out/node-runtime-cache{,/**/*}', '!config{,/**/*}', + // Cloud services deploy separately; their sources are not desktop runtime resources. + '!cloud{,/**/*}', // Release archives and other build staging are not runtime resources. '!.build{,/**/*}', // Worktree-local Vite dependency caches are development inputs. diff --git a/config/scripts/electron-builder-config.test.mjs b/config/scripts/electron-builder-config.test.mjs index 37ae87b21ed..d7a6e0235a3 100644 --- a/config/scripts/electron-builder-config.test.mjs +++ b/config/scripts/electron-builder-config.test.mjs @@ -26,6 +26,7 @@ describe('electron-builder config', () => { expect.arrayContaining([ '!src{,/**/*}', '!config{,/**/*}', + '!cloud{,/**/*}', '!docs{,/**/*}', '!mobile{,/**/*}', '!native{,/**/*}', diff --git a/config/scripts/packaged-cloud-source-exclusion.test.mjs b/config/scripts/packaged-cloud-source-exclusion.test.mjs new file mode 100644 index 00000000000..53e3fe8dd09 --- /dev/null +++ b/config/scripts/packaged-cloud-source-exclusion.test.mjs @@ -0,0 +1,53 @@ +import { existsSync } from 'node:fs' +import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises' +import { createRequire } from 'node:module' +import { tmpdir } from 'node:os' +import { dirname, join } from 'node:path' +import { describe, expect, it } from 'vitest' + +const require = createRequire(import.meta.url) +const electronBuilderConfig = require('../electron-builder.config.cjs') +const { copyFiles, FileMatcher } = require('app-builder-lib/out/fileMatcher') + +describe('packaged cloud source exclusion', () => { + it('omits cloud service sources during traversal while preserving compiled cloud clients', async () => { + const root = await mkdtemp(join(tmpdir(), 'orca-packaging-cloud-')) + const source = join(root, 'app') + const destination = join(root, 'selected') + const cloudPaths = [ + 'cloud/apps/relay/src/index.ts', + 'cloud/apps/push/src/app.test.ts', + 'cloud/infra/main.tf', + 'cloud/dev/scripts/deploy.mjs', + 'cloud/.env', + 'cloud/packages/push-contract/src/push-host-proof-vector.json' + ] + const runtimePaths = [ + 'package.json', + 'out/main/index.js', + 'out/cli/index.js', + 'out/main/runtime/mobile-cloud-relay/index.js', + 'out/main/runtime/push/push-host-proof.js', + 'out/shared/mobile-push-contract.js', + 'out/renderer/index.html', + 'out/web/assets/cloud/client.js', + 'resources/cloud/icon.png' + ] + try { + for (const fixturePath of [...cloudPaths, ...runtimePaths]) { + const file = join(source, fixturePath) + await mkdir(dirname(file), { recursive: true }) + await writeFile(file, fixturePath) + } + await copyFiles([ + new FileMatcher(source, destination, (value) => value, electronBuilderConfig.files) + ]) + expect(existsSync(join(destination, 'cloud'))).toBe(false) + for (const runtimePath of runtimePaths) { + expect(await readFile(join(destination, runtimePath), 'utf8')).toBe(runtimePath) + } + } finally { + await rm(root, { recursive: true, force: true }) + } + }) +}) diff --git a/config/scripts/pr-package-test-paths.mjs b/config/scripts/pr-package-test-paths.mjs index 05cdc5a7e31..fb5e11da5da 100644 --- a/config/scripts/pr-package-test-paths.mjs +++ b/config/scripts/pr-package-test-paths.mjs @@ -1,4 +1,5 @@ export const LINUX_PACKAGE_TESTS = [ + 'config/scripts/packaged-cloud-source-exclusion.test.mjs', 'src/main/browser/popup-origin-chrome.electron.test.ts', 'src/main/browser/browser-link-materialization.electron.test.ts', 'src/main/browser/browser-client-page-renderer-lifecycle.electron.test.ts',