CLI

Tutorial: first release + first patch

An end-to-end walkthrough — install the CLI, log in, set up a Flutter project, cut a base release, submit the store binary, then ship a live code-only patch with the auto-diff workflow.

This tutorial takes you from a clean machine to a live over-the-air patch. It uses a Flutter project because that's the richest path; the React Native flow is called out where it differs. By the end you'll have cut a base release, submitted a store binary, edited real code, and shipped that change to devices without a store resubmission.

Prerequisites

  • Node.js 18+ and the platform toolchain for your target (Xcode for iOS, Android SDK + JDK 17 for Android). See Install the CLI.
  • A Sankofa account with a project. Create one in the dashboard first.

Step 1 — Install and log in

bash
npm install -g sankofa-cli
sankofa --version

sankofa login             # opens your browser, mints a Deploy Token for the project you pick

For CI, skip the browser and pass a pre-minted Deploy Token instead:

bash
sankofa login --deploy-token sk_deploy_xxxxxxxx --project-id proj_xxxxxxxx

Step 2 — Set up the project

From your Flutter project root:

bash
sankofa init --deploy

This adds the Sankofa Flutter SDK, creates sankofa.yaml, wires lib/main.dart (the updater pre-flight call), patches the Android + iOS native files, and installs the Sankofa engine. Because you already logged in, sankofa.yaml's app_id and api_key are filled from the project you selected — nothing to paste.

Confirm everything is wired:

bash
sankofa doctor --deploy

Step 3 — Cut the base release

A base release builds the signed store binary and registers the OTA baseline patches attach to. Pick your platform:

bash
# Android — produces a Play Store AAB
sankofa release android

# iOS — produces a signed .ipa for App Store Connect / TestFlight
sankofa release ios

The CLI detects the app version, verifies the embedded engine is a genuine Sankofa build, captures the auto-diff base for future patches, and (after you confirm) publishes the baseline. It prints the release label (e.g. v1.0.0), the rollout %, and the on-disk path of the store binary.

Step 4 — Submit the store binary

Upload the artifact the CLI printed:

  • iOS: drag the .ipa into Transporter, or use Xcode Organizer / xcrun altool.
  • Android: upload the .aab to the Play Console (Production or a testing track).

Submit the exact binary sankofa release produced — it contains the Sankofa engine and OTA wiring. A binary from a raw flutter build is not registered for OTA and won't accept patches.

Step 5 — Ship your first patch

Now the payoff. Edit your real Dart code — fix a bug, change a string, adjust logic:

Dart
// lib/home_page.dart (example)
Text('Welcome back!')          // was: Text('Welcome')

Then ship it. Sankofa rebuilds your edited app, diffs it against the baseline, and ships only the changed functions — no patch file, no store resubmission:

bash
sankofa patch android
# or: sankofa patch ios   (App Store compliant)

You'll see something like:

text
Patch module built — 1 changed function(s) (612 B).
Changed: _HomePageState.build
Publish patch v1.0.0-patch.1 targeting 1.0.0? (Y/n)

Confirm, and the patch publishes as v1.0.0-patch.1. Devices in the rollout fetch and apply it on next launch.

Step 6 — Roll out gradually

Publish to a slice of devices first, then widen once it looks healthy:

bash
sankofa patch android --publish --rollout 10 --description "welcome copy fix"
# …watch Catch + adoption, then re-publish wider by cutting the next patch at a higher rollout

Watch progress any time:

bash
sankofa status
sankofa status --env live --platform android

React Native differences

The shape is identical — release then patch — but a React Native patch ships a JavaScript bundle rather than diffed Dart:

bash
sankofa release ios
# …edit your JS/TS…
sankofa patch ios --publish --rollout 25

React Native's patch shows a picker of base releases and asks whether the change touches native code (which can't go OTA).

One-shot deploy

For CI scripts that shouldn't care whether a baseline exists yet, sankofa deploy auto-picks release (first run) or patch (subsequent runs):

bash
sankofa deploy android --publish --rollout 50

Where to go next

Edit this page on GitHub