Shipping a Patchable Release

The store build you ship is the base every future patch applies against. This page is the end-to-end procedure for producing one, registering it, and uploading it — so that code push actually works once it's live.

Shipping on iOS?

This walkthrough covers the Android release flow (multi-ABI AAB, Play Store). On iOS the flow is: build with koolbase build ios, ship that binary through App Store review as normal, keep the built App binary, and push fixes with patch ios build + patch push-ios. See the Quick Start and CLI Reference.

Two things make a build patchable

A build can receive patches only if (1) it was produced with koolbase release — which embeds the engine — and (2) its build_ids were registered with Koolbase at build time. A plain flutter build appbundle has no engine and can never be patched.

Before you build

Have these in place once per machine:

  • The Koolbase CLI installed and logged in (koolbase login) to an account with access to your project.
  • The Koolbase engine for your Flutter version installed via koolbase engine.
  • A Flutter SDK matching that engine's version, passed with --flutter-sdk.
  • Your Android upload keystore configured (the CLI re-signs the AAB with it).

The release procedure

1

Bump the version

The build number must be higher than whatever is already on the store, or the store rejects the upload as a duplicate. Update version: in pubspec.yaml.
2

Build with koolbase release — and pass your project

Passing --project (or being logged in) is what registers the build_ids. Without it the AAB still builds, but it is silently unpatchable.
koolbase release android \
  --engine <engine-version> \
  --flutter-sdk /path/to/matching/flutter \
  --flavor prod \
  --dart-define-from-file=.env \
  --channel stable \
  --project <your-project-id>
3

Confirm registration in the output

This is the step that's easy to miss. The output must show the releases being registered — not a warning that they weren't:
=== registering releases ===
  registered arm64-v8a   -> release rel_... (build_id ..., channel stable)
  registered armeabi-v7a -> release rel_... (build_id ..., channel stable)
Record the rel_... IDs — they identify the release you'll patch later.

If you see “releases NOT registered”

The build_ids were not registered and the build cannot be patched. Make sure you're logged in and passed --project, then rebuild.
4

Verify the AAB is signed

koolbase release re-signs the bundle with your upload key (it modifies the AAB to inject per-ABI engines, which would otherwise strip the signature). Confirm:
jarsigner -verify build/app/outputs/koolbase/app-prod-release.aab
Expect jar verified. Self-signed / no-timestamp warnings are normal for an upload key — the store re-signs with the app signing key anyway.
5

Upload the engine-carrying AAB

Upload build/app/outputs/koolbase/app-prod-release.aab — the engine-carrying bundle — not the plain bundle/<flavor>Release/ one.

Store re-signing keeps it patchable

When you use Play App Signing, Google re-signs your AAB and delivers per-device splits. The instruction bytes of the compiled snapshot are identical through that process, so the build_id is unchanged — the build you registered stays matchable, and patches reach store-installed users the same as sideloaded ones.

The patch key is bound to the build

koolbase release bakes a patch-verification public key into the engine. On device, the engine accepts a patch only if it was signed by the matching private key.

A released build can only be patched by its own key

To patch a build that is already live, you must sign with the same private key that built it — a different key fails verification on device. A new key only takes effect from a future release built with that key's public half. Keep the patch signing key safe and transferable: losing it makes the live build unpatchable.

Once the release is live and users update to it, push fixes against it with koolbase patch push — see Releases & Patches for how devices match a release, and Rollout & Rollback for staged delivery and recall.

Checklist

[ ]  Version bumped above the live build
       [ ]  koolbase release ... --project <id>
       [ ]  Output shows "registering releases" (NOT "NOT registered")
       [ ]  Recorded the rel_ IDs
       [ ]  jarsigner -verify  ->  jar verified
       [ ]  Uploaded outputs/koolbase/app-<flavor>-release.aab to the store