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
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
Bump the version
version: in pubspec.yaml.Build with koolbase release — and pass your project
--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>Confirm registration in the output
=== registering releases ===
registered arm64-v8a -> release rel_... (build_id ..., channel stable)
registered armeabi-v7a -> release rel_... (build_id ..., channel stable)rel_... IDs — they identify the release you'll patch later.If you see “releases NOT registered”
--project, then rebuild.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.aabjar verified. Self-signed / no-timestamp warnings are normal for an upload key — the store re-signs with the app signing key anyway.Upload the engine-carrying AAB
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
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