简介
本指南演示如何向持续集成 (CI) 工作流添加一个步骤,该步骤可在 GitHub Actions 运行器上安装 Apple 代码签名证书和配置文件。这将允许您为发布到 Apple App Store 或分发给测试组签署您的 Xcode 应用。
先决条件
您应该熟悉 YAML 和 GitHub Actions 的语法。更多信息,请参见
您应该了解 Xcode 应用构建和签名的知识。更多信息,请参见Apple 开发者文档。
为您的证书和配置文件创建密钥
签名过程涉及存储证书和配置文件,将它们传输到运行器,导入到运行器的密钥链中,并在您的构建中使用它们。
要在运行器上使用您的证书和配置文件,我们强烈建议您使用 GitHub 密钥。有关在工作流中创建密钥和使用密钥的更多信息,请参见"在 GitHub Actions 中使用密钥"。
为以下项目在您的仓库或组织中创建密钥
-
您的 Apple 签名证书。
-
这是您的
p12
证书文件。有关从 Xcode 导出签名证书的更多信息,请参见Xcode 文档。 -
保存为密钥时,应将证书转换为 Base64。在此示例中,密钥名为
BUILD_CERTIFICATE_BASE64
。 -
使用以下命令将您的证书转换为 Base64 并将其复制到剪贴板
base64 -i BUILD_CERTIFICATE.p12 | pbcopy
-
-
您的 Apple 签名证书的密码。
- 在此示例中,密钥名为
P12_PASSWORD
。
- 在此示例中,密钥名为
-
您的 Apple 配置文件。
-
有关从 Xcode 导出配置文件的更多信息,请参见Xcode 文档。
-
保存为密钥时,应将配置文件转换为 Base64。在此示例中,密钥名为
BUILD_PROVISION_PROFILE_BASE64
。 -
使用以下命令将您的配置文件转换为 Base64 并将其复制到剪贴板
base64 -i PROVISIONING_PROFILE.mobileprovision | pbcopy
-
-
密钥链密码。
- 将在运行器上创建一个新的密钥链,因此新密钥链的密码可以是任何新的随机字符串。在此示例中,密钥名为
KEYCHAIN_PASSWORD
。
- 将在运行器上创建一个新的密钥链,因此新密钥链的密码可以是任何新的随机字符串。在此示例中,密钥名为
向您的工作流添加步骤
此示例工作流包括一个步骤,该步骤从 GitHub 密钥导入 Apple 证书和配置文件,并将它们安装在运行器上。
name: App build on: push jobs: build_with_signing: runs-on: macos-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Install the Apple certificate and provisioning profile env: BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }} P12_PASSWORD: ${{ secrets.P12_PASSWORD }} BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }} KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} run: | # create variables CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db # import certificate and provisioning profile from secrets echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH # create temporary keychain security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH security set-keychain-settings -lut 21600 $KEYCHAIN_PATH security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH # import certificate to keychain security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH security list-keychain -d user -s $KEYCHAIN_PATH # apply provisioning profile mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles - name: Build app # ...
name: App build
on: push
jobs:
build_with_signing:
runs-on: macos-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install the Apple certificate and provisioning profile
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# import certificate and provisioning profile from secrets
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
# create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# import certificate to keychain
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
# apply provisioning profile
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
- name: Build app
# ...
注意
对于 iOS 构建目标,您的配置文件应具有扩展名.mobileprovision
。对于 macOS 构建目标,扩展名应为.provisionprofile
。上述示例工作流应更新以反映您的目标平台。
自托管运行器上的必需清理
GitHub 托管运行器是隔离的虚拟机,会在作业执行结束时自动销毁。这意味着在作业期间在运行器上使用的证书和配置文件将在作业完成后与运行器一起销毁。
在自托管运行器上,$RUNNER_TEMP
目录会在作业执行结束时清理,但密钥链和配置文件可能仍然存在于运行器上。
如果您使用自托管运行器,则应向您的工作流添加一个最终步骤,以帮助确保在作业结束时删除这些敏感文件。下面显示的工作流步骤是如何执行此操作的一个示例。
- name: Clean up keychain and provisioning profile
if: ${{ always() }}
run: |
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
rm ~/Library/MobileDevice/Provisioning\ Profiles/build_pp.mobileprovision