最近使用 Tauri 开发了一个电脑端的应用,但是 MacOS 因为系统安全性原因,如果不进行代码签名,安装时会报“应用程序” 已损坏,无法打开。您应该将它移到废纸篓。
。如果不进行软件公证,安装时会报macOS无法验证此App不包含恶意软件
。
当然前一个问题可以通过执行命令sudo spctl --master-disable
和sudo xattr -r -d com.apple.quarantine /Applications/xxx.app
来解决。第二个问题可以通过在设置里面允许打开“任何来源”的方式来解决。
但是这样的方式对于普通用户,想要通过上述的方式打开软件,还是有一些门槛和解释成本的。所以就想尝试完成软件的代码签名和公证。
前置条件
对 MacOS 软件进行代码签名和公证,需要您先申请加入苹果开发者计划,每年需要 688 元人民币。
开发者可以通过Apple Developer App以及网页注册,注册成为个人/组织均可。
注册完毕,等待审核通过即可。
信息准备
创建签名证书请求
要创建一个新的签名证书,您必须在您的 Mac 电脑上通过钥匙串访问
程序生成一个证书签名请求(CSR)文件。
- 启动位于 /Applications/Utilities 中的“钥匙串访问”。
- 选取“钥匙串访问”>“证书助理”>“从证书颁发机构请求证书”。
- 在“证书助理”对话框中,在“用户电子邮件地址”栏位中输入电子邮件地址。
- 在“常用名称”栏位中,输入密钥的名称 (例如,Gita Kumar Dev Key)。
- 将“CA 电子邮件地址”栏位留空。
- 选取“存储到磁盘”,然后点按“继续”。
最终会生成一个扩展名为.certSigningRequest
的文件。
创建并下载证书
- 在您的苹果开发者账户上,导航到Certificates, Identifiers & Profiles页面。
- 点击
+
号创建一个新的证书。 - 选择合适的证书类型(
Apple Distribution
用于将应用提交到 App Store,Developer ID Application
用于将应用打包成 dmg 发布到 App Store 之外的地方)。 - 上传你的 CSR 文件(即上一步的扩展名为
.certSigningRequest
的文件),证书就会被创建出来 - 在 Certificates, Identifiers & Profiles页面,点击你想要使用的证书,然后点击
Download
按钮。 它会保存一个.cer
文件,打开后将证书安装到 钥匙串访问 上。
将证书转换为 base64 格式
- 打开 钥匙串访问 应用程序,点击 登录类型 中的
我的证书
标签,找到你的证书条目。 - 展开条目,右键点击,并选择 导出。
- 选择保存证书的
.p12
文件的路径,并为导出的证书设置一个密码。 - 在终端运行以下脚本将
.p12
文件转换为 base64:
openssl base64 -in /path/to/certificate.p12 -out certificate-base64.txt
- 将
certificate-base64.txt
文件的内容设置为APPLE_CERTIFICATE
环境变量的值。 - 将证书密码设置为
APPLE_CERTIFICATE_PASSWORD
环境变量。
获取并配置 Apple ID 的信息
- 在 account.apple.com 上,登录你的 Apple 账户。
- 在“登录和安全”部分中,选择“App 专用密码”。
- 选择“生成 App 专用密码”,然后按照屏幕上的步骤操作。
- 将您的Apple ID 的邮箱设置为
APPLE_ID
环境变量。 - 将您的第 3 步生成的专用密码设置为
APPLE_ID_PASSWORD
环境变量。 - 进入Developer 账户页面,获取您的团队 ID,并将其设置为
APPLE_TEAM_ID
环境变量。
获取并配置 App Store Connect 信息
- 打开App Store Connect 用户和访问页面,并选择“集成”选项卡。
- 点击
+
号添加密钥信息,名字可以自定义,访问权限选择“开发者”,点击“生成”按钮。 - 在集成页面可以看到“Issuer ID”信息,复制,并将其设置为
APPLE_API_ISSUER
环境变量。 - 在有效的密钥列表中,有一列“密钥ID”数据,复制对应的密钥 ID 信息,并将其设置为
APPLE_API_KEY
环境变量。 - 下载密钥,它只能下载一次,并且只有在页面重新加载后才可见(该按钮显示在新创建密钥的表格行上),下载完毕后打开文件,获取密钥文件内容,并将其设置为
APPLE_API_KEY_CONTENT
环境变量。 - 将
~/.appstoreconnect/private_keys/AuthKey_xxx.p8
设置为APPLE_API_KEY_PATH
环境变量(其中xxx你需要自行替换)。
创建Github Action文件
在.github/workflows
目录下,创建publish.yml
文件,内容如下:
name: "publish"
on:
workflow_dispatch:
push:
branches:
- release
jobs:
publish-tauri:
permissions:
contents: write
strategy:
fail-fast: false
matrix:
include:
- platform: "macos-latest" # for Arm based macs (M1 and above).
args: "--target aarch64-apple-darwin"
- platform: "macos-latest" # for Intel based macs.
args: "--target x86_64-apple-darwin"
- platform: "ubuntu-22.04"
args: ""
- platform: "windows-latest"
args: ""
runs-on: ${{ matrix.platform }}
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
steps:
- uses: actions/checkout@v4
- name: install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-22.04' # This must match the platform value defined above.
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
- name: setup node
uses: actions/setup-node@v4
with:
node-version: lts/*
cache: "yarn" # Set this to npm, yarn or pnpm.
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable # Set this to dtolnay/rust-toolchain@nightly
with:
# Those targets are only used on macos runners so it's in an `if` to slightly speed up windows and linux builds.
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
- name: install sqlx-cli
run: cargo install sqlx-cli --no-default-features --features sqlite,rustls
- name: init db
run: cd src-tauri && sqlx database create && sqlx migrate run && cd ../
- name: Rust cache
uses: swatinem/rust-cache@v2
with:
workspaces: "./src-tauri -> target"
- name: install frontend dependencies
# If you don't have `beforeBuildCommand` configured you may want to build your frontend here too.
run: yarn install # change this to npm or pnpm depending on which one you use.
- name: Import Apple Developer Certificate
if: matrix.platform == 'macos-latest'
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain
security find-identity -v -p codesigning build.keychain
- name: Create .p8 file
if: matrix.platform == 'macos-latest'
run: |
mkdir -p ~/.appstoreconnect/private_keys
echo "${{ secrets.APPLE_API_KEY_CONTENT }}" > ~/.appstoreconnect/private_keys/AuthKey_${{ secrets.APPLE_API_KEY }}.p8
- name: Verify Certificate
if: matrix.platform == 'macos-latest'
run: |
CERT_INFO=$(security find-identity -v -p codesigning build.keychain | grep "Developer ID Application")
CERT_ID=$(echo "$CERT_INFO" | awk -F'"' '{print $2}')
echo "CERT_ID=$CERT_ID" >> $GITHUB_ENV
echo "Certificate imported."
- uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ env.CERT_ID }}
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
APPLE_API_KEY_PATH: ${{ secrets.APPLE_API_KEY_PATH }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
with:
tagName: app-v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version.
releaseName: "App v__VERSION__"
releaseBody: "See the assets to download this version and install."
releaseDraft: true
prerelease: false
args: ${{ matrix.args }}