From 4fb817fc0beb1663bb0135e3615d550e3bf7c18c Mon Sep 17 00:00:00 2001 From: Sniphs <56806984+Sniphs98@users.noreply.github.com> Date: Thu, 24 Sep 2026 21:54:47 +0200 Subject: [PATCH 1/2] fix(packaging): give the app its own icon instead of Electron's default The Windows build never had its .exe edited (`signAndEditExecutable: false`, set because the winCodeSign bundle can't be extracted without symlink rights on a normal Windows account), and that edit is what stamps the app icon and version info into the executable. Installed builds therefore showed Electron's default icon and called themselves "Electron" by "GitHub, Inc.". - Release and CI packaging now pass -c.win.signAndEditExecutable=true; their runners have the privilege. Local builds keep it off so `npm run package` still works without Developer Mode. - The window gets the icon explicitly on Linux, where a window has none of its own, and in `npm run dev:electron`, which runs the plain electron binary. Verified locally with the edit enabled: the .exe carries the app icon and reports ProductName "BetterSshClient". Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 4 +++- .github/workflows/release.yml | 6 ++++-- electron-builder.yml | 12 ++++++++---- packages/electron/src/main.ts | 12 ++++++++++++ 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index df67173..fc29755 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -149,5 +149,7 @@ jobs: - name: Install dependencies run: npm ci + # With the .exe editing the release build does (app icon + version info), so a + # break in it shows up here rather than on release day. - name: Package (unpacked directory only) - run: npm run package:dir + run: npm run package:dir -- -c.win.signAndEditExecutable=true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 136811a..1f19077 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -112,15 +112,17 @@ jobs: - run: npm run build + # signAndEditExecutable: stamps the app icon and version info into the Windows .exe + # (off in electron-builder.yml for local builds, see there). Ignored on other OSes. - name: Package and upload to the draft release if: github.event_name == 'push' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: npx electron-builder --publish always + run: npx electron-builder --publish always -c.win.signAndEditExecutable=true - name: Package (dry run) if: github.event_name == 'workflow_dispatch' - run: npx electron-builder --publish never + run: npx electron-builder --publish never -c.win.signAndEditExecutable=true - name: Keep the dry-run installers if: github.event_name == 'workflow_dispatch' diff --git a/electron-builder.yml b/electron-builder.yml index 8a8e159..2911192 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -38,6 +38,9 @@ files: extraResources: - from: packages/ui/build to: ui/build + # The window icon on Linux, where a window has none of its own (main.ts `windowIcon`). + - from: build/icons/256x256.png + to: icon.png asarUnpack: - "**/*.node" @@ -54,10 +57,11 @@ win: target: [nsis, portable, zip] artifactName: ${productName}-${version}-win-${arch}.${ext} icon: build/icon.ico - # electron-builder otherwise fetches the (macOS-targeted) winCodeSign bundle even - # for a plain unsigned Windows build, then fails extracting it here: its symlinks - # need SeCreateSymbolicLinkPrivilege, which a non-admin/non-Developer-Mode Windows - # account doesn't have. Not needed anyway — this build isn't signed. + # Off for local builds: editing the .exe needs electron-builder's winCodeSign bundle, + # whose macOS symlinks a non-admin, non-Developer-Mode Windows account can't extract. + # But editing is also what stamps the app icon and version info into the .exe — without + # it Windows shows Electron's default icon — so the CI and Release workflows turn it on + # (`-c.win.signAndEditExecutable=true`); their runners have the privilege. signAndEditExecutable: false linux: diff --git a/packages/electron/src/main.ts b/packages/electron/src/main.ts index d9474d9..4a250cc 100644 --- a/packages/electron/src/main.ts +++ b/packages/electron/src/main.ts @@ -30,6 +30,17 @@ import { loadWindowGeometry, trackWindowGeometry } from './windowState.js'; // `--bg` token (packages/ui/src/app.css). const BACKGROUND_COLOR = '#171717'; +/** The window's icon. Packaged on Windows and macOS the window takes the icon of its + * .exe / .app bundle; this covers Linux, where a window has none of its own, and + * `npm run dev:electron`, which runs the plain electron binary and would otherwise + * show Electron's default icon. */ +function windowIcon(): string | undefined { + if (process.platform === 'darwin') return undefined; + return app.isPackaged + ? join(process.resourcesPath, 'icon.png') + : join(__dirname, '..', '..', '..', 'build', 'icons', '256x256.png'); +} + /** How long the hidden window may wait for the page before it is revealed anyway. */ const REVEAL_FALLBACK_MS = 3000; @@ -44,6 +55,7 @@ function createWindow(): BrowserWindow { const win = new BrowserWindow({ title: 'BetterSshClient', + icon: windowIcon(), width: geometry.width, height: geometry.height, x: geometry.x, From 071016f951b6e5737cd140bf9b2c14ea7aada1af Mon Sep 17 00:00:00 2001 From: Sniphs <56806984+Sniphs98@users.noreply.github.com> Date: Fri, 25 Sep 2026 16:05:03 +0200 Subject: [PATCH 2/2] fix(ci): run the packaging steps in bash on Windows too Windows runners default to PowerShell, which splits `-c.win.signAndEditExecutable=true` at the dot into `-c` and `.win.signAndEditExecutable=true`; electron-builder then tried to load the latter as a config file and the Windows package job failed. The release workflow had the same line and would have failed on the next release. Reproduced with node's argv under PowerShell; bash passes it intact. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 7 +++++++ .github/workflows/release.yml | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc29755..d8617ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -137,6 +137,13 @@ jobs: env: CSC_IDENTITY_AUTO_DISCOVERY: false + # Bash on every OS, Windows included: PowerShell splits an argument like + # `-c.win.signAndEditExecutable=true` at the dot, and electron-builder then reads + # `.win.…` as the path of a config file. + defaults: + run: + shell: bash + steps: - name: Checkout uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1f19077..34cc5ec 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -90,6 +90,13 @@ jobs: # Unsigned builds: don't let electron-builder go looking for a signing identity. CSC_IDENTITY_AUTO_DISCOVERY: false + # Bash on every OS, Windows included: PowerShell splits an argument like + # `-c.win.signAndEditExecutable=true` at the dot, and electron-builder then reads + # `.win.…` as the path of a config file. + defaults: + run: + shell: bash + steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4