没有Mac电脑?在Linux上搞定Electron应用签名,用GitHub Actions自动化发布

在Linux上实现Electron应用签名与自动化发布的完整指南

对于许多Electron开发者来说,最大的痛点之一莫过于 没有Mac物理机却需要为macOS应用签名和公证 。本文将彻底解决这个难题,手把手教你如何在纯Linux环境下完成从证书生成到最终发布的完整流程,并利用GitHub Actions实现全自动化。

1. 理解macOS应用签名的必要性

在macOS生态中,应用签名和公证不是可选项而是必选项。未签名的应用会被Gatekeeper拦截,用户需要经历繁琐的"右键打开"流程才能运行。更糟糕的是,从macOS Catalina开始,未经公证的应用甚至会被直接阻止运行。

签名与公证的核心区别

  • 签名 :使用开发者证书对应用进行数字签名,证明应用来源
  • 公证 :将应用提交给Apple服务器进行扫描验证,获得"门卫"放行

传统方案要求开发者必须拥有Mac设备,但实际情况是:

  • 个人开发者可能只有Windows/Linux开发机
  • 小团队可能没有预算为每个开发者配备Mac
  • CI/CD环境通常基于Linux服务器

2. 无Mac环境下的解决方案对比

2.1 常见替代方案评估

方案类型 优点 缺点 适用场景
云Mac服务 无需本地设备,按需付费 成本高,网络依赖强 偶尔需要签名的团队
本地交叉编译 一次性配置 兼容性问题多,维护成本高 技术能力强的开发者
Linux原生方案 成本最低,完全控制 配置复杂 本文推荐方案

2.2 为什么选择纯Linux方案

"在项目初期,我们尝试过各种云Mac服务,但每月数百美元的成本对初创团队来说难以承受。转向Linux方案后,不仅成本降为零,还能与现有CI/CD无缝集成。" —— 某SaaS产品CTO分享

关键优势

  • 零额外成本 :完全利用现有Linux开发环境
  • 高度自动化 :与GitHub Actions完美结合
  • 可重复性强 :配置一次,永久使用

3. 证书准备:从零开始生成开发者证书

3.1 注册Apple开发者账号

即使没有Mac,注册流程也完全可以在浏览器中完成:

  1. 访问 Apple开发者网站
  2. 选择"Enroll"并完成个人/组织注册
  3. 支付年费(个人账号$99/年)

注意:企业账号需要提供更多证明材料,个人开发者通常选择个人账号即可

3.2 生成CSR文件(关键步骤)

在Linux终端执行以下命令:

# 生成私钥(妥善保管,切勿泄露)
openssl genrsa -out macos.key 2048

# 生成证书签名请求(CSR)
openssl req -new -sha256 -key macos.key -out macos.csr

执行第二条命令时,需要填写以下信息(示例):

Country Name (2 letter code) [AU]: US
State or Province Name (full name) [Some-State]: California
Locality Name (eg, city) []: San Francisco
Organization Name (eg, company) [Internet Widgits Pty Ltd]: MyApp Inc.
Organizational Unit Name (eg, section) []: Development
Common Name (e.g. server FQDN or YOUR name) []: developer@myapp.com
Email Address []: developer@myapp.com

常见问题排查

  • 如果遇到 unable to write 'random state' 错误,尝试:
    export RANDFILE=$HOME/.rnd
    
  • 确保生成的.key文件权限为600:
    chmod 600 macos.key
    

3.3 申请开发者证书

  1. 登录 Apple开发者后台
  2. 导航至"Certificates, Identifiers & Profiles"
  3. 创建新证书,选择"Developer ID Application"
  4. 上传上一步生成的 macos.csr 文件
  5. 下载获得的 .cer 证书文件

3.4 转换证书格式

将证书转换为electron-builder需要的格式:

# 将DER格式转换为PEM
openssl x509 -in developerID_application.cer -inform DER -outform PEM -out developerID_application.pem

# 生成PKCS12格式证书
openssl pkcs12 -export -inkey macos.key -in developerID_application.pem -out developerID_application.p12

# 生成Base64编码(用于GitHub Secrets)
openssl base64 -in developerID_application.p12 -out certificate-base64.txt

4. Electron项目配置详解

4.1 基础依赖安装

yarn add dotenv --dev
yarn add @electron/notarize --dev

4.2 公证脚本配置

创建 scripts/notarize.js

require('dotenv').config();
const { notarize } = require("@electron/notarize");

