Using our continuous integration tool to continuously integrate our continuous integration tool
Kyle Johnson Jun 14
During the development of our feature flagging tool Bullet Train, we got to the point where we were actually using Bullet Train to develop Bullet Train so that we could continuously integrate while we continuously integrate.
We developed Bullet Train with the belief that continuous integration is something that all development teams should aspire to. Feature flags and remote config can be a huge help to the achieving the goal of CI, especially into production. So, following this belief and to avoid being hypocritical we used its benefits to CI to develop the tool itself.
Bullet Train is an open source project that lets you separate releasing and configuring features from code. You can manage feature flags and remote config across several languages on web, mobile and server-side applications.
Using CI and Bullet Train is not all or nothing decision
Developers often consider taking the leap to continuous integration as an all or nothing decision, but it doesn't have to be that way. CI can be used at any point in your project using feature flags to roll out into production on a feature by feature basis.
A great example to demonstrate this is how we started to use Bullet Train on itself. We pushed out an initial Beta release in June 2018. Immediately following the release we started on a forgot password feature.
At this point the project was stable, we had End to End tests using Nightwatch that ran with every commit we pushed, so we were in a great place to start using continuous integration. These are the exact recorded steps we took to create a project and integrate the new forgot password feature with Bullet Train.
Step 1: Signed up
We created an account on https://bullet-train.io.
Step 2: Created a project
Step 1 automatically created an organisation called Bullet Train and added me as a member. The next step was to create a project.
Step 3: Created a feature flag for "forgot password"
Bullet Train automatically creates a development and production environment for newly created projects. We created a feature flag called forgot_password.
Step 4: Integration
As soon as I created the feature I was provided with a couple of code snippets to install and integrate into our code.
Of course, how you integrate it is up to you. In our case, we had a React application and a Flux store which broadcasted when feature flags changed. Finally, our homepage would show the forgot password link depending on what Bullet Train returned. You can see the commit for this process here here
Using feature flags meant that I could release this feature into production as is without holding up other development.
Step 5: Enabling the feature
With my new forgot password feature in production all I had to do was enable it so it could be deployed to the world. As soon as I enabled the forgot password feature in the dashboard I could see it on the site.
How does this help us?
People who are not used to continuous integration might be wondering: why didn't I just release the feature the way I normally would? Some of the reasons for feature flags being such a good approach:
- It allowed me to move to enable continuous integration for production. Every commit that is pushed to master now automatically builds to production.
- It introduces the ability to test code in production with gradual/targeted rollouts to specific users.
- It empowers non-technical team members to manage feature releases.
- It enables testing of features early, against an up-to-date codebase. CI means we're constantly testing features on a very close representation to what is running in production.
- It allows you to introduce beta programs to get early user feedback.
- It reduces the need to rollback code with the ability to turn off features remotely in the event of an emergency.
This week I want to talk about something that I have used for a excuse quite a few times. Before I finally started getting a schedule going. And that is saying the excuse I don’t have time to learn blank.