From 4850be0838b0e8166f0e56a3ff5d76ae4b950364 Mon Sep 17 00:00:00 2001 From: Sparsh Date: Mon, 11 May 2026 21:44:18 +0530 Subject: [PATCH] feat(build): implement afterPack hook to copy node.exe for Windows builds --- gitnexus-desktop/electron-builder.yml | 4 +--- gitnexus-desktop/scripts/after-pack.mjs | 21 +++++++++++++++++++++ gitnexus-desktop/scripts/package.mjs | 16 ++++++++++------ 3 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 gitnexus-desktop/scripts/after-pack.mjs diff --git a/gitnexus-desktop/electron-builder.yml b/gitnexus-desktop/electron-builder.yml index e649cadfd..6400790a0 100644 --- a/gitnexus-desktop/electron-builder.yml +++ b/gitnexus-desktop/electron-builder.yml @@ -34,14 +34,12 @@ extraResources: to: gitnexus/package.json asar: false npmRebuild: false +afterPack: scripts/after-pack.mjs win: signAndEditExecutable: false icon: build/icon.png target: - nsis - extraResources: - - from: '${env.GITNEXUS_DESKTOP_NODE_BINARY}' - to: runtime/node.exe mac: category: public.app-category.developer-tools icon: build/icon.png diff --git a/gitnexus-desktop/scripts/after-pack.mjs b/gitnexus-desktop/scripts/after-pack.mjs new file mode 100644 index 000000000..04cded19b --- /dev/null +++ b/gitnexus-desktop/scripts/after-pack.mjs @@ -0,0 +1,21 @@ +import { copyFileSync, mkdirSync } from 'node:fs'; +import path from 'node:path'; + +/** + * afterPack hook — runs after electron-builder assembles the app directory, + * before any installer (NSIS, DMG, AppImage) is sealed. + * + * On Windows, lbugjs.node PE-imports "node.exe" by name. Electron's binary + * is not named node.exe, so LoadLibrary fails. We copy the real node.exe into + * resources/runtime/node.exe so main.ts can use it as the subprocess host. + * This fires for both --dir and --win builds, fixing the smoke test and installer. + */ +export default async function afterPack(context) { + if (context.electronPlatformName !== 'win32') return; + + const runtimeDir = path.join(context.appOutDir, 'resources', 'runtime'); + mkdirSync(runtimeDir, { recursive: true }); + copyFileSync(process.execPath, path.join(runtimeDir, 'node.exe')); + + console.log(`[after-pack] Copied node.exe → ${path.join(runtimeDir, 'node.exe')}`); +} diff --git a/gitnexus-desktop/scripts/package.mjs b/gitnexus-desktop/scripts/package.mjs index 6205511e2..8fcc82067 100644 --- a/gitnexus-desktop/scripts/package.mjs +++ b/gitnexus-desktop/scripts/package.mjs @@ -155,12 +155,6 @@ const builderEnvironment = { GITNEXUS_DESKTOP_GITNEXUS_SKILLS: toBuilderRelativePath(path.join(gitnexusRoot, 'skills')), GITNEXUS_DESKTOP_GITNEXUS_VENDOR: toBuilderRelativePath(path.join(gitnexusRoot, 'vendor')), GITNEXUS_DESKTOP_WEB_DIST: toBuilderRelativePath(path.join(gitnexusWebRoot, 'dist')), - // On Windows, lbugjs.node PE-imports node.exe by name, which fails under Electron's binary. - // electron-builder copies this into resources/runtime/node.exe so it lands in both - // win-unpacked (smoke test) and the NSIS installer (end-user install). - // The extraResources entry in electron-builder.yml is platform: [win] so this value is - // ignored on macOS/Linux (empty string prevents electron-builder from touching it there). - GITNEXUS_DESKTOP_NODE_BINARY: process.platform === 'win32' ? process.execPath : '', }; const builderCliArgs = [ @@ -436,6 +430,16 @@ runCommand(process.execPath, ['scripts/ensure-gitnexus-runtime.mjs'], packageRoo runCommand(npmCommand, ['run', 'bundle'], packageRoot); +const gitnexusSharedRoot = path.join(workspaceRoot, 'gitnexus-shared'); +if (!fs.existsSync(path.join(gitnexusSharedRoot, 'dist'))) { + if (!fs.existsSync(path.join(gitnexusSharedRoot, 'node_modules'))) { + runCommand(npmCommand, ['ci'], gitnexusSharedRoot); + } + runCommand(npmCommand, ['run', 'build'], gitnexusSharedRoot); +} +if (!fs.existsSync(path.join(gitnexusWebRoot, 'node_modules'))) { + runCommand(npmCommand, ['ci'], gitnexusWebRoot); +} runCommand(npmCommand, ['run', 'build'], gitnexusWebRoot); runCommand(process.execPath, builderCliArgs, packageRoot, builderEnvironment);