We’ve recently changed how new features are released to our production environment. A new system has been introduced into our application titled “Feature Control”. Read more...
Our application codebase is generally split into two branches, master and development. Most of the work occurs in development; when ready the changes are merged into master. From there we deploy the master branch to our production environment. Our users now have access to the shiny new feature.
This workflow works well for us, but misses one important element when releasing a new feature: Beta Testing. Up until recently we had no way to gradually rollout features to a subset of our users. Our releases went to all users immediately. This is scary — feedback is essential when changing how a user is going to interact with the application.
I’ll admit it, my initial thoughts when I first started to hear how other applications and services implement similar systems, were skeptical. Scattering if statements all throughout your code, a separate dashboard, a key/value store, user buckets to manage features, it felt wrong… too many moving parts. Something was bound to break. It just so happened my confused mental model broke, and I saw the light!
Some of the benefits we’ve already experienced in this new system's short lifetime, have been:
- Free regression testing. Even though some features are not released in production for all users, the code still lives inside the system. We’ll have a much better idea if a new feature causes any trouble.
- Gradual rollout of features. We can easily enable or disable a feature to collect feedback and improve.
- Ability to enabled/disable features through our UI without engineer intervention or a full deploy.
At this point Feature Control manages features in the UI only. While this works well for us currently, it could be extended to control functionality in the backend as well.
When one of our users loads the application, we determine if they have beta access to any features, and grant them access (see Beta image below). Once set, the User IDs will persist between feature states. If we rollback from beta to disabled and then back to beta again, we do not need to re-enter the IDs a second time. When a feature is marked as disabled, nobody is granted access, no checks are performed. When a feature is marked as production, everybody is granted access. This is similar to Forrst's Bucket concept.
I’ve included a couple screen shots below to help visualize how we manage features from the UI.
We still use the same development-to-master workflow, only now we can merge the codebase back into master at a much higher frequency. Flickr embraces a similar paradigm, only they are not using branches.
If your team implemented something similar, let me know.