Skip to content

راهنمای استقرار و به‌روزرسانی اتوماتیک GitHub Actions برای برنامه‌های Electron متن باز

1. معرفی

این مقاله راهنمای دقیقی در مورد نحوه استفاده از GitHub Actions برای دستیابی به ساخت اتوماتیک، انتشار، و به‌روزرسانی اتوماتیک برنامه‌های Electron از طریق UpgradeLink ارائه می‌دهد. از طریق این راهنمای شما یاد می‌گیرید که چگونه Workflowهای GitHub Actions را پیکربندی کنید تا فرآیند اتوماسیون کامل از ارسال کد تا به‌روزرسانی برنامه را تکمیل کنید.

2. معرفی ابزارهای اصلی

UpgradeLink پلاگین GitHub Action برای بارگذاری فایل‌های به‌روزرسانی تولید شده توسط برنامه Electron به سرور UpgradeLink ارائه می‌دهد. UpgradeLink آدرس‌های فایل برنامه را از فایل‌های JSON می‌خواند، فایل‌ها را ذخیره می‌کند، و فایل‌های نسخه برنامه و استراتژی‌های به‌روزرسانی مربوطه را به‌طور خودکار ایجاد می‌کند.

2. پروژه نمونه با Workflow کامل

پروژه نمونه با Workflow کامل:

3. توضیح Workflow

Workflow از سه job اصلی تشکیل می‌شود:

  1. electron-build: ساخت و انتشار بسته‌های برنامه Electron برای پلتفرم‌ها و معماری‌های مختلف

    • ساخت چند پلتفرمی: همزمان از macOS، Linux، و Windows پشتیبانی می‌کند
    • استخراج نسخه: استخراج شماره نسخه برنامه از خروجی ساخت Electron
  2. electron-release: انتشار نسخه‌های بر اساس بسته‌های ساخته شده توسط electron-build

    • مدیریت انتشار: به‌طور خودکار GitHub Release ایجاد کرده و بسته‌های نصب برنامه را بارگذاری می‌کند
    • پارامترهای خروجی: شماره نسخه برنامه را برای jobهای بعدی خروجی می‌دهد
  3. upgradeLink-upload: هم‌گام‌سازی اطلاعات به‌روزرسانی با UpgradeLink

    • وابستگی: منتظر تکمیل دو job بالا می‌ماند
    • آگاهی نسخه: شماره نسخه برنامه را از طریق پارامترهای خروجی دریافت می‌کند
    • فراخوانی‌های API: از UpgradeLink Action برای بارگذاری بسته‌های نصب مربوطه به سرور به‌روزرسانی استفاده می‌کند

4. توضیح دقیق مراحل ادغام

1. آماده‌سازی

ابتدا، اطمینان حاصل کنید که:

  • مخزن GitHub ایجاد شده و کد برنامه Electron بارگذاری شده است
  • حساب پلتفرم UpgradeLink دارید و مراکز زیر را به‌دست آورده‌اید:
  • آدرس مخزن GitHub را در پیکربندی برنامه electron در پلتفرم UpgradeLink پیکربندی کرده‌اید.

2. پیکربندی GitHub Secrets

مولفه‌های محیطی رمزگذاری شده زیر را در GitHub repository 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 را ویرایش کنید، مطابق با نیازهای خود تنظیم کنید.

yaml
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 }}
yaml
  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. مشکلات رایج و راه‌حل‌ها

1. مشکلات امضای دیجیتال

  • macOS برنامه‌ها باید امضای دیجیتال داشته باشند تا به‌روزرسانی‌های اتوماتیک کار کنند. مستندات مرجع

2.troubleshooting بروزرسانی ساخت

  • برای اطلاعات خطای خاص، به لاگ‌های GitHub Actions مراجعه کنید
  • اطمینان حاصل کنید که همه وابستگی‌ها به‌درستی نصب شده، به‌ویژه وابستگی‌های سیستم برای پلتفرم Linux
  • سازگاری نسخه Node.js را تایید کنید
  • بررسی کنید که آیا شناسه برنامه در کنسول UpgradeLink با پیکربندی مطابقت دارد
  • تأیید کنید که آیا فایل‌های بسته نصب درست در GitHub Releases تولید شده‌اند

6. خلاصه

از طریق پیکربندی بالا، می‌توانید اتوماسیون کامل فرآیندهای ساخت، انتشار، و به‌روزرسانی برنامه Electron را به‌وجود آورید. هرگاه که کد به برانچ مشخص شده رانده شود، GitHub Actions به‌طور خودکار کارهای زیر را تکمیل خواهد کرد:

  1. تشخیص تغییرات کد
  2. ساخت برنامه Electron در محیط‌های چند پلتفرمی
  3. ایجاد GitHub Release و بارگذاری بسته‌های نصب
  4. استخراج شماره نسخه برنامه
  5. هم‌گام‌سازی اطلاعات به‌روزرسانی با پلتفرم UpgradeLink
  6. کاربران نهایی از طریق UpgradeLink اعلان‌های به‌روزرسانی برنامه را دریافت خواهند کرد

این Workflow اتوماتیک به شدت کارایی توسعه را بهبود می‌بخشد، خطاهای عملیات دستی را کاهش می‌دهد، و به توسعه‌دهندگان اجازه می‌دهد تا بیشتر بر توسعه功املیات برنامه تمرکز کنند.

toolsetlink@163.com