Every prior distributable DMG this session was built with plain `npx electron-builder`, never `--config electron-builder.config.js`. electron- builder does not auto-detect a file named electron-builder.config.js (its search list is .yml/.yaml/.json/.json5/.js/.cjs/.mjs/.ts, not .config.js), so the config - correct productName/appId/icon and all - was silently ignored on every build. Caught only by actually launching the packaged .app: it booted to "Bulwark Webmail Setup" demanding a token from container logs, default Electron atom icon, output in dist/ instead of dist-electron-builds/. Fixes, each verified against the packaged .app (Playwright _electron.launch, not the build log): - Add dist:mac/win/linux/dir scripts that pass --config explicitly, so this can't recur. - Dedicated 1024x1024 app icon (build-resources/app-icon.png, SRC symbol on #09090b) instead of reusing the web PWA manifest icon. Verified: icns ships at 1024x1024, pixel-identical to the source (mean diff 0.0/255). - electron/main.ts: getDesktopDefaults() sets JMAP_SERVER_URL to the sandbox (the ONLY thing that puts the server into "env-managed" mode and skips the setup wizard - see lib/setup/state.ts), plus APP_NAME/login logo/ favicon/company-name env vars, spread before ...process.env so a real deployment still overrides. Verified: packaged app now opens straight to a login screen with the JMAP endpoint field pre-filled https://stalwart.sandbox.vnc.de, title "VNCmail+", SRC logo. - LOGIN_SHOW_SUBTITLE=false: the subtitle falls back to the login.title i18n string ("Webmail") whenever it differs from APP_NAME - a check written for the original Bulwark pairing where they matched. Hiding it avoids touching that shared string for every other deployment.
122 lines
5.9 KiB
JavaScript
122 lines
5.9 KiB
JavaScript
// electron-builder config for the VNCmail+ (Bulwark) desktop shell.
|
|
//
|
|
// Phase 1 of the VNCprodbuild rollout (~/.claude/skills/VNCprodbuild/SKILL.md):
|
|
// step 1 - base config, no targets (superseded by this file)
|
|
// step 6 - this file: real packaging targets + branding icon (below)
|
|
// step 7 - this file's `publish` block + electron/main.ts's
|
|
// setupAutoUpdater() - electron-updater against GitHub Releases.
|
|
// step 9 - still open: code signing / notarization (Apple Developer ID,
|
|
// optional Windows cert) - both are human-owned purchases, not
|
|
// configured here. Builds below ship UNSIGNED.
|
|
module.exports = {
|
|
appId: "de.vnc.vncmailplus",
|
|
productName: "VNCmail+",
|
|
copyright: "Copyright © VNC AG",
|
|
directories: {
|
|
output: "dist-electron-builds",
|
|
},
|
|
// The packaged app (`files` below) is plain esbuild-bundled JS - no native
|
|
// node modules of its own. The one native dependency anywhere in the repo,
|
|
// @signalapp/sqlcipher (used by lib/mail-index/**), ships its own prebuilt
|
|
// .node binaries for every platform/arch and is copied in wholesale by
|
|
// scripts/assemble-standalone.mjs as part of the extraResources standalone
|
|
// bundle below - it is never rebuilt by electron-builder.
|
|
//
|
|
// Without this, electron-builder's default @electron/rebuild pass scans
|
|
// the ENTIRE node_modules tree (not just what's actually packaged) for
|
|
// anything with a native binding and tries to recompile it from source
|
|
// against Electron's ABI via node-gyp. That caught @parcel/watcher - a
|
|
// transitive devDependency of some dev tool, never shipped in this app -
|
|
// and hard-failed the whole packaging step on any machine without a full
|
|
// Xcode Command Line Tools install (`gyp: No Xcode or CLT version
|
|
// detected!`), even though nothing that rebuild step touches is part of
|
|
// the artifact. Verified by execution: builds failed with npmRebuild at
|
|
// its default (true) and succeeded once set to false.
|
|
npmRebuild: false,
|
|
files: ["dist-electron/**/*", "package.json"],
|
|
extraResources: [
|
|
{
|
|
// Same artifact the Dockerfile bakes into the container image (see
|
|
// Dockerfile + scripts/assemble-standalone.mjs). electron/main.ts
|
|
// reads it from process.resourcesPath in packaged builds.
|
|
//
|
|
// Deliberately `from: ".next"` (not ".next/standalone") + a filter,
|
|
// not the more obvious `from: ".next/standalone"` alone:
|
|
// app-builder-lib's copy filter unconditionally drops a directory
|
|
// literally named "node_modules" sitting at the copy root (see
|
|
// node_modules/app-builder-lib/out/util/filter.js's
|
|
// `relative === "node_modules"` check - it assumes extraResources are
|
|
// hand-authored assets, not a pre-built server with a traced
|
|
// node_modules of its own). Copying from one level up so
|
|
// "standalone/node_modules" is never the literal copy root sidesteps
|
|
// that check, so the standalone server's node_modules actually
|
|
// survives into the packaged app instead of getting silently
|
|
// stripped (caught by manually launching a --dir build - the packaged
|
|
// server crashed with "Cannot find module 'next'").
|
|
from: ".next",
|
|
filter: ["standalone/**/*"],
|
|
to: ".",
|
|
},
|
|
],
|
|
// Dedicated 1024x1024 app icon: the SRC symbol centred on the SRC dark
|
|
// ground (#09090b), generated from public/branding/SRC_Symbol.png into
|
|
// build-resources/app-icon.png (NOT build/ - that's electron-builder's own
|
|
// gitignored output dir; a source asset living inside it would never get
|
|
// committed, which is exactly the bug this comment is warning about one
|
|
// paragraph down). 1024 is the size macOS actually wants for the largest
|
|
// icns representation ("ICON512@2x"), so nothing gets upsampled.
|
|
//
|
|
// Deliberately NOT public/icon-512x512.png (what this used to point at):
|
|
// that file is the *web* PWA manifest icon, so retouching it for the
|
|
// desktop app silently changes the browser/PWA install icon too. Separate
|
|
// source, separate concern.
|
|
//
|
|
// NOTE for whoever runs this next: electron-builder does NOT auto-detect a
|
|
// file named `electron-builder.config.js` - its search list is
|
|
// electron-builder.{yml,yaml,json,json5,js,cjs,mjs,ts}. Packaging must be
|
|
// invoked with an explicit `--config electron-builder.config.js`, or every
|
|
// setting in this file is silently ignored and you get stock defaults
|
|
// (default Electron atom icon, `dist/` output, productName taken from
|
|
// package.json's `name`). See the `dist:*` scripts in package.json, which
|
|
// exist so nobody has to remember that.
|
|
icon: "build-resources/app-icon.png",
|
|
mac: {
|
|
target: [
|
|
{ target: "dmg", arch: ["x64", "arm64"] },
|
|
{ target: "zip", arch: ["x64", "arm64"] },
|
|
],
|
|
category: "public.app-category.productivity",
|
|
// No Apple Developer ID yet (VNCprodbuild step 9) - ship unsigned/
|
|
// un-notarized for now. hardenedRuntime is meaningless without signing
|
|
// but left explicit so it's obvious what step 9 needs to flip on.
|
|
hardenedRuntime: false,
|
|
},
|
|
afterSign: "scripts/after-sign.cjs",
|
|
win: {
|
|
target: [{ target: "nsis", arch: ["x64"] }],
|
|
},
|
|
nsis: {
|
|
oneClick: false,
|
|
allowToChangeInstallationDirectory: true,
|
|
},
|
|
linux: {
|
|
target: [
|
|
{ target: "AppImage", arch: ["x64"] },
|
|
{ target: "deb", arch: ["x64"] },
|
|
],
|
|
category: "Network;Email;",
|
|
},
|
|
// electron-updater feed (see electron/main.ts's setupAutoUpdater()).
|
|
// GitHub Releases, not a new distribution channel - the skill's
|
|
// recommendation since this repo is already private and this needs no
|
|
// extra infrastructure. "Light decision" per VNCprodbuild step 7, not
|
|
// blocking, but flagged: switching later (e.g. to a self-hosted update
|
|
// server) would mean revisiting this block and the `provider` electron-
|
|
// updater talks to.
|
|
publish: {
|
|
provider: "github",
|
|
owner: "brvncde-dotcom",
|
|
repo: "vncmail-plus",
|
|
},
|
|
};
|