关于 ionic-appflow-migration
用于将 Capacitor 项目中的 Ionic Appflow 功能迁出的技能,涵盖 Live Updates、云构建和商店部署。它帮助团队盘点依赖、验证替代方案,并在迁移确认后再移除 Appflow。
主要功能
- 01盘点 Appflow 用法
- 02将 Live Updates 迁至 Capgo
- 03规划云构建替代方案
- 04梳理商店发布选项
- 05验证切换后再清理
适用场景
- 01将 Live Updates 从 Appflow 迁出
- 02替换 Appflow 原生构建流水线
- 03迁移应用商店部署工作流
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ cap-go/ capgo-skills --skill ionic-appflow-migration安装后在 Claude Code 中输入/ionic-appflow-migration确认已加载。
附带文件metadata.json
详细介绍
Ionic Appflow 迁移
替换项目使用的每项 Appflow 功能——Live Updates、原生云构建、应用商店部署——并仅在确认每项替代方案正常工作后,才移除 Appflow。
背景:Ionic 于 2025 年 2 月停止销售 Appflow;现有客户可继续使用至 2027 年 12 月 31 日,但不会获得新功能。请务必在此日期之前提前规划迁移。
适用场景
满足以下条件时触发:
package.json中包含@capacitor/live-updates或cordova-plugin-ionic。capacitor.config.*中包含plugins.LiveUpdates,或者config.xml/Info.plist/strings.xml中包含 Appflow 部署密钥(APP_ID、CHANNEL_NAME、UPDATE_METHOD、IonAppId、IonChannelName)。- CI 调用
ionic deploy、appflow、ionic package build,或者 Appflow 控制面板会触发构建和应用商店上传。
以下情况不适用:
@ionic-enterprise/*插件 →ionic-enterprise-sdk-migration。- Capawesome Cloud →
capawesome-live-update-migration。 - 从零开始配置 Capgo →
capgo-live-updates。
实时项目快照
检测到的 Appflow 相关软件包和脚本:
!node -e "const fs=require('fs');if(!fs.existsSync('package.json'))process.exit(0);const pkg=JSON.parse(fs.readFileSync('package.json','utf8'));const out=[];for(const section of ['dependencies','devDependencies']){for(const [name,version] of Object.entries(pkg[section]||{})){if(name==='@capacitor/live-updates'||name==='cordova-plugin-ionic'||name.includes('appflow')||name==='@ionic/cli'||name==='@capgo/capacitor-updater'||name==='@capacitor/core')out.push(section+'.'+name+'='+version)}}for(const [name,cmd] of Object.entries(pkg.scripts||{})){if(/appflow|ionic deploy|ionic package|live-updates/i.test(cmd))out.push('scripts.'+name+'='+cmd)}console.log(out.join('\n'))"
可能包含 Appflow 配置和工作流的路径:
!find . -maxdepth 4 -not -path '*/node_modules/*' \( -name '.io-config.json' -o -name 'ionic.config.json' -o -name 'config.xml' -o -name 'capacitor.config.json' -o -name 'capacitor.config.ts' -o -name 'capacitor.config.js' -o -path './.github/workflows/*' -o -name '.gitlab-ci.yml' -o -name 'appflow.config.json' \)
流程
第 1 步:清点(编辑前报告)
rg -n "@capacitor/live-updates|cordova-plugin-ionic|LiveUpdates|IonAppId|IonChannelName|UPDATE_METHOD|CHANNEL_NAME|ionic deploy|appflow|dashboard.ionicframework.com|ionic.io/appflow" \
-g '!node_modules' .
按功能记录:
- Live Updates:正在使用的 SDK、Appflow 应用 ID、通道及指向这些通道的二进制文件、更新方式(
background、none、恢复运行时始终使用最新版本、强制更新)、maxVersions,以及任何调用sync()、download()、extract()、reload()的代码。 - 原生构建:构建技术栈、存储在 Appflow 中的签名证书/配置文件和密钥库、环境变量、原生配置覆盖项。
- 应用商店部署:TestFlight / Google Play 的目标位置和发布轨道。
在删除任何内容之前,请让用户从 Appflow 导出签名凭据(或确认他们拥有原始凭据)。
步骤 2:实时更新 → Capgo
npm uninstall @capacitor/live-updates # or: npm uninstall cordova-plugin-ionic
npm install @capgo/capacitor-updater
npx cap sync
对于 cordova-plugin-ionic,还要从 config.xml 中移除其 <plugin>/<variable> 条目,并从原生文件中移除所有 Ion* 键。
替换配置块:
// capacitor.config.ts
plugins: {
// remove LiveUpdates: { appId, channel, autoUpdateMethod, maxVersions }
CapacitorUpdater: {
autoUpdate: true,
autoDeletePrevious: true,
},
},
| Appflow | Capgo |
|---|---|
appId | 使用 npx @capgo/cli@latest init 创建的 Capgo 应用(使用 capacitor.config 中的 appId) |
channel | Capgo 渠道(控制台/CLI);在服务端设置默认渠道,或在配置中设置 defaultChannel 以按构建覆盖 |
autoUpdateMethod: 'background' | autoUpdate: true(默认行为:在后台下载,并在下次启动时应用) |
autoUpdateMethod: 'none' + 手动 sync() | 除非产品需要自定义时机,否则保留 autoUpdate: true;否则使用 autoUpdate: false + 手动 API |
maxVersions | autoDeletePrevious: true,加上服务端 Bundle 保留策略 |
| 按二进制版本定位 | 每个原生主版本使用一个渠道,或使用 --min-update-version / 元数据策略(capgo-release-workflows) |
| 强制更新 | 在 Capgo 中设置 Bundle/渠道行为,并监听 majorAvailable 或使用 directUpdate |
在应用外壳渲染后添加一次必要的 Hook:
import { CapacitorUpdater } from '@capgo/capacitor-updater';
void CapacitorUpdater.notifyAppReady();
如果没有它,Capgo 会将 Bundle 视为损坏并回滚。
API 对照(仅当产品需要自定义 UI 或时机时才保留手动调用):
Appflow(@capacitor/live-updates) | Capgo |
|---|---|
LiveUpdates.sync() | 使用 autoUpdate: true 时无需调用;手动方式:CapacitorUpdater.getLatest() + download() |
LiveUpdates.reload() | CapacitorUpdater.set({ id })(应用更新并重新加载)或 reload() |
调用 sync() 的恢复监听器 | 移除;恢复时会检查自动更新 |
sync() 后调用 SplashScreen.hide() | 应用启动后直接调用 SplashScreen.hide();可选监听 appReady |
将第一个 Bundle 上传到测试渠道:
npm run build
npx @capgo/cli@latest bundle upload --channel development
步骤 3:原生云构建
有两种替代方案;询问用户偏好哪一种:
- Capgo Cloud Build:
npx @capgo/cli@latest build credentials save --platform ios|android ...,然后运行npx @capgo/cli@latest build request <appId> --platform ios|android。详情见capgo-native-builds。 - 由仓库管理的 CI(GitHub Actions、GitLab、Fastlane):
capacitor-ci-cd。
原样保留环境变量、构建时配置和签名输入;每次只更改一项。
步骤 4:发布到应用商店
保存商店凭据后,Capgo Cloud Build 可以上传到 TestFlight / Play;否则使用 CI 上传步骤(capacitor-ci-cd)或手动提交(capacitor-app-store)。保持 Bundle ID、Play 轨道和凭据不变。
步骤 5:切换并清理
- 向应用商店发布包含
@capgo/capacitor-updater的原生构建版本。在旧二进制版本上的设备会继续从 Appflow 拉取更新,直到完成更新——在采用率足够高之前,保持 Appflow 渠道可用。 - 在过渡期内将 Web 更新同时发布到两个系统,或将 Appflow 冻结在与新二进制版本一同发布的最后一个 Bundle。
- 等没有受支持的二进制版本依赖 Appflow 后,移除 Appflow 软件包、
plugins.LiveUpdates、.io-config.json引用、Appflow CI 作业和密钥。
验证
rg -n "@capacitor/live-updates|cordova-plugin-ionic|LiveUpdates\\." -g '!node_modules' .返回空结果(清理后)。- 全新安装新二进制版本:日志显示已调用
notifyAppReady;Capgo 控制台显示该设备。 - 将测试 Bundle 上传到非生产渠道;设备会下载该 Bundle,并在下次启动时应用。
- 将一个故意损坏的 Bundle(不包含
notifyAppReady)上传到测试渠道;设备会回滚。 - 新的原生构建流水线会生成已签名的 IPA/AAB,且 Bundle ID 相同、构建号更高。
错误处理
| 问题 | 解决方法 |
|---|---|
| 应用回滚每次更新 | 未调用 notifyAppReady()(调用过晚、放在登录之后,或代码路径抛出异常);请在应用外壳渲染后立即调用 |
Capgo CLI 提示 Cannot find API key in local folder or global, please login first | 在本地运行 npx @capgo/cli@latest login <apikey>,或在 CI 中设置 CAPGO_TOKEN |
| 始终收不到更新 | 设备所在的通道没有该 bundle,或 bundle 与原生版本不兼容;请检查通道并运行 npx @capgo/cli@latest bundle compatibility |
| 旧版 Appflow 更新覆盖了 Capgo bundle | 二进制文件中仍安装着旧 SDK;确认已移除 @capacitor/live-updates / cordova-plugin-ionic,并在构建前运行 npx cap sync |
| 移除 Appflow 后构建失败 | Appflow 注入了环境变量或原生配置;请在 CI 或 Capgo Cloud Build 环境中重新配置 |