How a release reaches users
The path from a merged commit to a mobile app on people's phones, on both stores. Read it before your first mobile release, and before you set up a new app.
How it works
Three things make mobile releases different from a web deploy:
- You cannot roll back. A shipped build stays on phones until users update. The only tools are a new build, a force-update gate, and server-side flags.
- Someone else approves it. Apple and Google review every public release, on their schedule, against rules that change. The two stores approve days apart.
- Identifiers are forever. A bundle id, package name, product id or signing key you get wrong cannot be renamed. See Identifiers and signing.
Flavors and environments
One codebase builds three apps. Each is a separate app in each store, with its own id and its own backend. Only prod is published.
| Flavor | Android package / iOS bundle id | Backend | Store presence |
|---|---|---|---|
| dev | com.example.app.dev | dev | Internal track and TestFlight only |
| staging | com.example.app.staging | staging | Internal track and TestFlight only |
| prod | com.example.app | prod | Published |
The display name differs per flavor ("ExampleDev", "ExampleStaging") so testers can tell them apart on one phone.
The pages in this module
| Page | Read it when |
|---|---|
| Identifiers and signing | You create an app, a flavor, a key, or bump a version |
| App Store | You upload to TestFlight or submit on iOS |
| Google Play | You upload to Play or set up Android CI |
| Getting through review | Before every submission |
| Release day and updates | The day a build is approved |
| Store mistakes | Your first week |
Rules
Never release a build the moment it is approved. Hold it, finish the backend work, then release. Both stores let you approve now and publish later.
Every build sends its version to the backend, and the backend can force an update. Ship the force-update gate in the first public build. Without it, a broken version stays in use for months.
Every store declaration (privacy labels, data safety, age rating, deletion URL, support URL) must match the binary, the privacy policy and the terms. Reviewers compare them.
Mistakes we made
See Store mistakes. The ones that shaped this page:
- Part of the Android user base was stuck on an old build for weeks. There was no force-update gate yet, and the old build still worked against the new API until it did not.
- The first iOS release took eight review rounds over six weeks. Every rejection was a rule we could have checked before submitting. The checks are in Getting through review.
Checklist
- Three flavors, three store records each, separate ids and backends.
- Version and build number bumped and unique.
- Force-update gate is in the build.
- Store declarations match this build.
- The approved build is held until the backend is ready.