每个移动端开发团队都经历过这种痛苦:功能已经开发完成准备评审,但要让利益相关者看到,却必须在 TestFlight 或 Google Play beta 审核的迷宫中周旋。原本几分钟就能搞定的事情,变成了数小时的等待、安装和管理 beta 版本。
如果你的生产环境 App 可以直接从任何 pull request 中获取最新更改并同步到设备上,而无需重新安装或等待 App Store 审核,那会怎样?
这就是 PR 预览 启用。当开发者提交 Pull Request 时,GitHub Action 会创建一个专属的更新频道并发布更改。任何已安装 App 的用户都可以切换到该频道进行功能测试,完成后再切回原频道——全程无需离开现有的 App。
TestFlight 的痛点
传统的移动端功能测试流程通常如下:
- 开发者提交 PR - Code 等待评审
- 等待 TestFlight - 15-30 分钟的处理时间
- 查找并安装 - 测试人员需寻找正确的 Build
- 测试并重复 - 每次更改都意味着新一轮等待
这造成了流程瓶颈。QA 因等待 Build 而被阻塞;产品经理无法快速验证功能;开发者在等待反馈时会丢失开发上下文。据行业估算,这因生产力损失导致每个 PR 平均成本高达 340 美元。
PR Preview 的工作原理
PR preview 利用 Capgo 的 channel 系统为每个 PR 创建独立的 update 流。流程如下:
- PR 已开启或已更新 - 触发 GitHub Action
- Bundle 已上传 - 您的 JS/CSS 变更将发送至该 PR 专属的 channel
- 已发布评论 - 测试人员会在 PR 中收到操作指南
- 即时测试 - 切换 channel 进行测试,完成后切回
无需重新安装 App,无需等待 TestFlight。同一个生产环境 App 即可从不同的 update channel 获取更新。
配置 PR Previews
在实现 PR 预览之前,您的项目需要配置好 Capgo Live Updates。请参考 Capgo 快速入门指南 (如果您尚未完成配置)。
GitHub Actions 工作流
创建 .github/workflows/pr-preview.yml:
name: PR Preview
on:
pull_request:
types: [opened, synchronize]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Setup Bun
uses: oven-sh/setup-bun@v2
- name: Install Dependencies
run: bun install
- name: Build
run: bun run build
# Create a channel named after your PR (may already exist on synchronize)
- name: Create PR Channel
id: create_channel
continue-on-error: true
run: bunx @capgo/cli@latest channel add pr-${{ github.event.pull_request.number }} --self-assign
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
# Upload the build to that channel
- name: Upload to Capgo
run: bunx @capgo/cli@latest bundle upload --channel pr-${{ github.event.pull_request.number }}
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
# Post a comment with testing instructions (only on PR open)
- name: Comment on PR
if: github.event.action == 'opened'
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: ${{ github.event.pull_request.number }},
body: '📱 **Test this PR on device:**\n\nOpen your app and switch to channel: `pr-${{ github.event.pull_request.number }}`\n\nUse the shake menu or call `setChannel()` from your app.'
})
关键在于创建 channel 时使用 --self-assign flag。这允许测试人员在 App 内通过使用以下方式切换到该 channel: setChannel() API。
配置 Capgo Token
- 前往你的 Capgo 控制台
- 前往 Settings > API Keys
- 使用以下方式生成新密钥:
all权限 - 将其添加为
CAPGO_TOKEN至你的 GitHub 仓库 Secrets 中
测试人员如何切换 Channel
测试人员有两种方式可以切换到 PR channel:
方案 1:Shake Menu(最简单)
在你的 Capacitor 配置中启用带 channel 选择器的 shake menu:
// capacitor.config.ts
const config: CapacitorConfig = {
// ... your other config
plugins: {
CapacitorUpdater: {
shakeMenu: true,
allowShakeChannelSelector: true
}
}
};
测试人员通过摇晃设备打开 debug menu,其中会显示带有搜索栏的可用 channel 列表。找到对应的 PR channel(例如: pr-123),点击选择,应用即可自动下载并应用更新。测试完成后,再次摇晃设备并切回 production 即可。
Shake menu 会自动处理整个流程:
- 通过以下方式获取所有可自选的 channel:
listChannels() - 支持搜索功能的 Channel 列表,快速定位特定 PR
- 选中后下载更新
- 弹出 Reload 提示,提供 “Reload Now” 或 “Later” 选项
方案 2:自定义 Channel 选择器 UI
在 App 中内置一个 Channel 切换器,列出所有可用的 PR Channel 并供测试人员选择。这需要用到两个核心 API:
listChannels()- 获取所有启用了 self-assignment 的 ChannelsetChannel()- 将设备切换至选定的 Channel
import { CapacitorUpdater } from '@capgo/capacitor-updater';
// Get all available channels (including PR channels)
async function getAvailableChannels() {
const { channels } = await CapacitorUpdater.listChannels();
// Filter to show only PR channels
const prChannels = channels.filter(c => c.name.startsWith('pr-'));
return prChannels;
}
// Switch to a specific PR channel
async function switchToChannel(channelName: string) {
await CapacitorUpdater.setChannel({
channel: channelName,
triggerAutoUpdate: true // Immediately check for updates
});
}
// Return to production
async function switchBackToProduction() {
await CapacitorUpdater.unsetChannel({});
}
// Get current channel
async function getCurrentChannel() {
const { channel } = await CapacitorUpdater.getChannel();
return channel;
}
利用这些基础组件,你可以构建一个简单的 UI:
// Example: List PR channels and let user select
const channels = await getAvailableChannels();
const current = await getCurrentChannel();
// Display channels in your UI
channels.forEach(channel => {
console.log(`${channel.name} ${channel.name === current ? '(current)' : ''}`);
});
// When user selects a channel
await switchToChannel('pr-123');
如需完整的 React 组件示例,请参阅 我们的 Channel 浏览指南.
清理 PR Channel
当 PR 被合并或关闭时,需要清理对应的 Channel。可以添加另一个 workflow:
name: Cleanup PR Preview
on:
pull_request:
types: [closed]
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Delete PR Channel
run: bunx @capgo/cli@latest channel delete pr-${{ github.event.pull_request.number }}
env:
CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}
PR 关闭时会自动移除该 channel,保持 channel 列表整洁。
版本兼容性
只有当 JavaScript bundle 与已安装的 native 版本兼容时,PR preview 才能工作。如果你的 PR 包含 native code 变更(新增 Capacitor 插件、iOS/Android 修改),测试人员需要新的 native build。
Capgo 会自动检查版本兼容性。如果 PR 的 bundle 所针对的 native 版本与已安装版本不一致,更新将不会生效。这可以防止因 code 不兼容导致的崩溃。
对于确实需要 native 变更的 PR,你需要分发新的 TestFlight/Play Store build。PR preview 最适合处理不涉及 native code 的 JavaScript、CSS 和资源变更。
PR Preview 适合谁
QA 工程师
- PR 创建后就能立即测试功能
- 无需重新安装即可在多个 PR 间切换
- 在真机上验证修复并检查回归
- 无需再等待 TestFlight 处理
产品经理
- 在合并前预览功能
- 直接在 PR 上提供反馈
- 验证实现是否符合需求
- 缩短评审周期
开发者
- 更快速地获取变更反馈
- 即时向利益相关者演示功能
- 针对特定用户调试问题
- 减少管理 Beta 构建的时间
对比:传统方式 vs PR Previews
| 维度 | TestFlight/Beta 版 | Capgo PR 预览 |
|---|---|---|
| 构建耗时 | 15-30 分钟 | <1 分钟 |
| 切换 PR | 重装需 5+ 分钟 | 10 秒 |
| 配置复杂度 | 需 App Store 凭据 | 仅需一个 workflow 文件 |
| 清理 | 手动 | 自动 |
| Native code 变更 | 必填 | 可选(仅 JS) |
最佳实践
- Channel 命名要清晰:使用
pr-{number}便于识别的命名规范 - 自动清理: PR 关闭时始终删除 Channel
- 限制访问: 仅在 debug/staging 构建中启用摇一摇菜单
- 记录流程: 在 PR 模板中添加测试说明
- 优雅地处理失败情况: 在发布评论前检查 Channel 是否创建成功
何时不应使用 PR Previews
PR 预览适用于 JavaScript/CSS 变更。如果您的 PR 包含:
- 新的 Capacitor 插件
- iOS 原生 code 变更
- Android 原生 code 变更
- 影响 Native Build 的依赖更新
此类变更仍需通过传统的 TestFlight/Play Store 进行分发。
与 Channel Surfing 结合使用
将 PR 预览与 Channel Surfing结合使用效果最佳。您的应用可以实现:
production- 面向所有用户的稳定版本beta- 面向选择性加入用户的早期访问版本pr-123- 面向特定 PR 的功能预览版本
使用生产环境构建版本的测试人员可以随时切换到任何 PR channel 进行功能测试,完成后再切回原版本 —— 这一切都无需重新安装应用。
资源
总结
PR 预览改变了团队评审和测试移动功能的方式。测试人员无需等待 TestFlight 处理,也无需管理多个 Beta 构建,只需使用已安装的应用,就能在几秒内切换到任意 PR 通道。
配置很简单——只需一个 GitHub Actions 工作流文件——收益会在整个团队中不断累积。QA 不再被阻塞,产品经理评审更快,开发者也能更快获得反馈。
先在一个仓库中添加该工作流,看看它如何改变你的评审流程。
继续阅读:把每个 Pull Request 变成可安装的预览版
如果你正在使用 把每个 Pull Request 变成可安装的预览版 要规划 Channel 路由和分阶段发布,请将其与 通道 有关 Channels 的实现细节, 通道 有关 Channels 的实现细节, 通道 有关 Channels 的实现细节, Beta 测试解决方案 适用于 Beta Testing Solution 产品工作流的,以及 版本定向解决方案 适用于 Version Targeting Solution 产品工作流的。