Electron React Boilerplate is a great template repository for getting started with an Electron application. This article includes a Github workflow for packaging this application automatically and distribution via the auto update mechanism in electron-builder.
I had some trouble getting a release and packaging workflow going. This post contains an end to end workflow for bumping version numbers, generating change logs and packaging your application for all desktop platforms.
It is based on the workflow implemented by Zettlr and adapted for ERB.
Github Actions Workflow for Electron React Boilerplate project
Github Workflow for Electron React Boilerplate
.github/workflows/master.yml
name: Build
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# RATIONALE BEHIND THIS HUGE WORKFLOW
#
# GitHub Actions runs everything in a sandboxed VM, and we need to build
# each asset on its "home" operating system, both because macOS code
# signing, e.g., doesn't work on other platforms. Additionally, this way
# we don't need WINE and, if necessary at some point, can build any
# native dependencies.
#
# This workflow tries to use as few hacks and monkey patches as possible
# to perform the same workflow as the ./scripts/make.sh-file. Therefore
# we ONLY build the corresponding release on the build-VMs, and then
# upload the resulting artifact to the Workflow.
#
# After all artifacts from the three VMs have been successfully uploaded
# to the workflow run, we then download all of them on a fourth VM, where
# we generate the checksums, verify the integrity and finally create a
# new release draft where we upload everything in one step.
#
# Benefits: Native environments without the need to upload useless
# stuff to foreign places (data scarcity, DRY).
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Only when we push to master, as this indicates a build
on:
push:
branches:
- master
# We need two jobs: First a build-job, running on a matrix
# to build all necessary releases, which also uploads all
# resulting assets to the workflow. And then, we download
# them onto a separate VM running the release-job to verify
# the checksums and create a draft release.
jobs:
release_management:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Setting up Node
uses: actions/setup-node@v1
with:
node-version: '10.15.1'
- name: Preparing release
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
pushd ./app
npx standard-version -a --no-verify --prerelease alpha --skip.commit --skip.tag --skip.changelog
echo ::set-env name=PACKAGE_VERSION::$(node -p -e "require('./package.json').version")
popd
npx standard-version -a --no-verify --prerelease alpha --skip.commit --skip.tag
env:
CI: true
# - name: Push to master
# uses: ad-m/github-push-action@v0.5.0
# with:
# github_token: $
# - name: Merge back to develop
# uses: ad-m/github-push-action@v0.5.0
# with:
# github_token: $
# branch: develop
build:
needs: [release_management]
# The build job needs to be built on Win, Linux, and macOS
# Win32 --> build NSIS
# macOS --> build DMG
# Linux --> build DEB, RPM, and AppImage
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
# Define the operating system
runs-on: $
steps:
# Clone the repository
- uses: actions/checkout@v2
# Setup node
- name: Setup NodeJS 12.x
uses: actions/setup-node@v1
with:
node-version: '10.15.0'
# Save the current package.json's version value
# as the output from this step so that we can
# reference it later on.
- name: Emit pkgver
id: pkg
run: |
appver=$(node -p -e "require('./app/package.json').version")
pkgver=$(node -p -e "require('./package.json').version")
echo ::set-output name=version::$appver
echo ::set-output name=package_version::$pkgver
shell: bash
# On Windows server, we have to create the handlebars-directory
# manually, because the node-process always crashes when it
# attempts literally the same thing.
- name: Manually create the handlebars-directory (Windows only)
if: matrix.os == 'windows-latest'
run: New-Item -Path "./source/common/assets" -Name "handlebars" -ItemType "directory" # Hello, PowerShell ._.
# Perform all necessary pre-build steps (LESS, handlebars, and so forth)
- name: Set up build environment and compile the assets
run: |
npm install
yarn
# Now we're set to finally release the beast!
# WINDOWS ==============================================================
- name: Build Windows Installer
if: matrix.os == 'windows-latest' # Only if the job runs on Windows
run: yarn package-win
- name: Cache Windows Exe release
if: matrix.os == 'windows-latest' # Only if the job runs on Windows
uses: actions/upload-artifact@v1
with:
name: Notorious-$.exe
path: ./release/Notorious Setup $.exe
- name: Cache Windows MSI release
if: matrix.os == 'windows-latest' # Only if the job runs on Windows
uses: actions/upload-artifact@v1
with:
name: Notorious-$.msi
path: ./release/Notorious $.msi
# MACOS ================================================================
# - name: Build macOS DMG file
# if: matrix.os == 'macos-latest' # Only if the job runs on macOS
# run: APPLE_ID=$ APPLE_ID_PASS=$ CSC_LINK=$ CSC_KEY_PASSWORD=$ npm run release:mac
# - name: Cache macOS release
# if: matrix.os == 'macos-latest' # Only if the job runs on macOS
# uses: actions/upload-artifact@v1
# with:
# name: Notorious-$.dmg
# path: ./release/Notorious-$.dmg
# LINUX ================================================================
- name: Build Linux targets
if: matrix.os == 'ubuntu-latest'
run: yarn package-linux
- name: Cache Linux Debian release
if: matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@v1
with:
name: Notorious-$-amd64.deb
path: ./release/notorious_$_amd64.deb
- name: Cache Linux Fedora release
if: matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@v1
with:
name: Notorious-$-x86_64.rpm
path: ./release/notorious-$.x86_64.rpm
- name: Cache Linux AppImage (x32) release
if: matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@v1
with:
name: Notorious-$-i386.AppImage
path: ./release/Notorious-$.AppImage
# - name: Cache Linux AppImage (x64) release
# if: matrix.os == 'ubuntu-latest'
# uses: actions/upload-artifact@v1
# with:
# name: Notorious-$-x86_64.AppImage
# path: ./release/Notorious-$.x86_64.AppImage
# As soon as the build matrix has completed correctly, this job will
# commence, creating a new draft release, downloading all assets from
# the previous job, verifying the checksum integrity, and uploading that
# whole mess to the draft release.
prepare_release:
needs: [build] # Make sure (and wait until) the build has succeeded
runs-on: ubuntu-latest
steps:
# Clone the repository to get the ./scripts/get-pkg-version.js and the ./package.json
- uses: actions/checkout@v2
# Setup node to run the retrieval script
- name: Setup NodeJS 12.x
uses: actions/setup-node@v1
with:
node-version: '10.15.0'
- name: Retrieve the current package version
id: pkg
run: |
pkgver=$(node -p -e "require('./app/package.json').version")
echo ::set-output name=version::$pkgver
# Now, download all resulting assets from the previous steps.
- name: Download the Windows asset
uses: actions/download-artifact@v1
with:
name: Notorious-$.exe
path: .
# - name: Download the macOS asset
# uses: actions/download-artifact@v1
# with:
# name: Notorious-$.dmg
# path: .
- name: Download the Debian asset
uses: actions/download-artifact@v1
with:
name: Notorious-$-amd64.deb
path: .
- name: Download the Fedora asset
uses: actions/download-artifact@v1
with:
name: Notorious-$-x86_64.rpm
path: .
- name: Download the AppImage (x32) asset
uses: actions/download-artifact@v1
with:
name: Notorious-$-i386.AppImage
path: .
# - name: Download the AppImage (x64) asset
# uses: actions/download-artifact@v1
# with:
# name: Notorious-$-x86_64.AppImage
# path: .
# Now we are set, we have all five release assets on the VM. It's time to create the
# SHA-checksums file and then upload everything!
- name: Generate SHA256 checksums
run: |
ls -la
sha256sum "Notorious Setup $.exe" > "SHA256SUMS.txt"
# sha256sum "Notorious-$.dmg" >> "SHA256SUMS.txt"
sha256sum "notorious_$_amd64.deb" >> "SHA256SUMS.txt"
sha256sum "notorious-$.x86_64.rpm" >> "SHA256SUMS.txt"
sha256sum "Notorious-$.AppImage" >> "SHA256SUMS.txt"
# sha256sum "Notorious-$-x86_64.AppImage" >> "SHA256SUMS.txt"
- name: Verify checksums
run: |
ls -la
sha256sum -c SHA256SUMS.txt
# Create a new release draft
- name: Create a new release draft
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: $
with:
tag_name: v$ # tag_name is required, but can be overridden during edit
release_name: Release v$ # release_name is required
body: If you can read this, we have forgotten to fill in the changelog. Sorry!
draft: true # Always create as draft, so that we can populate the remaining values easily
# And finally, upload that shit
- name: Upload Windows asset
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: $
with:
upload_url: $
asset_path: ./Notorious Setup $.exe
asset_name: Notorious-$.exe
asset_content_type: application/x-msdownload
# - name: Upload macOS asset
# uses: actions/upload-release-asset@v1.0.1
# env:
# GITHUB_TOKEN: $
# with:
# upload_url: $
# asset_path: ./Notorious-$.dmg
# asset_name: Notorious-$.dmg
# asset_content_type: application/octet-stream
- name: Upload Debian asset
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: $
with:
upload_url: $
asset_path: ./notorious_$_amd64.deb
asset_name: Notorious-$-amd64.deb
asset_content_type: application/octet-stream
- name: Upload Fedora asset
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: $
with:
upload_url: $
asset_path: ./notorious-$.x86_64.rpm
asset_name: Notorious-$-x86_64.rpm
asset_content_type: application/octet-stream
- name: Upload AppImage (x32) asset
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: $
with:
upload_url: $
asset_path: ./Notorious-$.AppImage
asset_name: Notorious-$-i386.AppImage
asset_content_type: application/octet-stream
# - name: Upload AppImage (x64) asset
# uses: actions/upload-release-asset@v1.0.1
# env:
# GITHUB_TOKEN: $
# with:
# upload_url: $
# asset_path: ./Notorious-$-x86_64.AppImage
# asset_name: Notorious-$-x86_64.AppImage
# asset_content_type: application/octet-stream
- name: Upload the checksums
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: $
with:
upload_url: $
asset_path: ./SHA256SUMS.txt
asset_name: SHA256SUMS.txt
asset_content_type: text/plain
Conclusion
If you found this article useful, please also check out this workflow for releasing python based Home Assistant components.