Our CI/CD and release management process at Flagsmith
At Flagsmith, our mission is to help engineering teams build faster and continuously improve their products. At Flagsmith, we build our product completely in the open. We do this because we see feature flags as a part of a long-term product and infrastructure decision that teams are making. When doing this, we believe that our customers should be able to see exactly what we are doing and how we are improving the product over time to best support them.
To serve our mission and live up to being an open company, one of our goals for this year is to start engaging (and hopefully helping) on the topic that surrounds CI/CD. In this post, you will see how our team at Flagsmith has decided to create our CI/CD Pipeline, CI/CD process and how we use automation to drive speed and security to our deployments. Let’s dive into what is a ci/cd pipeline & in the process in detail:
Here are the main “buckets” that we consider in the software development process:
1. Code & Review in CI/CD process
Let's start with CI/CD code review - nothing too crazy here…but at Flagsmith, engineers create code on their local machines with the IDE of their choice. The most common among the team was Jetbrains and Emacs. Flagsmith is built on python, so a lot of the tooling that you’ll see throughout this presentation are geared towards that technology.
Once engineers are happy with what they’ve built, they then create a Pull Request to our Github Repo (github.com/flagsmith/flagsmith):
When the Pull Request is created, the code is then sent to the team to be picked up for a code review. We have tons of opinions on code reviews and ideal team sizes that we’ll be sharing in subsequent articles. For now, here is a quick example of a back-and-forth between the team to improve the original PR:
After feedback is incorporated into the PR and everyone is happy, the PR (Pull Request) is approved which concludes the human process of getting this into production:
2. Testing & Linting
At Flagsmith, we made a decision to build our product in the open and with that in mind, it was an easy decision to choose Github Actions. Beyond making it really easy to combine our day-to-day efforts with community engagement all in Github, they also provide some great automation for CI/CD. This is where we leverage Github Actions to accomplish the following:
- Units Tests - unit testing our python API code
- E2E Tests - running the entire platform (front end, API and database)
- Linting - checks the code for formatting and style
Here is some of the automation that we mentioned in Github Actions:
Once the Pull Request has passed the linting and testing phase and all the tests above are green, the code is now ready to be merged to our main branch github.com/flagsmith/flagsmith. This then kicks off the third step of the automated CI/CD process.
3. Build to Staging
In this step, we are now building the software towards a specific infrastructure (which hopefully is the same as your production) for a check to make sure everything is running smoothly in ideal conditions. This stage consists of the following:
- Build and deploy to our staging (Is it time to delete your staging environment?)
- Run End-to-End Tests against staging
After the code passes this bar, we are now ready for the final step in our CI/CD process.
4. Deploy to Production
We are in the final stage and can already hear the customers rejoicing in our work! ;) As we deploy to production, we create a git tag off our main branch that then triggers the following workflow:
- Build all our Docker Images and push them to Docker Hub
- Push the Docker Images to our internal AWS Docker repository
- Trigger an AWS ECS Deployment that deploys our API into production
- Run E2E Tests in Production
And finally, we’ve done it! Oh wait…there is one more step that we use at Flagsmith and that is the final and fifth step…Release.
5. Release/Test in Production
Most teams consider step 4 the same as step 5, but we see this as distinctly different. In some cases, we don’t want the deployment to be the same as all of our users getting access to the newly built code. In this case, we wrap certain features in a feature flag and have a release plan for each feature. The steps we take here are:
- Set targeting conditions for the feature to specific users or percentage of users.
- Manage feedback from users or performance indicators to finalize any changes to the feature.
- Finalize release & monitor performance over time (btw, here are 6 metrics to monitor when you roll out features).
Hopefully this was a good overview for you all to learn more about how we do things at Flagsmith. Since we build in the open, we also appreciate any and all feedback on how we can improve.
If you liked this article, you might be interested in this: Delete your staging environment.