diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c001be981c10..f579bfa8a5a8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10438,10 +10438,6 @@ packages: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} - tough-cookie@6.0.1: - resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} - engines: {node: '>=16'} - tough-cookie@6.0.2: resolution: {integrity: sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==} engines: {node: '>=16'} @@ -18908,7 +18904,7 @@ snapshots: decimal.js: 10.6.0 html-encoding-sniffer: 6.0.0(@noble/hashes@1.8.0) is-potential-custom-element-name: 1.0.1 - lru-cache: 11.5.2 + lru-cache: 11.5.3 parse5: 8.0.1 saxes: 6.0.0 tough-cookie: 6.0.2 @@ -20013,7 +20009,7 @@ snapshots: rettime: 0.10.1 statuses: 2.0.2 strict-event-emitter: 0.5.1 - tough-cookie: 6.0.1 + tough-cookie: 6.0.2 type-fest: 5.7.0 until-async: 3.0.2 yargs: 17.7.2 @@ -20039,7 +20035,7 @@ snapshots: rettime: 0.10.1 statuses: 2.0.2 strict-event-emitter: 0.5.1 - tough-cookie: 6.0.1 + tough-cookie: 6.0.2 type-fest: 5.7.0 until-async: 3.0.2 yargs: 17.7.2 @@ -20516,7 +20512,7 @@ snapshots: path-scurry@2.0.2: dependencies: - lru-cache: 11.5.2 + lru-cache: 11.5.3 minipass: 7.1.3 path-to-regexp@6.1.0: {} @@ -21953,11 +21949,6 @@ snapshots: totalist@3.0.1: {} - tough-cookie@6.0.1: - dependencies: - tldts: 7.4.2 - optional: true - tough-cookie@6.0.2: dependencies: tldts: 7.4.2 diff --git a/scripts/build-desktop-artifact.test.ts b/scripts/build-desktop-artifact.test.ts index 4e97301ddba8..98ba0aaefbc8 100644 --- a/scripts/build-desktop-artifact.test.ts +++ b/scripts/build-desktop-artifact.test.ts @@ -175,6 +175,8 @@ const makeWindowsPayloadFixture = Effect.fn("test.makeWindowsPayloadFixture")(fu readonly copyUnpackedNatives: boolean; readonly serverEntrySource?: string; readonly wslRuntime?: "valid" | "loose-server-tree" | "missing-pty" | "bad-digest"; + readonly targetArch?: "x64" | "arm64"; + readonly ptyPrebuildArch?: "x64" | "arm64"; }) { const fs = yield* FileSystem.FileSystem; const path = yield* Path.Path; @@ -212,7 +214,7 @@ const makeWindowsPayloadFixture = Effect.fn("test.makeWindowsPayloadFixture")(fu yield* fs.writeFileString(path.join(packagedAppDir, "chrome_crashpad_handler.exe"), "crashpad"); if (input.wslRuntime !== undefined) { - const stem = wslRuntimeArchiveStem(WINDOWS_PAYLOAD_FIXTURE_VERSION, "x64"); + const stem = wslRuntimeArchiveStem(WINDOWS_PAYLOAD_FIXTURE_VERSION, input.targetArch ?? "x64"); const sourceArchivePath = input.wslRuntime === "loose-server-tree" ? // The old hand-rolled runtime: apps/server/dist + node_modules at the @@ -226,9 +228,16 @@ const makeWindowsPayloadFixture = Effect.fn("test.makeWindowsPayloadFixture")(fu : yield* makeLinuxCliArchiveFixture({ root: path.join(tempDir, "wsl-runtime"), stem, - ...(input.wslRuntime === "missing-pty" + ...(input.wslRuntime === "missing-pty" || input.ptyPrebuildArch !== undefined ? { omitMembers: [`${stem}/node_modules/node-pty/build/Release/pty.node`] } : {}), + ...(input.ptyPrebuildArch !== undefined + ? { + extraMembers: [ + `${stem}/node_modules/node-pty/prebuilds/linux-${input.ptyPrebuildArch}/pty.node`, + ], + } + : {}), }); const archivePath = path.join(resourcesDir, WSL_RUNTIME_ARCHIVE_NAME); const hashPath = path.join(resourcesDir, WSL_RUNTIME_ARCHIVE_HASH_NAME); @@ -1206,6 +1215,55 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => { ).pipe(Effect.provideService(HostProcessPlatform, "linux")), ); + for (const targetArch of ["x64", "arm64"] as const) { + it.effect(`accepts an embedded archive with the Linux ${targetArch} node-pty prebuild`, () => + Effect.scoped( + Effect.gen(function* () { + const fixture = yield* makeWindowsPayloadFixture({ + copyUnpackedNatives: true, + wslRuntime: "valid", + targetArch, + ptyPrebuildArch: targetArch, + }); + const result = yield* validateWindowsPackagedPayload({ + stageDistDir: fixture.stageDistDir, + appExecutableName: fixture.appExecutableName, + targetArch, + appVersion: WINDOWS_PAYLOAD_FIXTURE_VERSION, + expectWslRuntime: true, + }); + + assert.equal(result.packagedAppDir, fixture.packagedAppDir); + }), + ).pipe(Effect.provideService(HostProcessPlatform, "linux")), + ); + + it.effect( + `rejects a node-pty prebuild for the wrong architecture in a Linux ${targetArch} archive`, + () => + Effect.scoped( + Effect.gen(function* () { + const fixture = yield* makeWindowsPayloadFixture({ + copyUnpackedNatives: true, + wslRuntime: "valid", + targetArch, + ptyPrebuildArch: targetArch === "x64" ? "arm64" : "x64", + }); + const error = yield* validateWindowsPackagedPayload({ + stageDistDir: fixture.stageDistDir, + appExecutableName: fixture.appExecutableName, + targetArch, + appVersion: WINDOWS_PAYLOAD_FIXTURE_VERSION, + expectWslRuntime: true, + }).pipe(Effect.flip); + + assert.instanceOf(error, WindowsPackagedPayloadValidationError); + assert.equal(error.reason, "wsl-runtime-invalid"); + }), + ), + ); + } + it.effect("rejects an embedded archive built for a different release version", () => Effect.scoped( Effect.gen(function* () { @@ -1285,6 +1343,7 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => { assert.equal(error.reason, "wsl-runtime-invalid"); assert.deepStrictEqual(error.missingFiles, [ `${wslRuntimeArchiveStem(WINDOWS_PAYLOAD_FIXTURE_VERSION, "x64")}/node_modules/node-pty/build/Release/pty.node`, + `${wslRuntimeArchiveStem(WINDOWS_PAYLOAD_FIXTURE_VERSION, "x64")}/node_modules/node-pty/prebuilds/linux-x64/pty.node`, ]); }), ), diff --git a/scripts/build-desktop-artifact.ts b/scripts/build-desktop-artifact.ts index d2d9df767946..5b22fddbb39a 100644 --- a/scripts/build-desktop-artifact.ts +++ b/scripts/build-desktop-artifact.ts @@ -3291,13 +3291,16 @@ export const validateWindowsPackagedPayload = Effect.fn( ), ); } - const requiredMembers = [ - `${stem}/t3`, - `${stem}/client`, - `${stem}/node_modules`, + const requiredMembers = [`${stem}/t3`, `${stem}/client`, `${stem}/node_modules`]; + const missingMembers = requiredMembers.filter((member) => !members.includes(member)); + // node-pty can load a source build or the prebuild for the WSL target. + const ptyCandidates = [ `${stem}/node_modules/node-pty/build/Release/pty.node`, + `${stem}/node_modules/node-pty/prebuilds/linux-${input.targetArch}/pty.node`, ]; - const missingMembers = requiredMembers.filter((member) => !members.includes(member)); + if (!ptyCandidates.some((member) => members.includes(member))) { + missingMembers.push(...ptyCandidates); + } if (missingMembers.length > 0) { return yield* new WindowsPackagedPayloadValidationError({ reason: "wsl-runtime-invalid",