From 6400598212aa7cb51fcff39b5db2d77123b6983b Mon Sep 17 00:00:00 2001 From: Neil Date: Tue, 8 Sep 2026 01:20:58 -0700 Subject: [PATCH] fix(release): prune optional natives before the linux arch floor check The linux-arm64 release build failed packaging, and retried three times: [verify-linux-glibc-floor] 1 bundled native binary is built for the wrong architecture (target arm64): resources/node_modules/@parcel/watcher-linux-x64-glibc/watcher.node is x64, expected arm64 (from its own path) `afterPack` ran `verifyLinuxGlibcFloor` at its top, before `prunePackagedRuntimeNodeModules`. A cross-build intentionally installs every optional native variant, so at that point the arm64 slice still carries the x64 `@parcel/watcher` package that the prune exists to drop. The check was reading a file that was never going to ship. Move the floor check below the prune so it inspects the binaries actually packed. Same ordering as 35f1b0ebb91 on the v1.4.197 release branch, which shipped green and was never merged back to main. --- config/electron-builder.config.cjs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/config/electron-builder.config.cjs b/config/electron-builder.config.cjs index 7e0009b3a24..6b36938a3d1 100644 --- a/config/electron-builder.config.cjs +++ b/config/electron-builder.config.cjs @@ -279,16 +279,6 @@ module.exports = { } }, afterPack: async (context) => { - // Why: a Linux runner-image glibc bump silently shipped a node-pty pty.node - // requiring GLIBC_2.34, crashing the app on startup on Ubuntu 20.04 (#9902). - // Fail packaging if any bundled native binary exceeds the supported floor. - if (context.electronPlatformName === 'linux') { - // Why the arch is passed: symbol-version checks pass happily on a wrong-architecture binary, - // so a cross-built slice could ship the host's pty.node and only fail at runtime. - verifyLinuxGlibcFloor(context.appOutDir, { - targetArch: { 1: 'x64', 3: 'arm64' }[context.arch] - }) - } const resourcesDir = context.electronPlatformName === 'darwin' ? join( @@ -326,6 +316,19 @@ module.exports = { } stampPackagedCliVersion(resourcesDir, context.packager.appInfo.version) prunePackagedRuntimeNodeModules(resourcesDir, context.electronPlatformName, context.arch) + // Why: a Linux runner-image glibc bump silently shipped a node-pty pty.node + // requiring GLIBC_2.34, crashing the app on startup on Ubuntu 20.04 (#9902). + // Fail packaging if any bundled native binary exceeds the supported floor. + // Why after the prune: cross-builds intentionally install every optional + // native variant, so an arm64 slice still carries the x64 @parcel/watcher + // until prunePackagedRuntimeNodeModules drops it. + if (context.electronPlatformName === 'linux') { + // Why the arch is passed: symbol-version checks pass happily on a wrong-architecture binary, + // so a cross-built slice could ship the host's pty.node and only fail at runtime. + verifyLinuxGlibcFloor(context.appOutDir, { + targetArch: { 1: 'x64', 3: 'arm64' }[context.arch] + }) + } verifyPackagedMainRuntimeDeps(resourcesDir) // Why: boot the packaged daemon-entry under plain Node, but only for the // slice matching the packaging host's arch — daemon-entry.js is JS, yet it