From 301b7ef0aeb5765510fa24085a05e7599ef5582f Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Tue, 10 Mar 2026 09:24:35 +0100 Subject: [PATCH] feat: add Docker build for Windows NSIS installer via Wine - contrib/windows/Dockerfile: cross-compile using Wine + xvfb; installs Python 3.11 for Windows, builds cli.exe with PyInstaller, packages Electron app as NSIS installer - contrib/windows/build.sh: convenience script to run the Docker build - frontend/electron/main.cjs: resolve cli.exe on win32, cli on other platforms - frontend/package.json: add win/nsis target; change extraResources to bundle resources/ dir so each platform picks its own binary --- contrib/windows/Dockerfile | 47 ++++++++++++++++++++++++++++++++++++++ contrib/windows/build.sh | 18 +++++++++++++++ frontend/electron/main.cjs | 3 ++- frontend/package.json | 5 +++- 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 contrib/windows/Dockerfile create mode 100755 contrib/windows/build.sh diff --git a/contrib/windows/Dockerfile b/contrib/windows/Dockerfile new file mode 100644 index 0000000..f2c36e1 --- /dev/null +++ b/contrib/windows/Dockerfile @@ -0,0 +1,47 @@ +FROM node:22.14.0-bookworm + +ENV WINEPREFIX=/root/.wine +ENV WINEDEBUG=-all + +# System dependencies + Wine + Xvfb +RUN dpkg --add-architecture i386 && \ + apt-get update && apt-get install -y --no-install-recommends \ + wine wine64 \ + python3 python3-pip python3-venv libpython3.11 \ + binutils wget xvfb ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /build + +# Copy repo +COPY . . + +# Python venv (Linux, for local tools only) +RUN python3 -m venv venv && \ + venv/bin/pip install --no-cache-dir -r requirements.txt + +# Bootstrap Wine prefix +RUN wineboot --init 2>/dev/null || 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 deps + PyInstaller under Wine Python +RUN xvfb-run wine "C:\\Python311\\python.exe" -m pip install --no-cache-dir -r requirements.txt pyinstaller + +# Compile Python CLI into Windows binary +RUN xvfb-run wine "C:\\Python311\\python.exe" -m PyInstaller \ + --onefile --name cli 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 + +# Export installer +CMD cp frontend/release/*.exe /out/ diff --git a/contrib/windows/build.sh b/contrib/windows/build.sh new file mode 100755 index 0000000..26ffff9 --- /dev/null +++ b/contrib/windows/build.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -euo pipefail + +REPO_ROOT=$(cd "$(dirname "$0")/../.." && pwd) +OUT_DIR="$REPO_ROOT/release" + +mkdir -p "$OUT_DIR" + +docker build -t wallet-gen-builder-win \ + -f "$REPO_ROOT/contrib/windows/Dockerfile" \ + "$REPO_ROOT" + +docker run --rm \ + -v "$OUT_DIR:/out" \ + wallet-gen-builder-win + +echo "Installer saved to: $OUT_DIR" +ls "$OUT_DIR"/*.exe diff --git a/frontend/electron/main.cjs b/frontend/electron/main.cjs index 86a1902..8f492f2 100644 --- a/frontend/electron/main.cjs +++ b/frontend/electron/main.cjs @@ -51,7 +51,8 @@ function resolveWalletFile(kind, filename) { // ── Resolve CLI command (dev: python + cli.py, prod: bundled binary) ────────── function getCliCommand() { if (!isDev) { - const bundled = path.join(process.resourcesPath, 'cli') + const cliName = process.platform === 'win32' ? 'cli.exe' : 'cli' + const bundled = path.join(process.resourcesPath, cliName) if (fs.existsSync(bundled)) return { exec: bundled, baseArgs: [] } } const repoRoot = path.join(__dirname, '..', '..') diff --git a/frontend/package.json b/frontend/package.json index 7ff4bbe..1a22800 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,7 +17,7 @@ "icon": "public/icons/icon.png", "files": ["dist/**", "electron/**"], "extraResources": [ - { "from": "resources/cli", "to": "cli" } + { "from": "resources", "to": "." } ], "directories": { "output": "release" @@ -25,6 +25,9 @@ "linux": { "target": "AppImage", "category": "Finance" + }, + "win": { + "target": "nsis" } }, "dependencies": {