一键导入
feature-flags-release
Decouple deploy from release using feature flags, kill switches, and remote config. Use this when shipping risky or incremental features.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Decouple deploy from release using feature flags, kill switches, and remote config. Use this when shipping risky or incremental features.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | feature-flags-release |
| description | Decouple deploy from release using feature flags, kill switches, and remote config. Use this when shipping risky or incremental features. |
The core principle: deploy ≠ release. Ship code behind flags turned OFF; turn them ON as a separate, small, reversible action. Every new user-facing capability needs a flag and a kill switch from day one.
| Kind | Purpose | Lifetime |
|---|---|---|
| Release flag | Gate unfinished work in main | Days–weeks, then removed |
| Experiment flag | A/B test a variant | Weeks, then winner picked |
| Ops / kill switch | Emergency disable of a feature or SDK | Permanent |
| Permission flag | Paid/entitlement gating | Permanent |
Mixing kinds in one flag leads to dead code paths. Keep them separate.
All decent systems evaluate on-device with a cached ruleset and refresh in the background.
interface FeatureFlags {
fun isEnabled(key: String, default: Boolean = false): Boolean
fun variant(key: String, default: String = "control"): String
}
class RemoteConfigFlags(private val rc: FirebaseRemoteConfig) : FeatureFlags {
override fun isEnabled(key: String, default: Boolean) =
if (rc.getKeyExists(key)) rc.getBoolean(key) else default
override fun variant(key: String, default: String) =
rc.getString(key).ifEmpty { default }
}
protocol FeatureFlags {
func isEnabled(_ key: String, default: Bool) -> Bool
func variant(_ key: String, default: String) -> String
}
final class StatsigFlags: FeatureFlags {
func isEnabled(_ key: String, default d: Bool) -> Bool {
Statsig.checkGate(key) // defaults to false if not loaded
}
func variant(_ key: String, default d: String) -> String {
Statsig.getExperiment(key).getValue(forKey: "variant", defaultValue: d) as? String ?? d
}
}
Every network-dependent feature checks a kill switch before its first call:
if (flags.isEnabled("checkout_v2_enabled", default = false)) {
startCheckoutV2()
} else {
startCheckoutLegacy()
}
The default is the safe state — usually "feature OFF". If remote config fails to load, users get the old, proven path.
Roll out by:
>= 1.4.2 to avoid enabling on versions that don't support it).Never target "new installs only" for a kill switch — you need to cover the whole base.
Example lint:
yq eval '.flags[] | select(.removal_date < now) | .key' flags.yaml
Binary rollout and flag flip are independent axes:
| Binary | Flag | Meaning |
|---|---|---|
| Old (1.4.1) at 95% | OFF | No users see the feature. |
| New (1.4.2) at 5% | OFF | 5% have the code; none see it. |
| New (1.4.2) at 100% | OFF | Entire base has the code; still dark. |
| New (1.4.2) at 100% | 10% | Real exposure begins. |
This separation is what makes rollbacks fast: flip the flag, don't touch the store.
FeatureFlags that returns the variant under test.DebugFlagsScreen) gated by a build flavor.Log flag.key, flag.value, flag.source (remote/default/override) on every evaluation that gates a user-visible surface. This lets you reconstruct what a user saw during a regression.
analytics.logEvent("flag_eval",
"key" to key, "value" to value, "source" to source, "user_id" to userId)
flags.yaml) with owner + removal date per flag.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.