Continuous deployment is the process of testing, integrating, and deploying software in rapid cycles in order to deliver bug fixes and new features to customers as quickly as possible. It gained popular acceptance as a cornerstone of extreme programming and agile development. It is very popular among Software as a Service providers.
A feature toggle system allows you to integrate features into your codebase even before they're finished and ready to release. During development, the features are toggled off by default. In order to turn them on, you must enable them manually. Using this method, you can deploy unfinished or untested changes into your production system without interfering with the user experience.
Feature toggles can allow software integration cycles that run in weeks, days, or even hours, as opposed to months or years. They are an essential component in a broader continuous integration system.
Feature toggles are popular in the startup community, but have gained widespread acceptance in the enterprise, including larger companies such as Facebook, Google, Yahoo, and Adobe.
Deciding how to organize features begins with deciding what exactly constitutes a feature. Once you figure that out, you should also decide how you're going to classify or group features together.
"Feature" can mean almost anything, ranging from a new page or route to an additional select option on a select element. Deciding how to classify the scope of the feature is up to the project manager, but it's easy to go overboard with features. My recommendation is to toggle at the page / route level whenever possible.
Features should be toggled on and off at the largest scale possible. For example, if you're building a new page, you shouldn't check whether the feature is on for every operation used to build up the page. Instead, toggle the feature at the route level. If the feature is a new element on the page, create a new view for that element, and only render that view if the feature is toggled on.
APIs should also use a feature toggle system, and the API should be capable of toggling at the route level, as well.
If you happen to use a hypermedia API and hypermedia-aware client, you can turn features on and off in the client simply by adding or removing resources from the API. For example, if you want to disable a route, just remove it from your hypermedia links, and the client won't be able to discover and use the route.
Sometimes it's handy to group features together. You should definitely do so for features that are designed to interact with each other. It's possible to build a feature dependency graph to keep track of which features rely on each other to opperate correctly, and then toggle them on and off simultaneously.
Groups can also be handy for marketing purposes. Sometimes it's useful to group several exciting new features together into a newsworthy release. For products that rely on publicity cycles to spur growth, engineering must provide the technical capabilities to generate worthy news events.
It's essential for product to engage marketing in a realistic way. The executives and marketing team should not start touting a release date until the features are in the testing stage and nearing completion. Features don't need to be released the moment they're complete. You can hold completed features for a scheduled marketing event, and flip the toggle switch at the precise moment that marketing has promised delivery. Since the features are already deployed into production, they'll be live and ready to use immediately.
Features are often grouped in default sets for each environment, as well. A default set commonly includes all of the features that will be toggled on in the next deploy cycle.
The creation of a feature begins with naming and documentation. Before you write a line of code, name and describe the feature, along with any required criteria to qualify it for production activation.
Start with a few functional unit tests. What does the feature do? How can you verify that behavior with code? Once that's done, begin the implementation, wrapping the lines of code that trigger the feature in a conditional block that only executes if the feature is enabled.
At the staging phase, features can be toggled on or off. Generally, the next set of production deploy defaults will be toggled on by default in staging.
It's possible to test new features in production without affecting the experience of regular users. Some apps have feature toggle consoles that can be accessed by authorized users in production. This can be a good strategy to enable manual testing. It's also common to enable clients to toggle features on and off using query parameters in order to facilitate automated testing.
Once features have been thoroughly tested in staging and production environments, they can be gradually rolled out to a percent of the general user population. You can start with 10%, and gradually increase it. Be sure to track critical metrics during the rollout, and be prepared to roll back feature toggles that have an adverse effect on critical metrics.
Default activation means that the feature is active by default across the whole system, and not on a user-by-user basis. A feature can stay in this state until it is no longer needed, or until it is phased out, or it can progress to full integration status.
Once a feature has made it this far, it's time to remove the feature toggle from the source code and the feature name from the features database. Cleaning up feature branching will reduce code complexity and make it easier to maintain the code going forward.
On the client side, you can show and hide features based on the presence of CSS classes. For example:
/**
* Takes an array of features and creates a class for
* each of them on the body tag.
* @param {array} features An array of active features.
*/
var setFlags = function setFlags(features) {
var featureClasses = features.map(function (feature) {
return 'ff-' + feature;
}).join(' ');
document.getElementsByTagName('body')[0].className +=
' ' + featureClasses;
}