From 2833c96d515a4f555d615a64a8e32cbabb14688b Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Tue, 10 Mar 2026 11:25:35 +0100 Subject: [PATCH] fix(windows): stabilize Wine build and ship installer + portable exe - Run Wine as non-root with dedicated WINEPREFIX and tolerate winetricks vcrun2019 failures - Switch to Python embeddable + offline wheelhouse install for reproducible Windows packaging - Update PyInstaller flags to bundle coincurve cffi backend and bip_utils data files (HD wallet runtime fix) - Build both NSIS installer and portable executable; update build output messaging --- contrib/windows/Dockerfile | 73 +++++++++++++++++++++++++++++--------- contrib/windows/build.sh | 2 +- frontend/package.json | 2 +- 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/contrib/windows/Dockerfile b/contrib/windows/Dockerfile index ad3c4e0..b4d66aa 100644 --- a/contrib/windows/Dockerfile +++ b/contrib/windows/Dockerfile @@ -1,6 +1,6 @@ FROM node:22.14.0-bookworm -ENV WINEPREFIX=/root/.wine +ENV WINEPREFIX=/home/node/.wine ENV WINEDEBUG=-all # System dependencies + Wine + Xvfb @@ -8,7 +8,7 @@ RUN dpkg --add-architecture i386 && \ apt-get update && apt-get install -y --no-install-recommends \ wine wine32 wine64 \ python3 python3-pip python3-venv libpython3.11 \ - binutils wget xvfb xauth cabextract ca-certificates \ + binutils wget xvfb xauth cabextract ca-certificates unzip \ && rm -rf /var/lib/apt/lists/* # Install winetricks manually (removed from Debian bookworm apt) @@ -19,37 +19,78 @@ RUN wget -q https://raw.githubusercontent.com/Winetricks/winetricks/master/src/w WORKDIR /build # Copy repo -COPY . . +COPY --chown=node:node . . +RUN chown -R node:node /build + +# Wine/winetricks are unstable as root; use the image's non-root user. +USER node # Python venv (Linux, for local tools only) RUN python3 -m venv venv && \ - venv/bin/pip install --no-cache-dir -r requirements.txt + venv/bin/pip install --no-cache-dir -r requirements.txt pyinstaller + +# Pre-download Windows wheels so Wine Python can install fully offline. +RUN mkdir -p wheelhouse && \ + venv/bin/pip freeze > win-lock.txt && \ + printf "pip\nsetuptools\nwheel\n" >> win-lock.txt && \ + while read -r pkg; do \ + venv/bin/pip download \ + --dest wheelhouse \ + --platform win_amd64 --implementation cp --python-version 3.11 --abi cp311 \ + --no-deps "$pkg"; \ + done < win-lock.txt && \ + # PyInstaller has Windows-only deps not present in Linux freeze output. + for win_pkg in pefile pywin32-ctypes colorama; do \ + venv/bin/pip download \ + --dest wheelhouse \ + --platform win_amd64 --implementation cp --python-version 3.11 --abi cp311 \ + --no-deps "$win_pkg"; \ + done # Bootstrap Wine prefix RUN wineboot --init 2>/dev/null || true -# Install Visual C++ 2019 runtime (required by Python 3.11) -RUN xvfb-run winetricks -q vcrun2019 +# vcrun2019 currently returns status 243 on Wine 8 (Debian bookworm). +# Keep it best-effort so the build can proceed if Python installer already bundles needed runtime. +RUN xvfb-run -a winetricks -q vcrun2019 || true -# Install Python for Windows under Wine (silent, no GUI) -RUN wget -q "https://www.python.org/ftp/python/3.11.9/python-3.11.9-amd64.exe" -O /tmp/py.exe && \ - xvfb-run wine /tmp/py.exe /quiet InstallAllUsers=1 PrependPath=1 TargetDir="C:\\Python311" && \ - rm /tmp/py.exe +# Install Python for Windows using embeddable zip (avoids installer/runtime failures under Wine) +RUN mkdir -p "$WINEPREFIX/drive_c/Python311" && \ + wget -q "https://www.python.org/ftp/python/3.11.9/python-3.11.9-embed-amd64.zip" -O /tmp/pyembed.zip && \ + unzip -q /tmp/pyembed.zip -d "$WINEPREFIX/drive_c/Python311" && \ + rm /tmp/pyembed.zip && \ + sed -i 's/^#import site/import site/' "$WINEPREFIX/drive_c/Python311/python311._pth" && \ + wget -q "https://bootstrap.pypa.io/pip/pip.pyz" -O "$WINEPREFIX/drive_c/pip.pyz" && \ + xvfb-run -a wine "C:\\Python311\\python.exe" --version + +# Install Python packaging toolchain first (needed for sdist like crcmod). +RUN xvfb-run -a wine "C:\\Python311\\python.exe" "C:\\pip.pyz" install --no-index \ + --find-links="Z:\\build\\wheelhouse" \ + pip setuptools wheel # Install Python deps + PyInstaller under Wine Python -RUN xvfb-run wine "C:\\Python311\\python.exe" -m pip install --no-cache-dir -r requirements.txt pyinstaller +RUN xvfb-run -a wine "C:\\Python311\\python.exe" "C:\\pip.pyz" install --no-index --no-build-isolation \ + --find-links="Z:\\build\\wheelhouse" \ + -r "Z:\\build\\win-lock.txt" # Compile Python CLI into Windows binary -RUN xvfb-run wine "C:\\Python311\\python.exe" -m PyInstaller \ - --onefile --name cli src/cli.py && \ +RUN xvfb-run -a wine "C:\\Python311\\python.exe" -m PyInstaller \ + --onefile --name cli \ + --hidden-import _cffi_backend \ + --hidden-import coincurve._cffi_backend \ + --collect-data bip_utils \ + --collect-submodules coincurve \ + --collect-binaries coincurve \ + --collect-data coincurve \ + src/cli.py && \ mkdir -p frontend/resources && \ cp dist/cli.exe frontend/resources/cli.exe # JS dependencies + electron-builder RUN cd frontend && npm ci && npm install --no-save electron-builder -# Build Windows NSIS installer -RUN cd frontend && npx vite build && npx electron-builder --win nsis --publish never +# Build Windows installer + standalone portable executable +RUN cd frontend && npx vite build && npx electron-builder --win nsis portable --publish never -# Export installer +# Export build artifacts CMD cp frontend/release/*.exe /out/ diff --git a/contrib/windows/build.sh b/contrib/windows/build.sh index 26ffff9..deb7089 100755 --- a/contrib/windows/build.sh +++ b/contrib/windows/build.sh @@ -14,5 +14,5 @@ docker run --rm \ -v "$OUT_DIR:/out" \ wallet-gen-builder-win -echo "Installer saved to: $OUT_DIR" +echo "Windows artifacts saved to: $OUT_DIR" ls "$OUT_DIR"/*.exe diff --git a/frontend/package.json b/frontend/package.json index 1a22800..9580a9e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -27,7 +27,7 @@ "category": "Finance" }, "win": { - "target": "nsis" + "target": ["nsis", "portable"] } }, "dependencies": {