From 53998071299555cadc3972d3195e494d3537cc12 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 31 Oct 2026 21:55:23 +0000 Subject: [PATCH] fix(release): build the Windows zip at normal compression The top-level `compression: maximum` makes electron-builder build a zip with 15-pass Deflate (-mx=9 -mfb=258 -mpass=15). On the x64 CUDA libraries that ran the v5.1.0 Windows release job past its 45-minute limit while it was still writing the zip. Setting win.compression to normal builds the zip at -mx=7; the NSIS app archive is 7z at -mx=9 either way, so the installer is unchanged. release.yml applies the same setting at build time for tags cut before this change (v5.1.0) and is a no-op after it. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Q5Uo5hC58DRSh1qB489Sos --- .github/workflows/release.yml | 23 +++++++++++++++++++++++ electron-builder.json | 1 + test/electron-builder-config.test.js | 21 +++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ce23258..510f842 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -175,6 +175,29 @@ jobs: if: steps.windows-release-mode.outputs.signed == 'true' run: node scripts/configure-win-signing.js electron-builder.json + - name: Keep the Windows zip off maximum compression + # At the top-level `compression: maximum`, electron-builder builds the zip + # with 15-pass Deflate, which outlasts this job's timeout on the x64 CUDA + # libraries. electron-builder.json now sets win.compression to normal; + # this applies the same setting to tags cut before it did (v5.1.0) and is + # a no-op afterwards. The NSIS app archive uses the same 7z settings + # either way, and only the x64 leg builds the zip. + if: matrix.arch == 'x64' + shell: bash + run: | + node -e ' + const fs = require("fs"); + const file = "electron-builder.json"; + const config = JSON.parse(fs.readFileSync(file, "utf8")); + if (config.win.compression === undefined) { + config.win.compression = "normal"; + fs.writeFileSync(file, JSON.stringify(config, null, 2) + "\n"); + console.log("Set win.compression to normal for this build."); + } else { + console.log("win.compression is already " + config.win.compression + "."); + } + ' + - name: Clean release output directory shell: pwsh run: | diff --git a/electron-builder.json b/electron-builder.json index ced8862..dc28417 100644 --- a/electron-builder.json +++ b/electron-builder.json @@ -88,6 +88,7 @@ "win": { "icon": "assets/icons/win/icon.ico", "target": ["nsis", "zip"], + "compression": "normal", "files": [ "!**/node_modules/better-sqlite3/prebuilds/!(win32-${arch}).node", "!**/node_modules/@node-llama-cpp/win-!(${arch}|${arch}-*)/**" diff --git a/test/electron-builder-config.test.js b/test/electron-builder-config.test.js index a42137e..7ea89c8 100644 --- a/test/electron-builder-config.test.js +++ b/test/electron-builder-config.test.js @@ -47,6 +47,27 @@ describe('electron-builder.json Windows targets', () => { }); }); +// The top-level `compression: maximum` turns a zip into 15-pass Deflate +// (-mfb=258 -mpass=15), which ran the x64 release job past its 45-minute limit +// on the CUDA libraries. win.compression overrides it for both Windows targets. +describe('electron-builder.json Windows compression', () => { + const { compute7zCompressArgs } = require('app-builder-lib/out/targets/archive'); + const winCompression = builderConfig.win.compression; + + test('the Windows zip is not built with 15-pass Deflate', () => { + expect(winCompression).toBe('normal'); + expect(compute7zCompressArgs('zip', { compression: winCompression })).not.toContain( + '-mpass=15' + ); + }); + + test('the NSIS app archive keeps the 7z settings it had at maximum', () => { + expect(compute7zCompressArgs('7z', { compression: winCompression })).toEqual( + compute7zCompressArgs('7z', { compression: 'maximum' }) + ); + }); +}); + // Runs app-builder-lib's own node_modules filter (the one NodeModuleCopyHelper // applies while copying dependencies) against the committed `files` patterns. describe('electron-builder.json node_modules exclusions', () => {