跳转到正文

GitHub 操作

直接从你的 GitHub 仓库自动化 iOS 和 Android 构建。只需一个 workflow 文件和几个 repository secrets,每次 push、tag 或手动触发都能产出已签名、可直接上架的应用——团队里没人需要 Mac、Xcode 或 Android Studio。

简而言之: 要在 GitHub Actions 上配置 Capacitor CI/CD,只需添加一个工作流来运行 Capgo CLI:Capgo Builder 会生成已签名的 iOS 和 Android 构建,并可将其上传至应用商店;此外,通过增加一个 bundle upload 任务(参见 自动 OTA 或原生),同一工作流还可以将仅涉及 Web 的变更作为 Capgo Live Update 发布。

全自动发布

在 Git 中给 release 打 tag,已签名的 iOS 和 Android 二进制文件就会自动提交到 TestFlight 和 Play Store。

无需本地配置

使用 Windows 或 Linux 的贡献者也能触发 iOS 构建。不用 Xcode,不用折腾 provisioning,也不用让签名证书在各自的笔记本之间传来传去。

限定作用域的 Secrets

凭据存放在 GitHub repository secrets 中,作用域仅限于你的仓库,且仅对 workflow runner 可见。轮换方便,审计也方便。

并行构建

用 matrix job 同时构建 iOS 和 Android。一次典型的发布不到 10 分钟就能完成。

在配置工作流之前,请确保您已准备好:

  • 一个已开通有效订阅的 Capgo 账号,以及 Capgo API 密钥
  • 您的应用已在 Capgo 中注册(bunx @capgo/cli@latest app add 如未注册)
  • 已通过以下方式在本地配置好构建凭据: bunx @capgo/cli@latest build init — 请参阅 凭据管理 查看向导操作步骤
  • 本地构建成功(bunx @capgo/cli@latest build request com.example.app --platform android --build-mode debug) — CI 不是调试首次构建的地方
  • 本指南中介绍的 GitHub CLI (gh) 已安装并认证 (gh auth login)

Capgo CLI 可以将您的本地凭据导出为可直接使用的 .env 文件。结合 gh secret set -f,整个 CI/CD 配置只需三条命令——无需手动 base64 编码,无需处理 JSON,也无需逐个复制粘贴密钥。

  1. 将您的 Capgo API 密钥添加为仓库密钥

    API 密钥不属于每个应用的凭据存储,因此需要手动添加一次:

    终端窗口
    gh secret set CAPGO_TOKEN --body "your_capgo_api_key_here"

    在 Capgo 控制台 配合 上传 权限或更高权限中生成密钥。

  2. 将您的凭据导出到 .env 文件

    运行交互式凭据管理器:

    终端窗口
    bunx @capgo/cli@latest build credentials manage --appId com.example.app

    在 TUI 中,选择 导出到 .env。CLI 写入 .env.capgo.<appId> 到当前目录,权限模式为 0600 (仅所有者可读)——例如, .env.capgo.com.example.app。当同时配置了 iOS 和 Android 时,两个平台的密钥都会写入同一文件,位于 # === IOS === 以及 # === ANDROID === 部分标题下。iOS 和 Android 的环境变量名互不重叠,因此合并使用不会产生冲突。

  3. 将 .env 文件推送到 GitHub Actions 密钥

    本指南中介绍的 gh secret set -f 命令读取 dotenv 文件,并为每个 KEY=value 行创建一个仓库密钥:

    终端窗口
    gh secret set -f .env.capgo.com.example.app

    搞定——你的工作流所需的所有密钥现在都在 GitHub 中。使用以下命令验证: gh secret list.

  4. 创建 workflow 文件

    添加 .github/workflows/capgo-build.yml 到你的仓库。根据你想触发 build 的方式,从以下三种触发模式中选择一种。

供参考: gh secret set -f 会创建以下 repository secrets(你的 workflow YAML 会用这些确切的名称引用它们):

平台已创建的 Secrets
iOSBUILD_CERTIFICATE_BASE64, P12_PASSWORD, CAPGO_IOS_PROVISIONING_MAP_BASE64, APPLE_KEY_ID, APPLE_ISSUER_ID, APPLE_KEY_CONTENT, APP_STORE_CONNECT_TEAM_ID
AndroidANDROID_KEYSTORE_FILE, KEYSTORE_KEY_ALIAS, KEYSTORE_KEY_PASSWORD, KEYSTORE_STORE_PASSWORD, PLAY_CONFIG_JSON
(手动添加)CAPGO_TOKEN

