Skip to main content

Release day and updates

What to do between "approved" and "live", and how to get users off old builds. Read it on the day a build is approved.

How it works​

Steps 3 and 5 are not reorderable. Release before routing is off and new users of the new version land on the review backend.

How to build it​

Hold the approved build​

  • App Store: choose manually release this version when submitting.
  • Play: turn on managed publishing, so approved changes wait for you.

The two stores approve days apart. Holding both lets you release them together, or release Android first on purpose.

The force-update gate​

  • A remote config value per platform: minimum version and latest version, separate for iOS and Android, because approvals land on different days.
  • Below the minimum: a full-screen "update required" that replaces the app's routes, with a button to the store page.
  • Below the latest: a dismissible prompt. On Android, use Play's in-app update API: immediate for forced updates, flexible (at most once a day) otherwise.
  • Fail open. If config cannot load, let the app run.
  • On iOS it only blocks when a real App Store id is configured.
  • Later, the API returns HTTP 426 with a store URL for versions it no longer supports.

After release​

  • Watch crash-free users and new crash clusters in the crash reporter for 24 hours.
  • Upload debug symbols for every release build, or crash traces are unreadable.
  • On Play, widen the staged rollout only while the crash rate holds.

Rules​

Rule

Keep old app versions working until the force-update gate has moved them. Every API change is checked against the oldest version still allowed.

Rule

Test the release-candidate build against real production only after routing is switched off. Before that, TestFlight testers on that version also reach the review backend.

Mistakes we made​

  • Users were stuck on an old Android build because there was no gate. We then had to audit every API change for backward compatibility.
  • A single TestFlight tester on the review build saw the review backend, not production, and reported "missing data". That is routing working as designed.

Checklist​

  • Approved builds held on both stores.
  • Backend deployed before release.
  • Release-candidate routing off, verified.
  • Released; staged rollout on Play.
  • Minimum version raised when needed.
  • Symbols uploaded; crash-free users watched for 24 hours.