Release Toggles in CommCare Connect¶
CommCare Connect uses django waffle to manage feature release.
Waffle provides different tools to control access to a feature on the environment.
For now, features are being released directly to users so new switches & flags should be added only when necessary.
Usage¶
Connect uses both switches and flags.
- While switches are used to turn a feature on or off for everyone, flags are used to enable a feature for specific users, groups, users meeting certain criteria (such as being authenticated, or superusers).
- This allows for global releases, as well as targeted releases to specific users, organizations, opportunities, and/or programs.
Expectations¶
- Switches and flags should be as short-lived as possible, existing through the release, but removed once the feature is out.
- All switches and flags should have a detailed description in the note field of the model, describing the feature they control.
- Exception:
delivery_stats_monthly_exportis a long-lived recipient list, not a release toggle. Its users receive the monthly Delivery Stats CSV email (managed from Internal Features → Delivery Stats Monthly Export). Don't remove it as a stale flag.
Configuration Details¶
Switches and Flags are actual Django models and not just set in code.
They can be managed by users with required access
- by navigating to "Toggles & Switches" under "Internal Features"
- via Django Admin
Switches¶
- switch names are added in the file
switch_names.py - use
switch_is_activeto check if switch is enabled - to gate a whole view behind a switch, use waffle's
waffle_switch(NAME)decorator (function views) orWaffleSwitchMixinwithwaffle_switch = NAME(class views); both 404 while the switch is off. List the mixin first among the view's bases so the 404 happens before any login or permission mixin redirects - for new switches, they can be created prior to deploy via Django Admin or added via migration with the release. However,
WAFFLE_CREATE_MISSING_SWITCHESis set to automatically add new switches to database when they are encountered in the codebase. Description should be added as a followup if created automatically.
Flags¶
Connect uses a custom Flag model commcare_connect.flags.models.Flag to define its own entities for access
- flags names are added in the file
flag_names.py - in a request, use waffle's
flag_is_active(request, NAME). The customFlag.is_active()adds Connect's checks to waffle's: the flag is also on when it is enabled forrequest.opportunity, that opportunity's program, orrequest.org - outside a request, or for an object other than the current one, call
Flag.is_active_for(obj)on the flag with anOrganization,OpportunityorProgram. It checks only that object, not the user - for new flags, they should be created on the relevant environment prior to deploy via Django Admin or added via a migration with the release