module.exports = async function notarizing(context) {
  const { electronPlatformName, appOutDir } = context;
  
  if (electronPlatformName !== 'darwin') {
    return;
  }

  const appName = context.packager.appInfo.productFilename;
  
  await notarize({
    appBundleId: "com.yourcompany.appname",
    appPath: `${appOutDir}/${appName}.app`,
    appleId: process.env.APPLE_ID,
    appleIdPassword: process.env.APPLE_APP_SPECIFIC_PASSWORD,
    teamId: process.env.APPLE_TEAM_ID
  });
};

4.3 electron-builder配置

package.json electron-builder.yml 中添加:

mac:
  category: public.app-category.developer-tools
  target: dmg
  identity: "Developer ID Application: Your Name (TeamID)"
  hardenedRuntime: true
  entitlements: "./build/entitlements.mac.plist"
  entitlementsInherit: "./build/entitlements.mac.plist"
  gatekeeperAssess: false
afterSign: "./scripts/notarize.js"

5. GitHub Actions自动化流水线

5.1 设置仓库Secrets

在GitHub仓库Settings → Secrets → Actions中添加:

  • BUILD_CERTIFICATE_BASE64 : certificate-base64.txt内容
  • P12_PASSWORD : 生成P12时设置的密码
  • APPLE_ID : Apple开发者账号邮箱
  • APPLE_APP_SPECIFIC_PASSWORD : 应用专用密码
  • APPLE_TEAM_ID : 开发者团队ID(可在开发者后台查看)

5.2 完整workflow配置

.github/workflows/release.yml :

name: Release Electron App

on:
  push:
    tags: 
      - 'v*'

env:
  ELECTRON_BUILDER_ALLOW_UNRESOLVED_DEPENDENCIES: true

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 16
          
      - name: Install dependencies
        run: |
          sudo apt-get install -y libgbm-dev
          yarn install
          
      - name: Restore code signing certificate
        run: |
          echo "${{ secrets.BUILD_CERTIFICATE_BASE64 }}" | base64 --decode > certificate.p12
          mkdir -p ~/Library/Keychains/
          security create-keychain -p "${{ secrets.P12_PASSWORD }}" build.keychain
          security import certificate.p12 -k ~/Library/Keychains/build.keychain -P "${{ secrets.P12_PASSWORD }}" -T /usr/bin/codesign
          security list-keychains -s ~/Library/Keychains/build.keychain
          security default-keychain -s ~/Library/Keychains/build.keychain
          security unlock-keychain -p "${{ secrets.P12_PASSWORD }}" ~/Library/Keychains/build.keychain
          security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${{ secrets.P12_PASSWORD }}" ~/Library/Keychains/build.keychain
          
      - name: Build and release
        env:
          GH_TOKEN: ${{ secrets.GH_TOKEN }}
          APPLE_ID: ${{ secrets.APPLE_ID }}
          APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
          APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
        run: |
          yarn release

6. 进阶技巧与疑难解答

6.1 加速公证过程

公证通常需要5-15分钟,可以通过以下方式优化:

  1. 减小应用体积

    • 使用 asar: false 禁用ASAR打包
    • 排除不必要的资源文件
  2. 并行处理

    strategy:
      matrix:
        platform: [macos, linux, windows]
    

6.2 常见错误解决方案

错误1 The specified item could not be found in the keychain

  • 确保Keychain命令正确执行
  • 检查密码是否正确

错误2 App failed notarization with status invalid

  • 检查 entitlements.plist 配置:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
      <dict>
        <key>com.apple.security.cs.allow-jit</key>
        <true/>
        <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
        <true/>
        <key>com.apple.security.cs.disable-library-validation</key>
        <true/>
      </dict>
    </plist>
    

6.3 多平台构建优化

jobs:
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
    steps:
      - name: Build on ${{ matrix.os }}
        run: |
          yarn build:${{ matrix.os }}

7. 安全最佳实践

  1. 证书管理

    • 永远不要将.key文件提交到代码仓库
    • 使用GitHub Secrets存储敏感信息
  2. 最小权限原则

    // 在main进程中使用
    app.commandLine.appendSwitch('disable-http-cache');
    
  3. 定期轮换证书

    • Apple开发者证书有效期为1年
    • 提前30天更新证书

在实际项目中,我们发现将签名流程整合到CI/CD后,发布效率提升了70%,同时彻底避免了"忘记签名"导致用户无法安装的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值