开源Electron应用GitHubActions自动化部署与升级指南

开源 Electron 应用 GitHub Actions 自动化部署与升级指南

一、前言

本文详细介绍如何利用 GitHub Actions 实现 Electron 应用的自动化构建、发布及通过 UpgradeLink 实现应用自动更新功能。通过本指南,你将学会配置

GitHub Actions 工作流,完成从代码提交到应用更新的全自动化流程。

二、核心工具介绍

UpgradeLink 提供的 GitHub Action 插件,用于将 Electron 应用生成的更新文件上传至 UpgradeLink 服务器,

UpgradeLink 读取json文件中应用文件的地址,保存文件,自动实现应用版本文件的创建,和对应升级策略的创建。

2.已经跑完全部流程的示例项目

流程的示例项目

三、工作流说明

工作流分为三个主要作业:

  1. electron-build:构建并发布 Electron 应用打包不同端与架构的安装包

    • 跨平台构建:同时支持 macOS、Linux 和 Windows
    • 版本号提取:从 Electron 构建输出中提取应用版本号
  2. electron-release :根据 electron-build 构建输出的包,进行 Releases 版本发布

    • 发布管理:自动创建 GitHub Release 并上传应用安装包
    • 输出参数:输出应用版本号,用于后续作业
  3. upgradeLink-upload:将更新信息同步到 UpgradeLink

    • 依赖关系:等待 上面两个作业 作业完成
    • 版本感知:通过输出参数获取应用版本号
    • API 调用:使用 UpgradeLink Action 将对应的安装包上传至升级服务器

四、接入步骤详解

1. 前期准备

首先需要确保:

  • 已创建 GitHub 仓库并上传 Electron 应用代码
  • 拥有 UpgradeLink 平台的账号并获取以下凭证:
  • 在 UpgradeLink平台的 electron 应用配置中,配置上 github 仓库的地址。

2. 配置 GitHub Secrets

在 GitHub 仓库的 Settings > Security > Secrets and variables > Actions 中添加以下加密环境变量:

Secret 名称 说明
UPGRADE_LINK_ACCESS_KEY UpgradeLink 平台提供的访问密钥,用于 API 调用身份验证
UPGRADE_LINK_ELECTRON_KEY UpgradeLink 平台为你的 Electron 应用分配的唯一标识

3. 编辑 electron-demo/.github/workflows/main.yml github-Action文件,根据自己的需要,进行调整。

复制代码
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: ubuntu-22.04
            target: x86_64-unknown-linux-gnu
            artifact-name: ubuntu-x86_64
            arch-suffix: x64
            # 直接定义完整的构建命令,包含通道信息
            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: 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: 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
        # 直接执行矩阵中定义的完整构建命令
        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

          # 先处理重复平台标识
          for file in *.yml; do
            if [ -f "$file" ]; then
              # 固定替换 -linux-linux 为 -linux
              if [[ "$file" == *-linux-linux* ]]; then
                new_file="${file//-linux-linux/-linux}"
                mv "$file" "$new_file"
                echo "替换重复标识: $file -> $new_file"
                file="$new_file"
              fi

              # 固定替换 -mac-mac 为 -mac
              if [[ "$file" == *-mac-mac* ]]; then
                new_file="${file//-mac-mac/-mac}"
                mv "$file" "$new_file"
                echo "替换重复标识: $file -> $new_file"
                file="$new_file"
              fi
          
              # 固定替换 x86_64-x64 为 -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

              # 处理架构后缀
              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: |
          # 优先从标签获取版本号
          if [[ "${{ github.ref }}" == refs/tags/* ]]; then
            VERSION=${{ github.ref_name }}
          else
            # 如果不是标签推送,从package.json读取版本号
            VERSION=$(node -p "require('./package.json').version")
            # 或者使用固定的默认值
            # 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 }}
复制代码
  upgradeLink-upload:
     # 同时依赖 electron-build 和 electron-release,确保能访问 electron-build 的输出
     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 应用唯一标识
           github-token: ${{ secrets.GITHUB_TOKEN }}
           version: ${{ needs.electron-build.outputs.appVersion }}
           prompt-upgrade-content: '提示升级内容'

五、常见问题与解决方案

1. 签名问题

  • macOS
    应用程序必须签名才能使自动更新工作。 参考文档

2. 构建失败排查

  • 检查 GitHub Actions 日志,查看具体错误信息
  • 确认所有依赖已正确安装,特别是 Linux 平台的系统依赖
  • 确保 Node.js 版本兼容
  • 检查 UpgradeLink 控制台中的应用标识是否与配置一致
  • 确认 GitHub Releases 中是否生成了正确的 安装包 文件

六、总结

通过以上配置,你可以实现 Electron 应用的全自动化构建、发布和更新流程。每当代码推送到指定分支时,GitHub Actions 将自动完成以下工作:

  1. 检测代码变更
  2. 在多平台环境中构建 Electron 应用
  3. 创建 GitHub Release 并上传安装包
  4. 提取应用版本号
  5. 将更新信息同步到 UpgradeLink 平台
  6. 最终用户将通过 UpgradeLink 收到应用更新通知

这种自动化流程大大提高了开发效率,减少了手动操作错误,让开发者可以更专注于应用功能开发。

相关推荐
朗宇芯工控16 小时前
注塑机械手控制系统的性能要求有哪些?
科技·自动化·制造·工业·运动控制系统
自可乐17 小时前
n8n全面学习教程:从入门到精通的自动化工作流引擎实践指南
运维·人工智能·学习·自动化
测试_AI_一辰18 小时前
Agent & RAG 测试工程05:把 RAG 的检索过程跑清楚:chunk 是什么、怎么来的、怎么被命中的
开发语言·人工智能·功能测试·自动化·ai编程
wAIxiSeu18 小时前
Github开源项目推荐
开源·github
web打印社区18 小时前
web-print-pdf:突破浏览器限制,实现专业级Web静默打印
前端·javascript·vue.js·electron·html
开源能源管理系统19 小时前
MyEMS开源能源管理系统赋能化纤织造产业绿色转型
开源·能源·能源管理系统·零碳工厂
zhangfeng113320 小时前
ModelScope(魔搭社区)介绍与模型微调全指南 中国版Hugging Face GPU租借平台 一站式开源模型社区与服务平台
人工智能·开源
修己xj20 小时前
FossFLOW:开源等距图表工具,为技术文档注入立体活力!
开源
兆龙电子单片机设计20 小时前
【STM32项目开源】STM32单片机多功能电子秤
stm32·单片机·开源·毕业设计·智能家居
向哆哆20 小时前
高校四六级报名管理系统的考试信息模块实现:Flutter × OpenHarmony 跨端开发实践
flutter·开源·鸿蒙·openharmony·开源鸿蒙