codepush 0.2.8 copy "codepush: ^0.2.8" to clipboard
codepush: ^0.2.8 copied to clipboard

PlatformAndroid

Ship Dart fixes to installed Flutter apps without an app-store review. Signed patches, staged rollout, crash-safe rollback. Android needs no forked engine.

0.2.8 #

A patch that crashes the app is now actually rolled back.

Probation used to end on the first frame. A patch that rendered a splash and then crashed while mounting the next screen cleared the breadcrumb on that frame, so every later launch treated it as healthy and crashed again — the app was permanently broken by a patch, and the mechanism meant to prevent exactly that never fired, because by its own measure nothing had gone wrong.

Probation now lasts healthyAfter (8s by default) past the first frame, which covers early navigation and the first real screen. Two launches that fail inside that window drop the patch and the app returns to shipped code.

The cost is a false positive: force-quitting inside the window twice in a row loses that patch. A lost patch is an inconvenience; an app that cannot start is not.

0.2.7 #

The check record says whether this process's timers are alive.

It is the first thing worth knowing when a check never finishes, and nothing else reports it: a platform channel answering proves the message loop works and says nothing about timers, which every timeout in the check is built on. If they are dead the check does not fail, it hangs.

0.2.6 #

The update check records running as well as scheduled and its decision, and has an outer deadline so it can never sit unfinished forever.

scheduled and a real decision were not enough to debug this on a device: a check that was never reached and a check that hung produced the same record, and they have completely different causes. The deadline covers what the inner timeouts cannot — a platform channel that never answers, or a socket that neither connects nor errors — and turns a permanent hang into a reported failure.

0.2.5 #

The iOS update check no longer uses a Timer, because a Timer does not fire on a launch where a patch applied.

Measured on a device: still unfired 90 seconds in, whether created before or after the patch was applied, while post-frame callbacks on the same isolate ran normally — including the boot report, which does network I/O. Async and the event loop are fine; applying a patch appears to take the isolate's timer queue with it. The consequence was that after the first patch a device never checked again: it ran that patch forever while later ones sat published, signed and fetchable, and nothing on the device or the server said so.

The check now runs from a post-frame callback, which the engine's frame scheduling drives rather than the Dart timer queue. This gives up the four-second delay the Timer provided; running after the first frame still keeps it off the startup path, and the check is one small GET.

0.2.3 and 0.2.4 were two wrong diagnoses of this same symptom.

0.2.4 #

0.2.3 named the right rule and fixed the wrong cause. The update check is now scheduled before the patch is applied, not after.

A timer created after IosPatchLoader.bootstrap() never fires on a launch where a patch applied — measured on a device, still unfired 90 seconds in, while post-frame callbacks on the same isolate ran normally. Capturing the config instead of reading a static (0.2.3) was not enough, because the callback was never reached at all. So every launch after the first patch skipped the check, and the device ran that patch forever while later ones sat published, signed and fetchable.

0.2.3 #

A patch could permanently switch off the update check. Once a patch was applied, every later launch skipped the check: the startup timer's callback read a static field in this library, and applying a patch can reinitialise the libraries it replaces, so that field read back null and the callback returned before doing anything. The device kept running the first patch it ever received while later patches sat published, signed and fetchable. Found on a real device, where patch 2 never arrived twice in a row.

The check now runs from the config captured when it was scheduled, so nothing on that path depends on static state outliving a patch. A patch must never be able to disable the mechanism that would replace it.

A check that is due also records itself as scheduled, so a check that never runs is distinguishable from one that ran and found nothing — those two were identical from outside the device, which is why this went unnoticed.

0.2.2 #

The device now records what the update check decided, not only what the boot loader did. Those are different things and only the second was ever written down: the check is where a patch is accepted or refused, and its one output was a debugPrint that does not reach a release build's console. So on a real device, "I published a patch and nothing changed" had no answer — the boot status kept correctly reporting the previous patch while the new one was being declined for an invisible reason.

0.2.1 #

The device status file now records which patch a launch acted on. The outcome alone could not answer the two questions actually asked of a device — "did my new patch land" and "did the rollback take" — because a before/after pair both report applied with the same replaced count.

0.2.0 #

Fixes the default patch contract, which named five packages the first app to use CodePush happened to depend on: go_router, intl, dio, shared_preferences and get. The compiler resolves every library a contract names, so any project without one of them failed an iOS release with "Couldn't resolve the package". They were also redundant — codepush release ios already adds every library the app links. The contract now lists framework libraries only.

0.1.0 #

First release.

0
likes
140
points
0
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Ship Dart fixes to installed Flutter apps without an app-store review. Signed patches, staged rollout, crash-safe rollback. Android needs no forked engine.

Topics

#code-push #hot-update #ota #deployment

License

MIT (license)

Dependencies

codepush_protocol, crypto, dio, flutter, path_provider, shared_preferences

More

Packages that depend on codepush

Packages that implement codepush