The release checklist we read out loud before every submission
Most failed releases fail on something trivial that everyone assumed somebody else had checked. The fix is boring and it works: a written list, read aloud, every time.
Releases rarely fail on hard problems. They fail on an expired demo account, a privacy label that no longer matches the SDKs, a screenshot of an interface that changed two sprints ago.
These are not difficult to catch. They are difficult to remember, which is a different problem with a well-known solution.
Why written, and why aloud
A checklist held in someone's head is a checklist that degrades under pressure, and release day is the highest-pressure moment in the cycle.
Reading it aloud with someone else matters more than it sounds. It converts a silent tick into a spoken claim, and people are noticeably less willing to say yes to something they have not actually looked at.
The wording of each item does real work here. Anything phrased as a state of the world invites agreement without inspection: production endpoints configured is easy to affirm from memory. The same item phrased as an action, read the base URL in the running build out loud, cannot be answered without doing it.
The list
Build:
- Version and build number incremented, and matching what the release notes say.
- Built from the release branch at a tagged commit, not from someone's working copy.
- Pointed at production endpoints, verified by looking rather than by assuming.
- Debug flags, test accounts and verbose logging off.
Store listing:
- Demo account exists, is not locked, and was signed into today.
- Every feature reachable by a reviewer with a fresh account and no seeded data.
- Screenshots match the current interface on current device sizes.
- Privacy labels match what the app and every SDK actually collect.
- Sign in with Apple present wherever a third-party login is offered.
After submission:
- Crash reporting confirmed as receiving from the release build.
- Staged rollout configured rather than releasing to everyone at once.
- Someone named is responsible for watching the crash-free rate for 48 hours.
- Rollback path written down and understood before it is needed.
The two items that catch the most
Over a few years of doing this, two lines have justified the whole exercise more than the rest combined.
The demo account, because it is the one part of a submission that decays without anybody touching the code. Passwords expire, trials end, a data cleanup removes the seeded records the account depended on. Nothing in the build changed, and the review fails anyway.
The privacy labels, because they describe dependencies rather than your own code. A minor version bump of an analytics SDK can add a collection category, and nobody reads a changelog for a patch release. The labels were accurate when written and are quietly wrong three releases later.
The staged rollout is the important one
Everything above reduces the chance of a bad release. Staged rollout reduces the cost of one, and that is a more reliable investment.
A bad release caught at five percent is an inconvenience. The same release at a hundred percent is a week.
It only works if somebody is actually watching. A staged rollout with nobody assigned to it reaches full availability on schedule regardless, which is why the named person is on the list. A rota with no name on it is not a rota.
Rehearse the rollback
Every team has a rollback plan. Far fewer have run it, and the gap between those two states is usually discovered at the worst possible moment.
Mobile makes this sharper than the web, because there is no undo. A build that has reached users cannot be recalled; the only moves available are halting the rollout and shipping a fix through review. Knowing which of those you would choose, and how long the second takes, is worth establishing on a calm afternoon rather than during an incident.
Keep it short
A checklist that takes an hour will be skipped the first time a deadline is tight. Ours takes about ten minutes. Anything that is genuinely automatic should move into CI rather than onto the list.
The list should also get shorter over time. Every item that has never once caught anything is a candidate for removal, and every item that failed twice is a candidate for automation. A checklist that only ever grows stops being read, which is the failure mode it exists to prevent.


