使用GitHub Actions在Match中自动创建iOS构建
为Capacitor应用设置CI/CD可能会很复杂和耗时。以下是您需要知道的内容:
新建推荐:使用Capgo Build
我们现在建议使用 Capgo 使用 Capgo CLI 构建 为原生 Capacitor 构建提供支持。 本 Fastlane Match 指南保留供维护现有 GitHub Actions pipeline 的团队使用,但新 iOS 构建应使用 Capgo CLI 以免自己维护 Fastlane、Match 仓库、Xcode 运行器、证书和上传脚本。
Capgo 使用 Capgo 构建 CI/CD
跳过 Fastlane Match、Xcode 运行器、证书、分发配置文件和上传脚本的维护。 Capgo 构建 从您的 CI/CD pipeline 运行签名的原生 iOS 构建:
- 与您的 pipeline 一起工作: 在您的 web 构建之后从 GitHub Actions、GitLab CI、Jenkins 或本地脚本中触发 Capgo 构建
npx cap sync. - 从 CI 秘密中签名: 在您的 CI 秘密中保留 App Store Connect 密钥、证书、分发配置文件、密码和团队 ID
- 无原生运行器维护: Capgo Build 提供维护的 Apple 构建环境,因此您不必管理 macOS 运行器、Xcode 图像、Fastlane 或 Match 仓库。
- Artifacts 和提交: 下载经过签名的 artifacts 用于 QA 或通过 Capgo CLI 提交发布版本。
定价
- Capgo 计划从 $12/月开始
- 包括 OTA 更新和约 15 个本地构建/月
- 额外的构建分钟通过信用额度按分钟计费
手动设置指南
以下是您需要做的事情:
使用 Fastlane 和 GitHub Actions 的 iOS 持续交付,使用 match
前置条件
继续教程之前…
- 确保你在开发机器上安装了Fastlane 在你的开发机器上安装了Fastlane iOS开发者计划会员资格
- 想看😆…
- 一家有很多开发者的公司,否则我们建议使用
- fastlane cert 简化工作流程的 关于价格的重要事项
价格__CAPGO_KEEP_0__ Action

https://github.com/features/actions
该服务在限制内是免费的,具体取决于所选择的机器。
我们将使用一个 macOS 机器,截图中显示了其价格和限制(截至教程创建时的价格,可能会在未来发生变化)
🔴 一旦警告了要求和价格,如果您喜欢,我们继续…
📣 在文章中,我们假设我们已经在 iTunes Connect 中创建了应用,我们有 Apple 生态系统的证书,Fastlane 将复制所有内容!
让我们深入!
文章中要遵循的步骤
- 使用 App Store Connect API 和 Fastlane Match
- 要求
- 创建 App Store Connect API 密钥
- 使用 App Store Connect API 密钥
- 快速复制Fastlane文件
- 配置Fastlane match
1. 使用App Store Connect API与Fastlane Match
从2021年2月开始,所有用户必须使用两步验证或两因素验证登录App Store Connect。这种额外的安全层对于您的Apple ID有助于确保您是唯一能够访问帐户的人。
来源 Apple Support
使用match进行初始设置需要撤销现有的证书。但是,您将直接获得新的证书。
要求
要能够使用App Store Connect API,Fastlane需要 三个 发行人ID
- three
- Key ID.
- Key 文件或Key 内容.
创建 App Store Connect API Key
要生成密钥,您必须在 App Store Connect 中具有管理员权限。如果您没有该权限,请将相关人员指向此文章并遵循以下说明。
1 — 登录到 App Store Connect.
2 — 选择 用户和访问.

3 — 选择

App Store Connect API 集成选项卡。

5 — 为此密钥输入一个名称。这个名称仅供您参考,不是密钥的一部分。

6 — 在 Access 下,选择此密钥的角色。密钥的角色与您的团队成员的角色相同。请参阅 角色权限。我们建议选择 应用管理者.
7 — 点击生成。
一个 API 密钥的访问权限不能仅限于特定的应用。
新密钥的名称、密钥 ID、下载链接和其他信息将出现在页面上。

