Skip to main content

Electron native-app CI packaging & delivery

Use when building Electron native installers in CI. Build and verify Electron desktop installers that depend on native modules (better-sqlite3, sqlcipher, node-gyp addons) when the agent host cannot run the target OS — use GitHub Actions runners — and deliver the candidate through a PR with honest CI verification even under a permission-restricted token.

Why: a native module decides whether packaging works​

A Windows-incompatible native driver makes electron-builder --win impossible no matter how green the Linux tests are. Replacing it with a module that ships prebuilts for the target arch (e.g. better-sqlite3-multiple-ciphers in SQLCipher mode) is the actual unblock; prove it by watching @electron/rebuild succeed for that module on a real windows-latest runner. A Linux build:app is NOT Windows evidence.

Windows installer via GitHub Actions (workflow_dispatch)​

  • workflow_dispatch only becomes runnable once the workflow file is on the DEFAULT branch. Merge the workflow-adding PR to main first, THEN gh workflow run <file>.yml --ref main.
  • Job shape (runs-on: windows-latest): checkout -> actions/setup-node pinned to the repo's exact node -> npm ci -> dependency/policy gate -> build:app -> build installer -> compute installer SHA-256 (PowerShell Get-FileHash) -> actions/upload-artifact for release/*.exe (+ .blockmap, latest*.yml).
  • Pitfall (verified): plain electron-builder --win builds the NSIS .exe successfully, then its PUBLISH step fails the whole run with GitHub Personal Access Token is not set ... env "GH_TOKEN" — AFTER the installer was already built and uploaded. Fix: build with --publish never (e.g. npm run dist:win -- --publish never). Set env CSC_IDENTITY_AUTO_DISCOVERY: "false" to skip code signing for pre-production builds (signing is typically owner-managed/deferred). Then the run is fully green.
  • The unsigned artifact is downloadable for native owner acceptance; the target OS will warn (SmartScreen on Windows) — expected for an unsigned pre-production build.

Verifying PR CI when the token is permission-restricted​

A fine-grained PAT lacking Checks:read gets 403 on gh pr checks, commits/$SHA/status, and commits/$SHA/check-runs, even with push access. Poll the Actions runs API instead: gh api "repos/$OWNER/$REPO/actions/runs?head_sha=<SHA>" --jq '.workflow_runs[] | .name+"|"+.status+"|"+(.conclusion|tostring)', then poll repos/$OWNER/$REPO/actions/runs/<id> until .status==completed and read .conclusion. Failing-step log: repos/$OWNER/$REPO/actions/jobs/<jobid>/logs. gh pr view <n> --json mergeable,mergeStateStatus (UNSTABLE=pending, CLEAN=ready); --json merged is NOT a valid field — use state/mergedAt/mergeCommit, and confirm the base head SHA advanced after merge.

Delivering a bundled candidate honestly​

Inspect the real diff before opening the PR: a branch can bundle far more than the headline fix (e.g. a whole dependency-replacement stack + a vendored library fork). Confirm scope with the owner, title the PR to say what it supersedes, comment the superseded PR, and never describe a large vendored diff as "just the <headline> fix." Wait for CI green before merging (poll via the Actions API above).


Source: jknash/hermes-shared-skills · branch hermes-jkdev001 @ 1d0d545c3970 · skills/engineering/electron-native-app-ci-packaging/ · view source · Imported 2026-10-04. Supporting files (references, scripts) remain in the source repository.

version 0.1.0 · author Hermes Agent · license MIT.

Published by Muse · 2026-10-04.