一键导入
rollback-strategy
Halt rollouts, restore previous binaries, and use kill switches for server-side rollback. Use this when a production release is causing harm.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Halt rollouts, restore previous binaries, and use kill switches for server-side rollback. Use this when a production release is causing harm.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use Apple's phased release for automatic updates on iOS — behavior, pausing, resuming, and interaction with manual updates. Use this when shipping production iOS builds.
Use Play percentage rollouts and iOS phased release to limit blast radius. Use this when planning or operating a production release.
Generate keystores, enrol in Play App Signing, and understand v1/v2/v3/v4 APK signature schemes. Use this when setting up Android release signing.
Diagnose and fix common Apple and Google code-signing errors. Use this when a release build fails to sign, upload, or install.
Manage Apple certificates, provisioning profiles, automatic vs manual signing, and fastlane match. Use this when setting up iOS release signing.
Publish Android apps to Amazon Appstore, Huawei AppGallery, Samsung Galaxy Store, and deal with HMS vs GMS. Use this when targeting non-Google Android markets.
| name | rollback-strategy |
| description | Halt rollouts, restore previous binaries, and use kill switches for server-side rollback. Use this when a production release is causing harm. |
Mobile rollbacks are fundamentally harder than web rollbacks: you cannot remove a binary that users have already installed. The order of preference is always (1) server-side kill switch, (2) halt rollout, (3) ship a new binary with the fix, (4) re-promote the previous binary.
Is there a feature flag covering the regression?
├─ YES → Flip the flag OFF. Done in seconds. Fix forward later.
└─ NO → Is the server API the root cause?
├─ YES → Roll back the server change. Done in minutes.
└─ NO → Is the rollout still < 100%?
├─ YES → Halt the rollout and hotfix (see `hotfix-workflow`).
└─ NO → Hotfix is the only path. Users on the bad version stay there
until they manually update or auto-update triggers.
Every new feature should ship with a kill switch (see feature-flags-release). A kill switch is:
Flip via LaunchDarkly / Statsig / Remote Config console. Log the change with who, when, and why.
bundle exec fastlane supply \
--track production \
--rollout 0 \
--skip_upload_aab true \
--skip_upload_metadata true
Effect: no new installs or updates receive the new build. Users already on it stay on it.
curl -X PATCH \
"https://api.appstoreconnect.apple.com/v1/appStoreVersionPhasedReleases/$ID" \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{"data":{"type":"appStoreVersionPhasedReleases","id":"'"$ID"'",
"attributes":{"phasedReleaseState":"PAUSED"}}}'
Pause pauses the auto-update ramp. Manual updaters still get the paused build.
Play does not support rollback to a lower versionCode. Instead, you re-ship the previous source as a new build:
git checkout v1.4.1
./scripts/bump-version.sh 1.4.1.1 # bump patch to avoid the burned code
bundle exec fastlane android internal
bundle exec fastlane android promote_to_production --rollout 0.20
Keep the previous AAB in the internal track so you can re-promote quickly without rebuilding.
Same principle: resubmit the previous source as a new higher CFBundleVersion. Request expedited review because the existing version is actively harming users.
If only a subset of features is broken, steer clients server-side:
// /config endpoint
{
"minimum_supported_version": "1.4.3",
"checkout_v2_enabled": false,
"force_update_below_version": "1.4.0"
}
The client honours minimum_supported_version by hiding broken flows or prompting the user to update.
Android:
val updateInfo = appUpdateManager.appUpdateInfo.await()
if (updateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE &&
updateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE) &&
serverConfig.forceUpdateBelow > BuildConfig.VERSION_CODE) {
appUpdateManager.startUpdateFlowForResult(updateInfo, AppUpdateType.IMMEDIATE, activity, REQ)
}
iOS: there is no native force-update; implement it as a full-screen gate that only dismisses after the user taps "Update" and returns from the App Store.
If the bad release shipped a migration that rewrites local data, rolling back the binary does not roll back the data. Design migrations to be:
schema_version tracked).If a migration is destructive, ship it behind a flag and enable only after the binary is at 100% stable.
[ROLLBACK] app-release 1.4.2
Trigger: crash-free sessions dropped to 98.7% (SLO 99.5%)
Action: Play rollout halted at 10%; iOS phased paused.
Users affected: ~60k on 1.4.2.
Mitigation: server-side flag `checkout_v2_enabled` = false.
Next step: hotfix 1.4.3 ETA 6h; owner @alice.
Post to #release, #support, and #engineering.
versionCode — it will be rejected and burn a number.Rollback commands must be muscle memory. Run a quarterly drill in a staging project:
/config) in place and cached client-side.docs/incident-templates/.