您可以在这里获取所有三个必要的信息。
<1> 问题 ID.
<2> 密钥 ID.
<3> 点击“下载 API 密钥”下载您的 API 私有密钥。下载链接仅在私有密钥尚未下载时才会出现。苹果公司不会保留私有密钥的副本。因此,您只能下载一次。
🔴 将您的私有密钥存储在安全的地方。您不应共享您的密钥、将密钥存储在 code 仓库中或将密钥包含在客户端 code 中。
使用 App Store Connect API 密钥
创建 JWT 认证令牌所需的有 API 密钥文件(您下载的 p8 文件)、密钥 ID 和发行者 ID。这些信息可以通过多种方式输入到 Fastlane 中,使用 Fastlane 的新动作 app_store_connect_api_key。您可以学习其他方法在 Fastlane 文档中。
Now we can manage Fastlane with the App Store Connect API key, great!
现在我们可以使用 App Store Connect __CAPGO_KEEP_0__ 密钥管理 Fastlane,太棒了!
2. 复制 Fastlane 文件
在项目根目录下创建一个Fastlane文件夹,并复制以下文件: Fastfile
default_platform(:ios)
DEVELOPER_APP_IDENTIFIER = ENV["DEVELOPER_APP_IDENTIFIER"]
DEVELOPER_APP_ID = ENV["DEVELOPER_APP_ID"]
PROVISIONING_PROFILE_SPECIFIER = ENV["PROVISIONING_PROFILE_SPECIFIER"]
TEMP_KEYCHAIN_USER = ENV["TEMP_KEYCHAIN_USER"]
TEMP_KEYCHAIN_PASSWORD = ENV["TEMP_KEYCHAIN_PASSWORD"]
APPLE_ISSUER_ID = ENV["APPLE_ISSUER_ID"]
APPLE_KEY_ID = ENV["APPLE_KEY_ID"]
APPLE_KEY_CONTENT = ENV["APPLE_KEY_CONTENT"]
GIT_USERNAME = ENV["GIT_USERNAME"]
GIT_TOKEN = ENV["GIT_TOKEN"]
def delete_temp_keychain(name)
delete_keychain(
name: name
) if File.exist? File.expand_path("~/Library/Keychains/#{name}-db")
end
def create_temp_keychain(name, password)
create_keychain(
name: name,
password: password,
unlock: false,
timeout: 0
)
end
def ensure_temp_keychain(name, password)
delete_temp_keychain(name)
create_temp_keychain(name, password)
end
platform :ios do
lane :build do
build_app(
configuration: "Release",
workspace: "./ios/App/App.xcworkspace",
scheme: "App",
export_method: "app-store",
export_options: {
provisioningProfiles: {
DEVELOPER_APP_ID => "#{PROVISIONING_PROFILE_SPECIFIER}"
}
}
)
end
lane :refresh_profiles do
match(
type: "development",
force: true)
match(
type: "adhoc",
force: true)
end
desc "Register new device"
lane :register_new_device do |options|
device_name = prompt(text: "Enter the device name: ")
device_udid = prompt(text: "Enter the device UDID: ")
device_hash = {}
device_hash[device_name] = device_udid
register_devices(
devices: device_hash
)
refresh_profiles
end
lane :closed_beta do
keychain_name = TEMP_KEYCHAIN_USER
keychain_password = TEMP_KEYCHAIN_PASSWORD
ensure_temp_keychain(keychain_name, keychain_password)
api_key = app_store_connect_api_key(
key_id: APPLE_KEY_ID,
issuer_id: APPLE_ISSUER_ID,
key_content: APPLE_KEY_CONTENT,
duration: 1200,
in_house: false
)
match(
type: 'appstore',
git_basic_authorization: Base64.strict_encode64("#{GIT_USERNAME}:#{GIT_TOKEN}"),
readonly: true,
keychain_name: keychain_name,
keychain_password: keychain_password,
api_key: api_key
)
gym(
configuration: "Release",
workspace: "./ios/App/App.xcworkspace",
scheme: "App",
export_method: "app-store",
export_options: {
provisioningProfiles: {
DEVELOPER_APP_ID => "#{PROVISIONING_PROFILE_SPECIFIER}"
}
}
)
pilot(
apple_id: "#{DEVELOPER_APP_ID}",
app_identifier: "#{DEVELOPER_APP_IDENTIFIER}",
skip_waiting_for_build_processing: true,
skip_submission: true,
distribute_external: false,
notify_external_testers: false,
ipa: "./App.ipa"
)
delete_temp_keychain(keychain_name)
end
lane :submit_review do
version = ''
Dir.chdir("..") do
file = File.read("package.json")
data = JSON.parse(file)
version = data["version"]
end
deliver(
app_version: version,
submit_for_review: true,
automatic_release: true,
force: true, # Skip HTMl report verification
skip_metadata: false,
skip_screenshots: false,
skip_binary_upload: true
)
end
end
Appfile
app_identifier(ENV["DEVELOPER_APP_IDENTIFIER"])
apple_id(ENV["FASTLANE_APPLE_ID"])
itc_team_id(ENV["APP_STORE_CONNECT_TEAM_ID"])
team_id(ENV["DEVELOPER_PORTAL_TEAM_ID"])
配置Fastlane match
Fastlane match 是iOS的code签名的新方法。Fastlane match使团队能够轻松管理iOS应用所需的证书和配置文件。
创建一个名为 certificates,例如在您的GitHub个人账户或组织中。
初始化Fastlane match为您的iOS应用。
fastlane match init
然后选择选项#1(Git存储)。
[01:00:00]: fastlane match supports multiple storage modes, please select the one you want to use:1. git2. google_cloud3. s3?
将新创建的仓库的URL assignments。
[01:00:00]: Please create a new, private git repository to store the certificates and profiles there[01:00:00]: URL of the Git Repo: <YOUR_CERTIFICATES_REPO_URL>
现在您在Fastlane文件夹中有一个名为 Matchfile应设置为证书仓库的HTTPS URL。 optionally,您也可以使用SSH,但这需要一个不同的步骤来运行。 下一步,我们将生成证书并在Fastlane Match中输入您的凭据。
_git_url_您将被要求输入一个密语。请正确记住它,因为它将在__CAPGO_KEEP_0__ Actions中用来解密您的证书仓库。
# ios/Matchfilegit_url("https://github.com/gitusername/certificates")storage_mode("git")type("appstore")
如果一切顺利,您应该看到类似这样的内容:
如果您在GitHub和必要的权限方面遇到任何问题,可能这个
fastlane match appstore
帖子
[01:40:52]: All required keys, certificates and provisioning profiles are installed 🙌
If you experienced any problem with GitHub and the necessary permissions, maybe this 生成的证书和配置文件将上传到证书仓库资源中 App Store Connect证书
最后,打开您的

