Loading...
Loading...
Guides the agent through migrating an existing Ionic/Capacitor project from Ionic Appflow to Capawesome Cloud. Detects which Appflow features are in use (Live Updates, Native Builds, App Store Publishing) and provides step-by-step migration for each feature to its Capawesome Cloud equivalent. Covers SDK replacement, configuration mapping, API migration, CI/CD pipeline updates, and verification. References the capawesome-cloud skill for detailed Capawesome Cloud setup procedures. Do not use for setting up Capawesome Cloud from scratch without an existing Appflow project, for non-Capacitor mobile frameworks, or for migrating Ionic Enterprise plugins.
npx skill4agent add capawesome-team/skills ionic-appflow-migration@capawesome/cli--helppackage.json@capacitor/core@capacitor/live-updatespackage.jsoncordova-plugin-ionicpackage.jsonLiveUpdatespluginscapacitor.config.tscapacitor.config.json@capacitor/live-updatescordova-plugin-ionic@capacitor/live-updatescordova-plugin-ionicappIdautoUpdateMethodbackgroundalwaysnonechannelenabledmaxVersionsionic appflow build.github/workflows/*.yml.gitlab-ci.ymlbitrise.ymlJenkinsfileazure-pipelines.ymldashboard.ionicframework.comappflow.ionic.ioappflow.config.jsonionic appflow deploynpx @capawesome/cli loginnpx @capawesome/cli apps:create@capacitor/live-updatesnpm uninstall @capacitor/live-updatescordova-plugin-ionicnpm uninstall cordova-plugin-ionicreferences/cordova-sdk-migration.mdInfo.pliststrings.xmlnpm install @capawesome/capacitor-live-update@latestnpm install @capawesome/capacitor-live-update@^7.3.0npm install @capawesome/capacitor-live-update@^6.0.0LiveUpdatesLiveUpdatecapacitor.config.ts.jsonIonic Appflow ( | Capawesome Cloud ( | Notes |
|---|---|---|
| | Replace with the Capawesome Cloud app ID from Step 2 |
| | Capacitor 7/8 only. Omit for Capacitor 6 |
| | Capacitor 7/8 only. Also add |
| (omit | Use manual sync code instead (see Step 3.6) |
| | Same value |
| (remove) | Not needed — controlled in code |
| | Boolean instead of number |
// capacitor.config.ts
const config: CapacitorConfig = {
plugins: {
- LiveUpdates: {
- appId: 'abc12345',
- autoUpdateMethod: 'background',
- channel: 'production',
- maxVersions: 3
- }
+ LiveUpdate: {
+ appId: '<CAPAWESOME_APP_ID>',
+ autoUpdateStrategy: 'background',
+ defaultChannel: 'production',
+ autoDeleteBundles: true
+ }
}
}; // capacitor.config.ts
const config: CapacitorConfig = {
plugins: {
- LiveUpdates: {
- appId: 'abc12345',
- channel: 'production',
- maxVersions: 3
- }
+ LiveUpdate: {
+ appId: '<CAPAWESOME_APP_ID>',
+ defaultChannel: 'production',
+ autoDeleteBundles: true
+ }
}
};@capacitor/live-updatescordova-plugin-ionic-import * as LiveUpdates from '@capacitor/live-updates';
+import { LiveUpdate } from '@capawesome/capacitor-live-update';-import { LiveUpdates } from '@capacitor/live-updates';
+import { LiveUpdate } from '@capawesome/capacitor-live-update';cordova-plugin-ionicreferences/cordova-sdk-migration.mdDeployLiveUpdateLiveUpdatesDeployLiveUpdatesync(){ activeApplicationPathChanged: boolean }{ nextBundleId: string | null } const result = await LiveUpdate.sync();
-if (result.activeApplicationPathChanged) {
+if (result.nextBundleId) {
await LiveUpdate.reload();
}reload()setConfig()getConfig()resetConfig() // Setting config at runtime
-await LiveUpdates.setConfig({ appId: '456', channel: 'staging', maxVersions: 5 });
+await LiveUpdate.setConfig({ appId: '456' });
+await LiveUpdate.setChannel({ channel: 'staging' }); // Getting config at runtime
-const config = await LiveUpdates.getConfig();
-console.log(config.channel);
+const config = await LiveUpdate.getConfig(); // { appId, autoUpdateStrategy }
+const { channel } = await LiveUpdate.getChannel(); // { channel } // Resetting config
-await LiveUpdates.resetConfig();
+await LiveUpdate.resetConfig();maxVersionsautoDeleteBundles: trueautoUpdateMethodalwaysnextBundleSetimport { LiveUpdate } from '@capawesome/capacitor-live-update';
LiveUpdate.addListener('nextBundleSet', async (event) => {
if (event.bundleId) {
const shouldReload = confirm('A new update is available. Install now?');
if (shouldReload) {
await LiveUpdate.reload();
}
}
});confirm() import { SplashScreen } from '@capacitor/splash-screen';
-import * as LiveUpdates from '@capacitor/live-updates';
+import { LiveUpdate } from '@capawesome/capacitor-live-update';
const initializeApp = async () => {
- const result = await LiveUpdates.sync();
- if (result.activeApplicationPathChanged) {
- await LiveUpdates.reload();
+ const { nextBundleId } = await LiveUpdate.sync();
+ if (nextBundleId) {
+ await LiveUpdate.reload();
} else {
await SplashScreen.hide();
}
};autoUpdateStrategyimport { App } from '@capacitor/app';
import { LiveUpdate } from '@capawesome/capacitor-live-update';
void LiveUpdate.ready();
App.addListener('resume', async () => {
const { nextBundleId } = await LiveUpdate.sync();
if (nextBundleId) {
const shouldReload = confirm('A new update is available. Install now?');
if (shouldReload) {
await LiveUpdate.reload();
}
}
});readyTimeoutautoBlockRolledBackBundlesLiveUpdateLiveUpdate: {
appId: '<CAPAWESOME_APP_ID>',
autoUpdateStrategy: 'background', // Capacitor 7/8 only
readyTimeout: 10000,
autoBlockRolledBackBundles: true,
}ready()import { LiveUpdate } from '@capawesome/capacitor-live-update';
void LiveUpdate.ready();ios/App/PrivacyInfo.xcprivacyNSPrivacyAccessedAPITypes<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>npx cap synccapawesome-cloudcapawesome-cloudreferences/native-builds.mdcapawesome-cloudcapawesome-cloudreferences/app-store-publishing.md| Appflow CLI Command | Capawesome CLI Equivalent |
|---|---|
| |
| |
| |
| |
| |
| Use versioned channels or |
| |
| |
-# Ionic Appflow authentication
-IONIC_TOKEN: ${{ secrets.IONIC_TOKEN }}
+# Capawesome Cloud authentication
+- run: npx @capawesome/cli login --token ${{ secrets.CAPAWESOME_CLOUD_TOKEN }}CAPAWESOME_CLOUD_TOKEN-ionic appflow build android --type release
+npx @capawesome/cli apps:builds:create --app-id <APP_ID> --platform android --type release --git-ref main --certificate "<CERTIFICATE_NAME>" --yes-ionic appflow build ios --type app-store
+npx @capawesome/cli apps:builds:create --app-id <APP_ID> --platform ios --type app-store --git-ref main --certificate "<CERTIFICATE_NAME>" --yes--detached-ionic appflow deploy web --channel production
+npx @capawesome/cli apps:liveupdates:upload --app-id <APP_ID> --channel production-ionic appflow deploy android --destination "Google Play"
+npx @capawesome/cli apps:deployments:create --app-id <APP_ID> --build-number <BUILD_NUMBER> --destination "<DESTINATION_NAME>"@ionic/appflowpackage.jsonIONIC_TOKENappflow.config.jsonnpm run buildnpx @capawesome/cli apps:channels:list --app-id <APP_ID> --jsonnpx @capawesome/cli apps:channels:create --app-id <APP_ID> --name <CHANNEL_NAME>npx @capawesome/cli apps:liveupdates:upload --app-id <APP_ID> --channel <CHANNEL_NAME>npm run build && npx cap syncnpx cap open iosnpx cap open androidautoUpdateStrategy: "background"package.jsoncapacitor.config.tscapacitor.config.jsonnpm uninstall @capacitor/live-updatespackage.jsonlive-updates@capacitornpx cap sync@capawesome/capacitor-live-updatepackage.jsonLiveUpdate.ready()autoUpdateStrategy: "background"LiveUpdates is not defined@capacitor/live-updates@capawesome/capacitor-live-updateLiveUpdatesLiveUpdateDeploy is not definedcordova-plugin-ionicreferences/cordova-sdk-migration.mdactiveApplicationPathChanged is not a property{ nextBundleId }{ activeApplicationPathChanged }setConfig is not a functionsetConfig()@capawesome/capacitor-live-updatecapacitor.config.tsnpx @capawesome/cli loginCAPAWESOME_CLOUD_TOKENnpx @capawesome/cli apps:certificates:createcapawesome-cloudreferences/certificates-android.mdreferences/certificates-ios.mdinvalid source releaseJAVA_VERSIONcapawesome-cloudreferences/build-troubleshooting.mdcapawesome-cloudreferences/apple-app-store-credentials.mdreferences/google-play-store-credentials.mdCAPAWESOME_CLOUD_TOKEN