你不需要记住这些 —— 下面的 workflow 示例已经全部引用了它们。

以下三个示例覆盖了最常见的模式。它们流程相同:检出仓库、安装依赖、构建 Web 资源、同步到原生,然后通过环境变量传入凭据,调用 Capgo Build。

让任何有写权限的人通过 操作 选项卡在 GitHub 中直接触发构建,并可通过下拉菜单选择平台。适合临时测试构建,或按需发起发布。

.github/workflows/capgo-build-manual.yml
name: Capgo Build (Manual)
on:
workflow_dispatch:
inputs:
platform:
description: 'Platform to build'
required: true
default: 'android'
type: choice
options: [ios, android, both]
mode:
description: 'Build mode'
required: true
default: 'debug'
type: choice
options: [debug, release]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install --frozen-lockfile
- run: bun run build
- run: bunx cap sync
- name: Trigger Capgo Build
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
CAPGO_IOS_PROVISIONING_MAP_BASE64: ${{ secrets.CAPGO_IOS_PROVISIONING_MAP_BASE64 }}
APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
APPLE_KEY_CONTENT: ${{ secrets.APPLE_KEY_CONTENT }}
APP_STORE_CONNECT_TEAM_ID: ${{ secrets.APP_STORE_CONNECT_TEAM_ID }}
ANDROID_KEYSTORE_FILE: ${{ secrets.ANDROID_KEYSTORE_FILE }}
KEYSTORE_KEY_ALIAS: ${{ secrets.KEYSTORE_KEY_ALIAS }}
KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }}
KEYSTORE_STORE_PASSWORD: ${{ secrets.KEYSTORE_STORE_PASSWORD }}
PLAY_CONFIG_JSON: ${{ secrets.PLAY_CONFIG_JSON }}
run: |
bunx @capgo/cli@latest build request com.example.app \
--platform ${{ inputs.platform }} \
--build-mode ${{ inputs.mode }}

替换 com.example.app 使用你的应用 ID。提交后,前往 Actions → Capgo Build (Manual) → 运行工作流 以触发它。

每次推送类似 v1.4.0的版本标签时,都会并行构建并发布两个平台。这是最常见的生产环境配置—— git tag v1.4.0 && git push --tags 将成为你的发布命令。

.github/workflows/capgo-build-release.yml
name: Capgo Build (Release)
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform: [ios, android]
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install --frozen-lockfile
- run: bun run build
- run: bunx cap sync ${{ matrix.platform }}
- name: Build ${{ matrix.platform }}
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
# iOS
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
CAPGO_IOS_PROVISIONING_MAP_BASE64: ${{ secrets.CAPGO_IOS_PROVISIONING_MAP_BASE64 }}
APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
APPLE_KEY_CONTENT: ${{ secrets.APPLE_KEY_CONTENT }}
APP_STORE_CONNECT_TEAM_ID: ${{ secrets.APP_STORE_CONNECT_TEAM_ID }}
# Android
ANDROID_KEYSTORE_FILE: ${{ secrets.ANDROID_KEYSTORE_FILE }}
KEYSTORE_KEY_ALIAS: ${{ secrets.KEYSTORE_KEY_ALIAS }}
KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }}
KEYSTORE_STORE_PASSWORD: ${{ secrets.KEYSTORE_STORE_PASSWORD }}
PLAY_CONFIG_JSON: ${{ secrets.PLAY_CONFIG_JSON }}
run: |
bunx @capgo/cli@latest build request com.example.app \
--platform ${{ matrix.platform }} \
--build-mode release

矩阵在独立的 runner 上并行运行 iOS 和 Android。设置 fail-fast: false 意味着 iOS 构建失败不会取消正在进行的 Android 构建(反之亦然)——当某个平台出现临时签名问题时非常有用。

3. 推送到 Main 分支时执行 Debug Build

章节标题为“3. 推送到 Main 分支时执行 Debug Build”

通过在每次推送到 main。运行成本低,反馈快,而且可以跳过 Play Store 上传,让它纯粹作为冒烟测试。

