Open Source Electron Application GitHub Actions Automated Deployment and Upgrade Guide
1. Introduction
This article provides a detailed guide on how to use GitHub Actions to achieve automated building, publishing, and automatic updates for Electron applications through UpgradeLink. Through this guide, you will learn how to configure GitHub Actions workflows to complete the full automation process from code submission to application updates.
2. Core Tools Introduction
1. UpgradeLink GitHub Action
UpgradeLink provides a GitHub Action plugin for uploading Electron application generated update files to the UpgradeLink server. UpgradeLink reads the application file addresses from JSON files, saves the files, and automatically creates application version files and corresponding upgrade strategies.
2. Example Project with Complete Workflow
Example project with complete workflow:
3. Workflow Description
The workflow consists of three main jobs:
electron-build: Build and publish Electron application packages for different platforms and architectures
- Cross-platform building: Supports macOS, Linux, and Windows simultaneously
- Version extraction: Extract application version number from Electron build output
electron-release: Release versions based on packages built by electron-build
- Release management: Automatically create GitHub Release and upload application installation packages
- Output parameters: Output application version number for subsequent jobs
upgradeLink-upload: Synchronize update information to UpgradeLink
- Dependency: Waits for the completion of the above two jobs
- Version awareness: Get application version number through output parameters
- API calls: Use UpgradeLink Action to upload corresponding installation packages to the upgrade server
4. Integration Steps Detailed Explanation
1. Preparation
First, ensure that:
- GitHub repository has been created and Electron application code has been uploaded
- Have an UpgradeLink platform account and obtain the following credentials:
- ACCESS_KEY (Access Key) Key Information
- ELECTRON_KEY (Application Unique Identifier) Application Information
- Configure the GitHub repository address in the electron application configuration on the UpgradeLink platform.
2. Configure GitHub Secrets
Add the following encrypted environment variables in GitHub repository Settings > Security > Secrets and variables > Actions:
| Secret Name | Description |
|---|---|
| UPGRADE_LINK_ACCESS_KEY | Access key provided by UpgradeLink platform for API call authentication |
| UPGRADE_LINK_ELECTRON_KEY | Unique identifier assigned by UpgradeLink platform for your Electron application |
3. Edit electron-demo/.github/workflows/main.yml GitHub Action file, adjust according to your needs.
name: 'publish'
on:
push:
branches:
- main
tags:
- '*.*.*'
jobs:
electron-build:
outputs:
appVersion: ${{ steps.extract-version.outputs.appVersion }}
permissions:
contents: write
strategy:
fail-fast: false
matrix:
include:
# Linux platform
- platform: ubuntu-22.04
target: x86_64-unknown-linux-gnu
artifact-name: ubuntu-x86_64
arch-suffix: x64
# Directly define complete build command including channel information
build-command: "yarn electron-builder --linux --x64 --publish always --config.publish.channel=latest-linux"
- platform: ubuntu-22.04
target: aarch64-unknown-linux-gnu
artifact-name: ubuntu-aarch64
arch-suffix: arm64
build-command: "yarn electron-builder --linux --arm64 --publish always --config.publish.channel=latest-linux"
# macOS platform
- platform: macos-latest
target: aarch64-apple-darwin
artifact-name: macos-arm64
arch-suffix: arm64
build-command: "yarn electron-builder --mac --arm64 --publish always --config.publish.channel=latest-mac"
- platform: macos-latest
target: x86_64-apple-darwin
artifact-name: macos-x64
arch-suffix: x64
build-command: "yarn electron-builder --mac --x64 --publish always --config.publish.channel=latest-mac"
# Windows platform
- platform: windows-latest
target: x86_64-pc-windows-msvc
artifact-name: windows-x64
arch-suffix: x64
build-command: "yarn electron-builder --win --x64 --publish always --config.publish.channel=latest-win"
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4
- name: setup node
uses: actions/setup-node@v4
with:
node-version: lts/*
cache: 'yarn'
- name: Install dependencies with yarn
run: yarn install
- name: List installed dependencies
run: yarn list
- name: install dependencies (ubuntu only)
if: startsWith(matrix.platform, 'ubuntu')
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf xdg-utils
- name: install dependencies (macos only)
if: matrix.platform == 'macos-latest'
run: |
brew install automake autoconf libtool
- name: install frontend dependencies
run: yarn install
- name: Install rimraf
run: yarn add rimraf --dev
- name: Build Electron App
# Directly execute the complete build command defined in the matrix
run: ${{ matrix.build-command }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Cleanup Artifacts for Linux
if: startsWith(matrix.platform, 'ubuntu')
run: |
mkdir -p dist-temp
find dist -maxdepth 1 -type f \( -name "*.AppImage" -o -name "*.yml" -o -name "*.zip" \) -exec cp {} dist-temp/ \;
rm -rf dist
mv dist-temp dist
echo "保留的发布文件:"
ls -la dist
- name: Cleanup Artifacts for macOS
if: matrix.platform == 'macos-latest'
run: |
mkdir -p dist-temp
find dist -maxdepth 1 -type f \( -name "*.dmg" -o -name "*.pkg" -o -name "*.zip" -o -name "*.yml" \) -exec cp {} dist-temp/ \;
rm -rf dist
mv dist-temp dist
echo "保留的发布文件:"
ls -la dist
- name: Cleanup Artifacts for Windows
if: matrix.platform == 'windows-latest'
run: |
New-Item -ItemType Directory -Path dist-temp -Force | Out-Null
Get-ChildItem -Path dist -File | Where-Object {
$_.Name -like "*.exe" -or $_.Name -like "*.msi" -or $_.Name -like "*.zip" -or $_.Name -like "*.yml"
} | Copy-Item -Destination dist-temp/
Remove-Item -Path dist -Recurse -Force
Rename-Item -Path dist-temp -NewName dist
Write-Host "保留的发布文件:"
Get-ChildItem -Path dist
- name: Rename files with architecture suffix (Linux/macOS)
if: startsWith(matrix.platform, 'ubuntu') || matrix.platform == 'macos-latest'
run: |
cd dist
ARCH_SUFFIX="${{ matrix.arch-suffix }}"
if [ "$ARCH_SUFFIX" != "x64" ] && [ "$ARCH_SUFFIX" != "arm64" ]; then
echo "错误: 架构后缀不正确 - $ARCH_SUFFIX"
exit 1
fi
# Process duplicate platform identifiers first
for file in *.yml; do
if [ -f "$file" ]; then
# Fixed replacement -linux-linux to -linux
if [[ "$file" == *-linux-linux* ]]; then
new_file="${file//-linux-linux/-linux}"
mv "$file" "$new_file"
echo "替换重复标识: $file -> $new_file"
file="$new_file"
fi
# Fixed replacement -mac-mac to -mac
if [[ "$file" == *-mac-mac* ]]; then
new_file="${file//-mac-mac/-mac}"
mv "$file" "$new_file"
echo "替换重复标识: $file -> $new_file"
file="$new_file"
fi
# Fixed replacement x86_64-x64 to -x64
if [[ "$file" == *-x86_64-x64* ]]; then
new_file="${file//x86_64-x64/-x64}"
mv "$file" "$new_file"
echo "替换重复标识: $file -> $new_file"
file="$new_file"
fi
# Process architecture suffix
if [[ "$file" != *-"$ARCH_SUFFIX".* ]]; then
filename="${file%.*}"
extension="${file#$filename}"
new_filename="${filename}-${ARCH_SUFFIX}${extension}"
mv "$file" "$new_filename"
echo "添加架构后缀: $file -> $new_filename"
else
echo "文件已处理完成: $file"
fi
fi
done
echo "最终文件列表:"
ls -l
- name: Rename files with architecture suffix (Windows)
if: matrix.platform == 'windows-latest'
run: |
cd dist
$ARCH_SUFFIX = "${{ matrix.arch-suffix }}"
if ($ARCH_SUFFIX -ne "x64" -and $ARCH_SUFFIX -ne "arm64") {
Write-Error "错误: 架构后缀不正确 - $ARCH_SUFFIX"
exit 1
}
Get-ChildItem -File | ForEach-Object {
$file = $_
if ($file.Name -match "-$ARCH_SUFFIX\.[^.]+$") {
Write-Host "文件已包含架构后缀: $($file.Name)"
} else {
$filename = $file.BaseName
$extension = $file.Extension
$new_filename = "$filename-$ARCH_SUFFIX$extension"
Rename-Item -Path $file.FullName -NewName $new_filename
Write-Host "重命名: $($file.Name) -> $new_filename"
}
}
Write-Host "重命名后的文件:"
Get-ChildItem -File
- name: Extract version
id: extract-version
run: |
# Prioritize getting version number from tag
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
VERSION=${{ github.ref_name }}
else
# If not a tag push, read version number from package.json
VERSION=$(node -p "require('./package.json').version")
# Or use a fixed default value
# VERSION="dev-$(date +%Y%m%d)"
fi
echo "appVersion=$VERSION" >> $GITHUB_OUTPUT
echo "Extracted version: $VERSION"
shell: bash
- name: Upload artifacts
uses: actions/upload-artifact@v4.0.0
with:
name: ${{ matrix.artifact-name }}
path: dist/*
if-no-files-found: error
electron-release:
needs: electron-build
runs-on: ubuntu-22.04
permissions:
contents: write
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: false
- name: Verify artifact files
run: |
echo "下载的文件结构:"
tree artifacts
if [ -z "$(find artifacts -type f)" ]; then
echo "错误: 没有找到任何artifact文件"
exit 1
fi
- name: Prepare release files
run: |
mkdir -p release-files
find artifacts -type f -exec cp {} release-files/ \;
echo "准备发布的文件:"
ls -l release-files
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ needs.electron-build.outputs.appVersion }}
name: Release ${{ needs.electron-build.outputs.appVersion }}
files: release-files/*
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}4. Introduce upgradelink-action module. Replace corresponding information
upgradeLink-upload:
# Depend on both electron-build and electron-release to ensure access to electron-build output
needs: [ electron-build, electron-release ]
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Send a request to UpgradeLink
uses: toolsetlink/upgradelink-action-electron@v1.0.1
with:
source-url: 'https://github.com/toolsetlink/electron-demo/releases/download/${{ needs.electron-build.outputs.appVersion }}'
access-key: ${{ secrets.UPGRADE_LINK_ACCESS_KEY }} # ACCESS_KEY key
electron-key: ${{ secrets.UPGRADE_LINK_ELECTRON_KEY }} # ELECTRON_KEY electron application unique identifier
github-token: ${{ secrets.GITHUB_TOKEN }}
version: ${{ needs.electron-build.outputs.appVersion }}
prompt-upgrade-content: 'Upgrade prompt content'5. Common Issues and Solutions
1. Signature Issues
- macOS Applications must be signed for automatic updates to work. Reference Documentation
2. Build Failure Troubleshooting
- Check GitHub Actions logs for specific error information
- Confirm all dependencies are correctly installed, especially system dependencies for Linux platform
- Ensure Node.js version compatibility
3. UpgradeLink Integration Issues
- Check if the application identifier in the UpgradeLink console matches the configuration
- Confirm if correct installation package files are generated in GitHub Releases
6. Summary
Through the above configuration, you can achieve full automation of Electron application building, publishing, and update processes. Whenever code is pushed to the specified branch, GitHub Actions will automatically complete the following work:
- Detect code changes
- Build Electron application in multi-platform environments
- Create GitHub Release and upload installation packages
- Extract application version number
- Synchronize update information to the UpgradeLink platform
- End users will receive application update notifications through UpgradeLink
This automated workflow greatly improves development efficiency, reduces manual operation errors, and allows developers to focus more on application feature development.