Publishing Electron apps to GitHub with Electron Forge
Releasing Electron desktop apps can be automated with Electron Forge and GitHub Actions. This post covers the main steps for automation.
Prerequisites
- bootstrapped Electron app
- GitHub personal access token (with
repo
andwrite:packages
permissions) as a GitHub Action secret (GH_TOKEN
)
Setup
Run the following commands to configure Electron Forge for the app release.
npm i @electron-forge/cli @electron-forge/publisher-github -Dnpm i electron-squirrel-startupnpx electron-forge import
The last command should install the necessary dependencies and add a configuration file.
Update the forge.config.js
file with the bin
field containing the app name and ensure the GitHub publisher points to the right repository.
Put Windows and MacOS icons paths in the packagerConfig.icon
field, Windows supports ico
files with 256x256 resolution, and MacOS supports icns
icons with 512x512 resolution (1024x1024 for Retina displays). Linux supports png
icons with 512x512 resolution, also include its path in the BrowserWindow
constructor config within the icon
field.
// forge.config.jsconst path = require('path');module.exports = {packagerConfig: {asar: true,icon: path.join(process.cwd(), 'main', 'build', 'icon'),},rebuildConfig: {},makers: [{name: '@electron-forge/maker-squirrel',config: {bin: 'Electron Starter'}},{name: '@electron-forge/maker-dmg',config: {bin: 'Electron Starter'},},{name: '@electron-forge/maker-deb',config: {bin: 'Electron Starter',options: {icon: path.join(process.cwd(), 'main', 'build', 'icon.png'),},}},{name: '@electron-forge/maker-rpm',config: {bin: 'Electron Starter',icon: path.join(process.cwd(), 'main', 'build', 'icon.png'),}}],plugins: [{name: '@electron-forge/plugin-auto-unpack-natives',config: {}}],publishers: [{name: '@electron-forge/publisher-github',config: {repository: {owner: 'delimitertech',name: 'electron-starter'},prerelease: true}}]};
Upgrade the package version before releasing the app. The npm script for publishing should use publish command. Set productName
field to the app name.
// package.json{// ..."version": "1.0.1","scripts": {// ..."publish": "electron-forge publish"},"productName": "Electron Starter"}
GitHub Action workflow for manually releasing the app for Linux, Windows, and MacOS should contain the below configuration.
# .github/workflows/release.ymlname: Release appon:workflow_dispatch:jobs:build:strategy:matrix:os:[{ name: 'linux', image: 'ubuntu-latest' },{ name: 'windows', image: 'windows-latest' },{ name: 'macos', image: 'macos-latest' },]runs-on: ${{ matrix.os.image }}steps:- name: Github checkoutuses: actions/checkout@v4- name: Use Node.jsuses: actions/setup-node@v4with:node-version: 20- run: npm ci- name: Publish appenv:GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}run: npm run publish
Windows startup events
Add the following code in the main process to prevent Squirrel.Windows launches your app multiple times during the installation/updating/uninstallation.
// main/index.jsif (require('electron-squirrel-startup') === true) app.quit();
Boilerplate
Here is the link to the boilerplate I use for the development. It contains the examples mentioned above with more details.