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