From 0bb098438a5a9a3864d270c77516cc9b41979e47 Mon Sep 17 00:00:00 2001 From: Bernd Rodler Date: Tue, 4 Aug 2026 12:58:41 +0200 Subject: [PATCH] ci(electron): GitHub Actions matrix build - mac/win/linux, unsigned Phase 1 step 8 of VNCprodbuild. New workflow, additive to the existing docker-publish*.yml/standalone-release.yml (which only ever built the Docker image / standalone tarball, never the desktop shell). Matrix over macos-latest/windows-latest/ubuntu-latest. Each leg: npm ci, build:standalone, build:electron, then npm run test:electron (the Phase 1 step 2 smoke test) as a REQUIRED gate before packaging or any artifact-upload step - a platform-specific regression fails the leg it breaks instead of slipping through because only one OS was ever smoke-tested. Linux needs an explicit Xvfb install first (no display server on that runner by default); macOS/Windows runners have one. Triggers on release-published (packages + publishes to that release via electron-builder's --publish always, matching standalone-release.yml's `gh release upload` precedent but through electron-builder's own GitHub publish provider) and workflow_dispatch (packages only, uploads a build artifact instead, --publish never). Ships unsigned - CSC_IDENTITY_AUTO_DISCOVERY: "false" stops electron-builder from probing for a macOS identity that doesn't exist (VNCprodbuild step 9: no Apple Developer ID or Windows cert yet, both human-owned purchases). Structured so signing needs no rewrite later - just add CSC_LINK/ CSC_KEY_PASSWORD (macOS) and/or WIN_CSC_LINK/WIN_CSC_KEY_PASSWORD (Windows) as repo secrets once those exist. --- .github/workflows/electron-build.yml | 89 ++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 .github/workflows/electron-build.yml diff --git a/.github/workflows/electron-build.yml b/.github/workflows/electron-build.yml new file mode 100644 index 00000000..b800a718 --- /dev/null +++ b/.github/workflows/electron-build.yml @@ -0,0 +1,89 @@ +name: Build Electron Desktop App + +# Phase 1 of the VNCprodbuild rollout (~/.claude/skills/VNCprodbuild/SKILL.md +# on the machine that authored this - Phase 1 step 8). Builds the desktop +# shell (electron/) for macOS, Windows, and Linux on every release, or +# on-demand via workflow_dispatch for a one-off test build. +# +# Ships UNSIGNED. There's no Apple Developer ID or Windows code-signing cert +# yet (VNCprodbuild Phase 1 step 9 - both are human-owned purchases, not +# something CI can provide). CSC_IDENTITY_AUTO_DISCOVERY: "false" below stops +# electron-builder from probing for a macOS signing identity it won't find. +# Adding real certs later needs no rewrite here - just add CSC_LINK/ +# CSC_KEY_PASSWORD (macOS) and/or WIN_CSC_LINK/WIN_CSC_KEY_PASSWORD (Windows) +# as repo secrets and electron-builder picks them up automatically. + +on: + release: + types: [published] + workflow_dispatch: + +permissions: + contents: write + +jobs: + build: + strategy: + fail-fast: false + matrix: + os: [macos-latest, windows-latest, ubuntu-latest] + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Build standalone Next.js server + run: npm run build:standalone + + - name: Bundle Electron main/preload + run: npm run build:electron + + # Only Linux runners lack a display server by default - macOS/Windows + # GitHub-hosted runners can launch a real (if headless) GUI session + # without one. + - name: Install Xvfb (Linux) + if: runner.os == 'Linux' + run: sudo apt-get update && sudo apt-get install -y xvfb + + # Required gate (VNCprodbuild Phase 1 step 2) before any packaging or + # artifact-upload step below, on every OS in the matrix - a + # platform-specific regression in electron/main.ts (path handling, + # spawn behavior, etc.) should fail exactly the leg it breaks, not + # slip through because only one OS was ever smoke-tested. + - name: Run Electron smoke test (Linux, via Xvfb) + if: runner.os == 'Linux' + run: xvfb-run --auto-servernum npm run test:electron + + - name: Run Electron smoke test + if: runner.os != 'Linux' + run: npm run test:electron + + - name: Package + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CSC_IDENTITY_AUTO_DISCOVERY: "false" + run: npx electron-builder --config electron-builder.config.js --publish ${{ github.event_name == 'release' && 'always' || 'never' }} + + - name: Upload artifact (workflow_dispatch) + if: github.event_name == 'workflow_dispatch' + uses: actions/upload-artifact@v4 + with: + name: vncmail-plus-desktop-${{ matrix.os }} + path: | + dist-electron-builds/*.dmg + dist-electron-builds/*.zip + dist-electron-builds/*.exe + dist-electron-builds/*.AppImage + dist-electron-builds/*.deb + retention-days: 7 + if-no-files-found: ignore