资源 project 在 Xcode 中,并更新您的应用程序的发布配置的分发配置文件。

注意事项 💡
MATCH
为了让 CI/CD 能够导入证书和分发配置文件,它需要访问证书仓库。您可以通过生成一个个人访问令牌(应在此之前使用),该令牌具有访问或读取私有仓库的权限。
在 GitHub 中,前往 设置 → 开发者设置 → 个人访问令牌 → 点击 Generate New Token → 勾选 repo 权限范围 → 然后点击 Generate token.

请保留生成的个人访问令牌,稍后将其用于环境变量 GIT_TOKEN.
然后用 Matchfile替换Fastlane文件夹中生成的匹配文件
CERTIFICATE_STORE_URL = ENV["CERTIFICATE_STORE_URL"]
GIT_USERNAME = ENV["GIT_USERNAME"]
GIT_TOKEN = ENV["GIT_TOKEN"]
FASTLANE_APPLE_ID = ENV["FASTLANE_APPLE_ID"]
git_url(CERTIFICATE_STORE_URL)
storage_mode("git")
type("appstore")
git_basic_authorization(Base64.strict_encode64("#{GIT_USERNAME}:#{GIT_TOKEN}"))
username(FASTLANE_APPLE_ID)
此文件将由GitHub Actions用于导入证书和配置文件。 并且变量将在GitHub Secrets中设置,而不是在文件中硬编码。
构建处理
在GitHub Actions中, 您按分钟计费 您用于运行CI/CD工作流的分钟数。从经验来看,需要约10-15分钟才能在App Store Connect中处理构建。
对于私有项目,估计每个构建的成本最高可达 $0.08/分钟 x 15 分钟 = $1.2,或更多,具体取决于您的项目的配置或依赖项。
如果您对私有项目的定价有同样的担忧,就像我一样,可以保留 skip_waiting_for_build_processing to true.
什么是陷阱呢?您必须手动更新应用程序在 App Store Connect 中的合规性,才能将构建分发给您的用户。
这是一个可选参数,用于更新,如果您想节省私有项目的构建分钟数。对于免费项目来说,这完全不是问题。 pricing.
3. 配置 GitHub 动作
配置 GitHub 秘密
您曾经想知道这些值是从哪里来的吗?现在不用再问了,它们来自您的项目的秘密。 ENV 设置 __CAPGO_KEEP_0__ 秘密