.github/workflows/capgo-build-main.yml
name: Capgo Build (Main)
on:
push:
branches: [main]
paths:
- 'src/**'
- 'android/**'
- 'ios/**'
- 'package.json'
- 'capacitor.config.*'
jobs:
smoke-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install --frozen-lockfile
- run: bun run build
- run: bunx cap sync android
- name: Smoke build (Android debug)
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
ANDROID_KEYSTORE_FILE: ${{ secrets.ANDROID_KEYSTORE_FILE }}
KEYSTORE_KEY_ALIAS: ${{ secrets.KEYSTORE_KEY_ALIAS }}
KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }}
KEYSTORE_STORE_PASSWORD: ${{ secrets.KEYSTORE_STORE_PASSWORD }}
run: |
bunx @capgo/cli@latest build request com.example.app \
--platform android \
--build-mode debug \
--no-playstore-upload \
--output-upload

本指南中介绍的 paths filter 确保工作流不会在仅文档变更时运行。 --no-playstore-upload 跳过 Play Store 提交(无需 PLAY_CONFIG_JSON ),并且 --output-upload 生成 APK 的下载 URL,以便在测试设备上安装。

对于测试构建,请跳过商店提交:Android 使用 --no-playstore-upload;对于 iOS,请以 ad-hoc 模式构建,并使用 --ios-distribution ad_hoc (该模式不会提交到 App Store)。将任一方式与 --output-upload 结合使用,即可获取该二进制文件的限时下载 URL。

默认情况下,release 构建会上传签名后的产物,并将最终的商店操作交由您控制。对于需要直接进入商店审核流程的 CI 发布,请添加 --submit-to-store-review.

Android 使用您的 PLAY_CONFIG_JSON 服务账号。 如果没有显式指定 track, --submit-to-store-review 默认使用 production track,并 release_status: completed. 建议在调用处明确指定 track,使用 --android-track (或 PLAY_STORE_TRACK),并在需要时通过 --android-release-status / PLAY_STORE_RELEASE_STATUS 覆盖状态:

- name: Submit Android release for review
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
ANDROID_KEYSTORE_FILE: ${{ secrets.ANDROID_KEYSTORE_FILE }}
KEYSTORE_KEY_ALIAS: ${{ secrets.KEYSTORE_KEY_ALIAS }}
KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }}
KEYSTORE_STORE_PASSWORD: ${{ secrets.KEYSTORE_STORE_PASSWORD }}
PLAY_CONFIG_JSON: ${{ secrets.PLAY_CONFIG_JSON }}
run: |
npx @capgo/cli@latest build request com.example.app \
--platform android \
--build-mode release \
--submit-to-store-review \
--android-track production \
--store-release-name "${GITHUB_REF_NAME}" \
--store-release-notes "Release ${GITHUB_REF_NAME}" \
--store-release-notes-locale "en-US=Release ${GITHUB_REF_NAME}"

对于内部完成的发布(而非 production):

- name: Submit Android internal release
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
ANDROID_KEYSTORE_FILE: ${{ secrets.ANDROID_KEYSTORE_FILE }}
KEYSTORE_KEY_ALIAS: ${{ secrets.KEYSTORE_KEY_ALIAS }}
KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }}
KEYSTORE_STORE_PASSWORD: ${{ secrets.KEYSTORE_STORE_PASSWORD }}
PLAY_CONFIG_JSON: ${{ secrets.PLAY_CONFIG_JSON }}
run: |
npx @capgo/cli@latest build request com.example.app \
--platform android \
--build-mode release \
--submit-to-store-review \
--android-track internal \
--store-release-name "${GITHUB_REF_NAME}"

iOS 使用 App Store Connect 的 API 密钥路径,并将处理后的 TestFlight 构建提交至 App Store 审核。这需要 app_store 分发; --ios-testflight-groups 对外部 Beta 分发是可选的,App Store 审核不需要:

- name: Submit iOS build to App Store review
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
CAPGO_IOS_PROVISIONING_MAP: ${{ secrets.CAPGO_IOS_PROVISIONING_MAP }}
APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
APPLE_KEY_CONTENT: ${{ secrets.APPLE_KEY_CONTENT }}
APP_STORE_CONNECT_TEAM_ID: ${{ secrets.APP_STORE_CONNECT_TEAM_ID }}
run: |
npx @capgo/cli@latest build request com.example.app \
--platform ios \
--build-mode release \
--ios-distribution app_store \
--submit-to-store-review \
--store-release-name "${GITHUB_REF_NAME}" \
--store-release-notes "Release ${GITHUB_REF_NAME}" \
--store-release-notes-locale "en-US=Release ${GITHUB_REF_NAME}" \
--no-ios-automatic-release

