我正在构建一个 Github Actions 作业来构建、签名和公证PKG 文件。
我使用的是 Apple Id 帐户(工作流程需要用户名和密码)以及带有私钥(加密)的 Developer Id Installer 证书。两者都保存为机密 (base64),并将在工作流程中转换为 .p12 文件,然后添加到钥匙串。
此作业是私有存储库中更大工作流程的一部分,该工作流程首先从软件生成文件(使用Pyinstaller),然后将 PKG 导出到 AWS S3 存储桶上。
jobs:
[...]
pkg:
needs: [...]
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Download macos bin file
uses: actions/download-artifact@v2
with:
name: macos-bin-files
path: dist/
- name:
run: |
----- Create certificate files from secrets base64 -----
echo ${{ secrets.DEVELOPER_ID_INSTALLER_CER }} | base64 --decode > certificate_installer.cer
echo ${{ secrets.DEVELOPER_ID_INSTALLER_KEY }} | base64 --decode > certificate_installer.key
----- Create p12 file -----
openssl pkcs12 -export -name zup -in certificate_installer.cer -inkey certificate_installer.key -passin pass:${{ secrets.KEY_PASSWORD }} -out certificate_installer.p12 -passout pass:${{ secrets.P12_PASSWORD }}
----- Configure Keychain -----
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
security create-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" $KEYCHAIN_PATH
----- Import certificates on Keychain -----
security import certificate_installer.p12 -P "${{ secrets.P12_PASSWORD }}" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
----- Generate PKG from files -----
use a macos installer script (ref: https://github.com/KosalaHerath/macos-installer-builder/tree/master/macOS-x64)
----- Sign PKG file -----
productsign --sign "${{ secrets.DEVELOPER_ID_INSTALLER_NAME }}" $INPUT_FILE_PATH $OUTPUT_FILE_PATH
- name: "Notarize Release Build PKG"
uses: devbotsxyz/xcode-notarize@v1
with:
product-path: $PATH_TO_PKG
appstore-connect-username: ${{ secrets.APPLE_ACCOUNT_USERNAME }}
appstore-connect-password: ${{ secrets.APPLE_ACCOUNT_PASSWORD }}
primary-bundle-id: 'BUNDLE_ID'
- name: "Staple Release Build"
uses: devbotsxyz/xcode-staple@v1
with:
product-path: $PATH_TO_PKG
[...]
我按照 Github Action 官方文档在 macOS 运行器上安装 Apple 证书,这部分按预期工作。我可以将证书添加到钥匙串,并使用它通过
productsign
命令对 PKG 文件进行签名。
但是,当我将 PKG 发送给 Apple 进行公证时,它返回了该错误:
Error: Notarization status <invalid> - Package Invalid
Error: Notarization failed
PKG 在分发时按预期工作(只需以管理员身份打开而不是经过公证),因此问题似乎与包实现无关。
我尝试使用命令行执行公证,遵循来自不同来源的链接:
但是,即使使用这些命令行(不使用公证操作),我也无法对 PKG 文件进行公证。
我的工作流程出了什么问题,在尝试对包裹进行公证之前我是否遗漏了某些内容?
PS:我找不到任何在 Github Actions macos 运行器上执行此操作的参考...
设置
devbotsxyz/xcode-notarize@v1
字段 verbose:true
后,我观察到 Apple 返回了一个 JSON 链接,解释了为什么该包对于公证无效。
在此 JSON 中,我们得知组成我的 PKG 的所有文件(有很多文件,因为我无法在我的上下文中使用 Pyinstaller
--onefile
)都是无效的 因为它们没有签名和时间戳。
经过一番研究,我在苹果开发者论坛上找到了这篇文章,并了解到PKG文件需要从内到外进行签名:首先,对Pyinstaller生成的每个文件进行签名,然后对收集所有这些文件的PKG进行签名。
为此,您不能使用
productsign
命令(因为它仅适用于 .pkg、.zip 和 .dmg),但可以使用 codesign
。
但是,
codesign
不使用Developer Id Installer certificate
,而是使用Developer Id Application certificate
,所以我也必须将这个新证书添加到工作流程中。
请注意,由于我的 PKG 将由数百个文件组成,因此我还需要 一个 bash 脚本来使用 codesign 对每个文件进行签名。
我的最终工作流程如下所示:
jobs:
[...]
pkg:
needs: [...]
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Download macos bin file
uses: actions/download-artifact@v2
with:
name: macos-bin-files
path: dist/
- name:
run: |
----- Create certificate files from secrets base64 -----
echo ${{ secrets.DEVELOPER_ID_INSTALLER_CER }} | base64 --decode > certificate_installer.cer
echo ${{ secrets.DEVELOPER_ID_INSTALLER_KEY }} | base64 --decode > certificate_installer.key
echo ${{ secrets.DEVELOPER_ID_APPLICATION_CER }} | base64 --decode > certificate_application.cer
echo ${{ secrets.DEVELOPER_ID_APPLICATION_KEY }} | base64 --decode > certificate_application.key
----- Create p12 file -----
openssl pkcs12 -export -name zup -in certificate_installer.cer -inkey certificate_installer.key -passin pass:${{ secrets.KEY_PASSWORD }} -out certificate_installer.p12 -passout pass:${{ secrets.P12_PASSWORD }}
openssl pkcs12 -export -name zup -in certificate_application.cer -inkey certificate_application.key -passin pass:${{ secrets.KEY_PASSWORD }} -out certificate_application.p12 -passout pass:${{ secrets.P12_PASSWORD }}
----- Configure Keychain -----
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
security create-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" $KEYCHAIN_PATH
----- Import certificates on Keychain -----
security import certificate_installer.p12 -P "${{ secrets.P12_PASSWORD }}" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security import certificate_application.p12 -P "${{ secrets.P12_PASSWORD }}" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
----- Codesign files with script -----
use a script to sign each file from the artifact (ref: https://gist.github.com/GuillaumeFalourd/4efc73f1a6014b791c0ef223a023520a)
----- Generate PKG from codesigned files -----
use a macos installer script (ref: https://github.com/KosalaHerath/macos-installer-builder/tree/master/macOS-x64)
----- Sign PKG file -----
productsign --sign "${{ secrets.DEVELOPER_ID_INSTALLER_NAME }}" $INPUT_FILE_PATH $OUTPUT_FILE_PATH
- name: Notarize Release Build PKG
uses: lando/notarize-action@v2
with:
product-path: $PATH_TO_PKG
appstore-connect-username: ${{ secrets.APPLE_ACCOUNT_USERNAME }}
appstore-connect-password: ${{ secrets.APPLE_ACCOUNT_PASSWORD }}
appstore-connect-team-id: FY8GAUX283 # if using notarytool
- name: "Staple Release Build"
uses: devbotsxyz/xcode-staple@v1
with:
product-path: $PATH_TO_PKG
[...]
编辑:Apple 上的公证工具已更新。之前,流程中使用了以下操作,但已从市场中删除:
- name: "Notarize Release Build PKG"
uses: devbotsxyz/xcode-notarize@v1
with:
product-path: $PATH_TO_PKG
appstore-connect-username: ${{ secrets.APPLE_ACCOUNT_USERNAME }}
appstore-connect-password: ${{ secrets.APPLE_ACCOUNT_PASSWORD }}
primary-bundle-id: 'BUNDLE_ID'