1. APP_STORE_CONNECT_TEAM_ID - 在 App Store Connect 中,转到应用程序 →
2. DEVELOPER_APP_ID App 信息 - → 到您的应用程序的 General Information 部分并寻找 Apple ID.
3. DEVELOPER_APP_IDENTIFIER - 应用程序的捆绑标识符。
4. DEVELOPER_PORTAL_TEAM_ID - 如果您属于多个团队,则您的开发者门户团队 ID。
5. FASTLANE_APPLE_ID - 您用于管理应用程序的 Apple ID 或开发者电子邮件。
6. GIT_USERNAME & GIT_TOKEN - 你的 Git 用户名和你的个人访问令牌。
7. MATCH_PASSWORD - 初始化匹配时分配的密钥,用于解密证书和配置文件。
8. PROVISIONING_PROFILE_SPECIFIER - match AppStore <YOUR_APP_BUNDLE_IDENTIFIER>例如 match AppStore com.domain.blabla.demo.
9. TEMP_KEYCHAIN_USER & TEMP_KEYCHAIN_PASSWORD - 为您的工作流分配一个临时密钥链用户和密码。
10. APPLE_KEY_ID — App Store Connect API Key 🔺Key ID.
11. APPLE_ISSUER_ID — App Store Connect API Key 🔺证书颁发者 ID。
12. APPLE_KEY_CONTENT — App Store Connect API Key 🔺 证书文件或证书内容。 .p8, 检查它
13. CERTIFICATE_STORE_URL — 你的 Match keys 的仓库 URL(例如: https://github.com/***/fastlane_match.git)
4. 配置 GitHub 工作流文件
创建一个 GitHub 工作流目录
cd .github/workflows
在这个目录里,创建一个名为 workflow 的文件,并添加以下内容 build-upload-ios.yml这个工作流应该在每次 __CAPGO_KEEP_0__ 后触发
name: Build source code on ios
on:
push:
tags:
- '*'
jobs:
build_ios:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v6
- name: set Node.js
uses: actions/setup-node@v6
with:
node-version: '24'
cache: npm
- name: Install dependencies
id: install_code
run: npm ci
- name: Build
id: build_code
run: npm run build
- uses: actions/cache@v5
with:
path: ios/App/Pods
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
- name: Sync
id: sync_code
run: npx cap sync
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.7.2
- uses: maierj/fastlane-action@v2.3.0
env:
DEVELOPER_APP_IDENTIFIER: ${{ secrets.DEVELOPER_APP_IDENTIFIER }}
DEVELOPER_APP_ID: ${{ secrets.DEVELOPER_APP_ID }}
PROVISIONING_PROFILE_SPECIFIER: match AppStore ${{ secrets.DEVELOPER_APP_IDENTIFIER }}
TEMP_KEYCHAIN_USER: ${{ secrets.TEMP_KEYCHAIN_USER }}
TEMP_KEYCHAIN_PASSWORD: ${{ secrets.TEMP_KEYCHAIN_PASSWORD }}
APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
APPLE_KEY_CONTENT: ${{ secrets.APPLE_KEY_CONTENT }}
CERTIFICATE_STORE_URL: https://github.com/${{ secrets.CERTIFICATE_STORE_REPO }}.git
GIT_USERNAME: ${{ secrets.GIT_USERNAME }}
GIT_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
FASTLANE_APPLE_ID: ${{ secrets.FASTLANE_APPLE_ID }}
MATCH_USERNAME: ${{ secrets.FASTLANE_APPLE_ID }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
APP_STORE_CONNECT_TEAM_ID: ${{ secrets.APP_STORE_CONNECT_TEAM_ID }}
DEVELOPER_PORTAL_TEAM_ID: ${{ secrets.DEVELOPER_PORTAL_TEAM_ID }}
with:
lane: closed_beta
- name: Upload release bundle
uses: actions/upload-artifact@v2
with:
name: ios-release
path: ./App.ipa
retention-days: 60
— 你的 Match keys 的仓库 URL(例如:https://GitHub.com/***/fastlane_match.git 标签, 如果您需要自动化标签,请参阅 自动构建和发布与 GitHub 动作 第一步。
然后,这个工作流程将拉取您的 NodeJS 依赖项,安装它们并构建您的 JavaScript 应用程序。
每次您发送新的提交时,测试飞行中的发布将被构建。
您的应用程序不需要使用Ionic,只需 Capacitor 基础即可,它可以具有旧的Cordova模块,但 Capacitor JS插件应优先使用。
5. 触发工作流程
创建一个提交
制作一个 提交, 您应该在仓库中看到正在活动的工作流程。
触发工作流
推送新提交到分支 main 或 development 以触发工作流

几分钟后,构建应该可在 App Store Connect 控制台中找到。

是否可以从本地机器部署?
是的,您可以,而且这很容易。
假设您有一个私有仓库,已经用完了免费计划的分钟数,并且不想为新发布支付费用,或者您更喜欢手动提交应用程序。
让我们开始
好,首先我们需要创建 My项目路径/fastlane 路径一个名为 .env, 与Fastfile在同一路径 为了能够创建相同的 机密 在我们的___CAPGO_KEEP_0__中找到以下属性: properties found in our _GitHub, a_s below:
现在,您可以转到
终端 并启动 and launch the 快速通道 从您的机器上:
fastlane closed_beta
❌ 关于快速通道的基本信息 .env 文件,因为我们不想暴露此数据,我们必须在我们的 .gitignore,类似于这样: ❌
fastlane/*.env
它应该与在远程机器上的 GitHub Actions 上发生的相同,但是在我们的本地机器上。 🍻

终端执行: $ Fastlane closed_beta
如果您已经走到这一步,我恭喜您,现在您已经拥有了使用快速通道和 GitHub Actions 来自动化您的 iOS 应用程序的完全自动化过程。
每次您发送新的提交,Google Play 控制台中的 beta 频道中将会构建一个新版本。 我会根据您的反馈来改进这篇博客,如果您有任何问题或建议,请通过电子邮件联系我 martin@capgo.app
在设备上构建
如果您仍需要在设备上构建,请手动将它们添加到配置文件中。
连接您的设备到您的Mac并打开设备菜单
然后复制您的标识符
然后启动命令:
fastlane register_new_device
它会要求您设置设备名称和标识符:

如果您遇到问题
如果您遇到开发设备无法测试等问题,通常会解决它。
有一个神奇的命令可以拯救您:
fastlane match nuke development
fastlane match development
然后: 清理项目,按住 Shift(⇧)+Command(⌘)+K 或选择 Product > Clean(它可能标记为“清理构建文件夹”)
然后再次尝试在您的设备上运行应用程序。
感谢
本博客基于以下文章:
从自动 Capacitor IOS 构建中继续,使用 GitHub 动作和 match
如果您正在使用 自动 Capacitor IOS 构建,使用 GitHub 动作和 match 规划 CI/CD 自动化时,如果您正在使用 Capgo CI/CD 为产品工作流程在Capgo CI/CD中 Capgo 本机构建 为产品工作流程在Capgo 本机构建中 Capgo 集成 为产品工作流程在Capgo 集成中 CI/CD 集成 CI/CD 集成的实现细节中, GitHub 动作集成 为GitHub 动作集成的实现细节