传入 --output-record <path> 在构建成功时将构建产物 URL 和 QR code 持久化到磁盘,然后在后续步骤中读取 build last-output。无需抓取日志,无需正则表达式。

- name: Build
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
# ...credentials...
run: |
bunx @capgo/cli@latest build request com.example.app \
--platform android --build-mode debug \
--output-upload --output-retention 1d \
--output-record /tmp/build.json
- name: Comment on PR with build URL
env:
GH_TOKEN: ${{ github.token }}
run: |
URL=$(bunx @capgo/cli@latest build last-output --path /tmp/build.json --field outputUrl)
if [ -n "$URL" ]; then
gh pr comment ${{ github.event.pull_request.number }} \
--body "Debug build ready: $URL"
fi

--output-record /tmp/build.json 写入一条 JSON 记录(包含 jobId, status, outputUrl, qrCodeAscii, qrCodePngPath, finishedAt) 以及旁边的 PNG 格式 code /tmp/build.json.qr.png. build last-output 读取该文件:

  • --field outputUrl 仅打印下载 URL(以换行符结尾;适用于 URL=$(...)).
  • --field qrCodePngPath 打印 PNG 文件路径,以便将其作为 PR 附件上传。
  • --qr 打印渲染后的 ASCII QR 码——将其放入 PR 评论中的 Markdown code 代码块内,即可实现内联扫描。

默认情况下,每次发布构建都会递增构建号。若要将其固定为您控制的值(例如 Git 标签),请传入 --skip-build-number-bump:

- name: Set version from tag
run: |
VERSION="${GITHUB_REF#refs/tags/v}"
# Update package.json or your version source here
bun pm version "$VERSION" --no-git-tag-version
- name: Build
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
# ...credentials...
run: |
bunx @capgo/cli@latest build request com.example.app \
--platform ios --build-mode release \
--skip-build-number-bump

bun install 本身已经足够快,JS 依赖缓存通常收益不大,但 Capacitor 的原生依赖(CocoaPods、Gradle)在大型项目中值得缓存:

- uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
ios/App/Pods
android/.gradle
key: ${{ runner.os }}-capgo-${{ hashFiles('**/bun.lock', '**/Podfile.lock') }}
现象可能原因
CAPGO_TOKEN is not set未添加 Secret,或 job 无权访问(检查 environment/branch protections)
iOS / Android 凭据缺失报错gh secret set -f 未运行,或针对的是其他仓库。请使用以下命令验证: gh secret list
cap sync CI 中失败但本地正常原生插件未包含在 package.json,或者你忘了 bun install 在……之前 cap sync
Build 成功但 App Store Connect 中看不到 AppTeam ID 错误,或 App Store Connect 中尚不存在该 App 记录。请在本地用以下命令验证: bunx @capgo/cli@latest build credentials manage
Build 在 “Uploading project” 之后卡住项目归档异常大 —— 请检查是否 node_modules 没有被上传(默认情况下不应上传)
Provisioning profile doesn't match bundle IDProvisioning map 指向的 Bundle ID 与 Xcode 正在签名的不一致。请重新运行 build init 以刷新 profile,然后用以下命令重新导出: build credentials manage
本地凭据已更改,但 CI 仍然失败别忘了重新导出并重新推送: bunx @capgo/cli@latest build credentials manage → gh secret set -f .env.capgo.<appId>
Manager 拒绝写入合并后的文件各平台的共享配置键不一致 —— Manager 会警告并要求确认。可以确认采用覆盖(一方胜出),或按平台重新导出: --platform ios / --platform android
build last-output 打印出的 URL 为空Build 未通过 --output-upload,或者在生成产物之前就失败了。 outputUrl 将是 null 在记录中。根据……分支 [ -n "$URL" ] 在使用前
build last-output 报错: Unsupported record schemaVersionRunner 使用的 CLI 版本低于写入该记录的版本。请将生产端和读取端都固定为相同的显式版本(例如 bunx @capgo/cli@7.104.0 … 在两端都指定 @latest,因为该版本会浮动,且可能在不同作业间产生偏差

有关平台特定的构建失败,请参阅 故障排查指南.