We take a look at the definition of technical debt, its causes and types and how to manage it through the use of feature flags.
As more modern software development teams start adopting DevOps practices that emphasize speed of delivery while maintaining product quality, these teams have had to instill certain processes that would allow them to deliver releases in small batches for the purpose of quicker feedback and faster time to market.
Continuous integration (CI) and continuous delivery (CD), implemented in the development pipeline, embody a set of practices that enable modern development teams to deliver quickly and more frequently.
We’ll start by breaking down these terms to have a clearer understanding of how these processes help shorten the software development lifecycle and bring about the continuous delivery of features.
What is CI/CD?
A CI/CD pipeline first starts with continuous integration. This software development practice is where developers merge their changes into a shared trunk multiple times a day through trunk-based development - a modern git branching strategy well-suited for fast turnaround.
This method enables developers to integrate small changes frequently. This way, developers can get quick feedback as they will be able to see all the changes being merged by other developers as well as avoid merge conflicts when multiple developers attempt to merge long-lived branches simultaneously.
This also ensures that bugs are detected and fixed rapidly through the automated tests that are triggered with each commit to the trunk.
Afterwards, continuous delivery keeps the software that has made it through the CI pipeline in a constant releasable state decreasing time to market as code is always ready to be deployed to users.
During CI/CD, software goes through a series of automated tests from unit tests to integration tests and more which verify the build to detect any errors which can be quickly fixed early on.
This saves time and boosts productivity as all repetitive tasks can now be automated allowing developers to focus on developing high quality code faster.
We may also add continuous deployment to the pipeline, which goes one step further and deploys code automatically and so its purpose is to automate the whole release process. Meanwhile, with continuous delivery, teams manually release the code to the production environment.
To sum up, CI and CD have many advantages including shortening the software development cycle and allowing for a constant feedback loop to help developers improve their work resulting in higher quality code.
However, they can even be better when combined with feature flags. We can even go further and argue that you cannot implement a true CI/CD pipeline without feature flags.
So what are feature flags?
Before we go further, we will provide a brief overview of feature flags and their value in software development processes.
Feature flags are a software development tool that enables the decoupling of release from deployment giving you full control over the release process.
Feature flags range from a simple IF statement to more complex decision trees, which act upon different variables. Feature flags essentially act as switches that enable you to remotely modify application behavior without changing code.
Most importantly, feature flags allow you to decouple feature rollout from code deployment which means that code deployment is not equal to a release. This decoupling or separation gives you control over who sees your features and when.
Therefore, they help ship releases safely and quickly as any unfinished changes can be wrapped in a flag; hence, this allows features that are ready to be progressively deployed to your users according to pre-defined groups and then eventually these features can be released to the rest of your user base.
As a result, feature flags allow teams to deliver more features with less risk. It allows product teams, in particular, to test out their ideas, through A/B testing for example, to see what works and discard what isn’t before rolling the feature out to all users.
Therefore, there are many advantages to feature flags as their value extends to a wide variety of use cases including:
- Running experiments and testing in production
- Progressive delivery
- User targeting
- Kill switch
Ultimately, there is one common underlying theme and purpose behind those use cases, which is risk mitigation.
Incorporating feature flags into your CI/CD pipeline
Feature flags are especially useful as part of the CI/CD pipeline as they represent a safety net to help you ship features quickly and safely and keep things moving across your pipeline.
As we’ve already seen, CI and CD will help shorten the software development cycle allowing you to release software faster but these processes aren’t without their risks.
That’s where feature flags come in handy. Feature flags will allow you to enable or disable features and roll back in case anything goes wrong.
This way you can test your new features by targeting them to specific user groups and measure their impact in relation to the relevant KPIs set at the beginning of the experiment.
In other words, by the time you release your features to all users you’d have already tested them and so you’re confident that they will perform well.
To better understand how CI and CD are better with feature flags, we will look at each process individually and discuss how feature flags help improve the efficiency of CI and CD.
Feature flags and CI
You’re only undertaking true continuous integration when you integrate early and often. However, without feature flags, developers who have finished their changes will have to wait until all the other developers on the team have also completed their changes to merge deploy the changes.
Then, another issue arises when they don’t integrate often enough as this will result in long-lived feature branches that may lead to merge conflicts, and worst case scenario, merge hell.
Things become even more complicated as your developer team grows. With such delays, the purpose of CI would be defeated.
This is where feature flags step in.
Feature flags will allow developers to release their ready features without having to wait for others to be finished as any unfinished features can be wrapped in a flag and disabled so it doesn't disrupt the next step, which is continuous delivery.
Thus, feature flags allow developers to turn off portions of the code that are incomplete or causing issues after being integrated. This way, other developers can still integrate their changes often- as soon as they’re ready- without disrupting the CI process.
Furthermore, practicing CI means you have to integrate frequently, often several times a day but what happens when a build fails? Feature flags will allow you to rollback buggy features until they are fixed and can then be toggled on when they are ready.
Thus, any features that fail the automated tests upon integration can be simply turned off. This also helps to keep your master branch healthy and bug-free as you’re able to disable the portions of code that are causing problems.
Feature flags and CD
Continuous delivery’s essence is speed so you should always be ready to deliver something in small increments frequently. This means if there’s a feature slowing you down or contains bugs then you cannot deploy and so you’ve lost the whole momentum of CD.
Again, this is where feature flags come in.
If developers haven’t finished working on their code, it can be turned off until it’s ready and still proceed with the release instead of delaying it for an indefinite amount of time resulting in disgruntled customers.
Any complete features can then be turned on in the trunk and other features remain unaffected and can remain disabled until they’re complete as well.
In other words, feature flags will allow you to still deploy your code so if there is an incomplete feature, users won’t be able to access the functionality as it would be turned off using feature flags. Only when the flag is activated making the feature visible can users finally access it.
Continuous delivery’s purpose is to keep code in a deployable state but if you’re not confident about the release and you’re worried about its impact on your users, what’s the solution?
Well, what if you don’t have to ship the release to all users? What if you can target specific users, for example internally within your organization, before releasing it to everyone else?
With feature flags, you can target certain user groups so that you test your new features in production without impacting all users.
Thus, you choose who you want to test on by using feature flags. If a feature isn’t working like it should while testing in production, then you can turn it off until you figure out the issue.
Feature flags + CI/CD= The answer to fast and risk-free deployments
Feature flags, then, help keep your features moving within your pipeline in a quick and safe manner.
Using feature flags means you no longer need to do a full rollback of a release while you fix any issues which could potentially take so long that you risk losing customers.
To put it simply, feature flags give you a safety net when integrating and delivering features by giving you control over what portions of code you enable or disable.
The key to success in modern software development is speed in order to keep up with rapidly changing consumer demands. Otherwise, you risk losing the race to competitors.
However, if not managed carefully, feature flags can be more burdensome than valuable. Thus, feature flags require careful management and monitoring to reap its benefits without bearing its potential heavy costs.
When we talk about heavy costs, we refer to the potential of feature flags accumulating into what is known as ‘technical debt’. If you don’t have a system in place to manage all your flags then feature flags can quickly become a liability.
This is why using a feature flag solution such as Flagship becomes crucial. Such sophisticated platforms give you a way to track and manage all the flags in your system throughout their entire lifecycle.
For example, Flagship has a flag tracking dashboard that lists all the flags you have set up with their current values (on/off) and the campaigns that reference them. This would allow you to keep track of every single flag purpose. This will ultimately enable you to clean up any stale flags that you’re no longer using which would otherwise result in technical debt.