Claude
Skills
Sign in
Back

ionic-appflow-migration

Included with Lifetime
$97 forever

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.

Backend & APIs

What this skill does


# Ionic Appflow Migration

Migrate an existing Ionic/Capacitor project from Ionic Appflow to Capawesome Cloud.

## Prerequisites

1. A **Capacitor 6, 7, or 8** app currently using Ionic Appflow.
2. Node.js 18+ and npm installed.
3. Access to the project's source code repository.
4. A [Capawesome Cloud](https://console.cloud.capawesome.io) account and organization.

## General Rules

- Before running any `@capawesome/cli` command for the first time, run it with the `--help` flag to review all available options.
- Do not remove Ionic Appflow configuration until the corresponding Capawesome Cloud feature is fully set up and verified.
- Determine the Capacitor version from `package.json` (`@capacitor/core`) before making any changes — it affects which plugin version and update strategy to use.

## Procedures

### Step 1: Detect Ionic Appflow Usage

Scan the project to determine which Appflow features are in use.

#### 1.1 Check for Live Updates

Search for these signals:

1. `@capacitor/live-updates` in `package.json` (dependencies or devDependencies).
2. `cordova-plugin-ionic` in `package.json` — this is the legacy Cordova SDK for Ionic Live Updates.
3. A `LiveUpdates` key inside the `plugins` object in `capacitor.config.ts` or `capacitor.config.json`.
4. Imports of `@capacitor/live-updates` or `cordova-plugin-ionic` in TypeScript/JavaScript source files.

If any signal is found, mark **Live Updates** as in use. Also record which SDK is in use (`@capacitor/live-updates` or `cordova-plugin-ionic`).

Record the current configuration values:

- `appId` (Ionic Appflow app ID)
- `autoUpdateMethod` (`background`, `always`, or `none`)
- `channel`
- `enabled`
- `maxVersions`

#### 1.2 Check for Native Builds

Search for these signals:

1. References to `ionic appflow build` in CI/CD configuration files (e.g., `.github/workflows/*.yml`, `.gitlab-ci.yml`, `bitrise.yml`, `Jenkinsfile`, `azure-pipelines.yml`).
2. References to `dashboard.ionicframework.com` or `appflow.ionic.io` in CI/CD files or scripts.
3. An `appflow.config.json` or similar Appflow build configuration file in the project root.

If any signal is found, mark **Native Builds** as in use.

#### 1.3 Check for App Store Publishing

Search for these signals:

1. References to `ionic appflow deploy` in CI/CD configuration files.
2. Appflow deploy destinations or channels configured for app store submission.

If any signal is found, mark **App Store Publishing** as in use.

#### 1.4 Present Findings

Present the detected features to the user. Ask the user to confirm which features to migrate. The user may choose to migrate all detected features or only a subset.

### Step 2: Set Up Capawesome Cloud

#### 2.1 Authenticate

```bash
npx @capawesome/cli login
```

#### 2.2 Create an App

Skip if the user already has a Capawesome Cloud app ID.

```bash
npx @capawesome/cli apps:create
```

Save the returned **app ID** (UUID) for subsequent steps.

### Step 3: Migrate Live Updates

Skip this step if Live Updates was not detected or the user chose not to migrate it.

#### 3.1 Remove the Ionic Live Updates SDK

If the project uses `@capacitor/live-updates`:

```bash
npm uninstall @capacitor/live-updates
```

If the project uses the legacy Cordova SDK (`cordova-plugin-ionic`):

```bash
npm uninstall cordova-plugin-ionic
```

Read `references/cordova-sdk-migration.md` for the native configuration cleanup steps (removing legacy keys from `Info.plist`, `strings.xml`, and Capacitor config).

#### 3.2 Install the Capawesome Live Update Plugin

Install the version matching the project's Capacitor version:

- **Capacitor 8**: `npm install @capawesome/capacitor-live-update@latest`
- **Capacitor 7**: `npm install @capawesome/capacitor-live-update@^7.3.0`
- **Capacitor 6**: `npm install @capawesome/capacitor-live-update@^6.0.0`

#### 3.3 Update the Capacitor Configuration

Replace the `LiveUpdates` plugin config with `LiveUpdate` in `capacitor.config.ts` (or `.json`). Map the configuration options as follows:

| Ionic Appflow (`LiveUpdates`) | Capawesome Cloud (`LiveUpdate`) | Notes |
|---|---|---|
| `appId` | `appId` | Replace with the Capawesome Cloud app ID from Step 2 |
| `autoUpdateMethod: 'background'` | `autoUpdateStrategy: 'background'` | Capacitor 7/8 only. Omit for Capacitor 6 |
| `autoUpdateMethod: 'always'` | `autoUpdateStrategy: 'background'` | Capacitor 7/8 only. Also add `nextBundleSet` listener (see Step 3.5) |
| `autoUpdateMethod: 'none'` | *(omit `autoUpdateStrategy`)* | Use manual sync code instead (see Step 3.6) |
| `channel` | `defaultChannel` | Same value |
| `enabled` | *(remove)* | Not needed — controlled in code |
| `maxVersions` | `autoDeleteBundles: true` | Boolean instead of number |

**Example — Capacitor 7/8 with background strategy:**

```diff
 // 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
+    }
   }
 };
```

**Example — Capacitor 6 (no autoUpdateStrategy):**

```diff
 // capacitor.config.ts
 const config: CapacitorConfig = {
   plugins: {
-    LiveUpdates: {
-      appId: 'abc12345',
-      channel: 'production',
-      maxVersions: 3
-    }
+    LiveUpdate: {
+      appId: '<CAPAWESOME_APP_ID>',
+      defaultChannel: 'production',
+      autoDeleteBundles: true
+    }
   }
 };
```

#### 3.4 Update Import Statements and API Calls

Search all TypeScript/JavaScript files for imports of `@capacitor/live-updates` (or `cordova-plugin-ionic`) and replace. The Ionic SDK uses two import styles — replace both:

```diff
-import * as LiveUpdates from '@capacitor/live-updates';
+import { LiveUpdate } from '@capawesome/capacitor-live-update';
```

```diff
-import { LiveUpdates } from '@capacitor/live-updates';
+import { LiveUpdate } from '@capawesome/capacitor-live-update';
```

If the project uses the legacy Cordova SDK (`cordova-plugin-ionic`), read `references/cordova-sdk-migration.md` for the complete `Deploy` → `LiveUpdate` method mapping, including the granular check-download-extract-reload pattern and native config cleanup.

Replace **all** references to the `LiveUpdates` class (or `Deploy` class) with `LiveUpdate` (singular).

**`sync()` return value has changed.** The Ionic Capacitor SDK returns `{ activeApplicationPathChanged: boolean }`. The Capawesome SDK returns `{ nextBundleId: string | null }`. Update all code that checks the sync result:

```diff
 const result = await LiveUpdate.sync();
-if (result.activeApplicationPathChanged) {
+if (result.nextBundleId) {
   await LiveUpdate.reload();
 }
```

**`reload()` has the same signature** — no changes needed beyond the class name.

**`setConfig()`, `getConfig()`, and `resetConfig()` exist but have different signatures (Capacitor 7/8 only, since v7.4.0).** The Capawesome SDK splits config and channel management into separate methods:

```diff
 // Setting config at runtime
-await LiveUpdates.setConfig({ appId: '456', channel: 'staging', maxVersions: 5 });
+await LiveUpdate.setConfig({ appId: '456' });
+await LiveUpdate.setChannel({ channel: 'staging' });
```

```diff
 // 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 }
```

```diff
 // Resetting config
-await LiveUpdates.resetConfig();
+await LiveUpdate.resetConfig();
```

`maxVersions` has no runtime equivalent — use `autoDeleteBundles: true` in the static Capacitor config instead.

#### 3.5 Add Always-Latest Update Logic (Capacitor 7/8 Only)

If the previous Ionic Appflow `autoUpdateMethod` was `always`, add a `nextBundleSet` listener to prompt the user when an upd

Related in Backend & APIs