The good thing about crisis situations is that they force you to think out of the box. If you have read my post about implementing continuous delivery, you know that I recommend the use of feature environments; an environment containing only a specific feature branch to QA a feature before it gets released. Let me tell a story of how this usage of feature environments expanded to be much more valuable than I had expected.
We were planning how to ship a new release, a very risky one including a change in the core functionality and a new authentication client. We knew that we needed to test the waters in production or we would most likely take down the site. Thinking how we already were using feature branches in the dev environment an idea appeared:
What if we just create a feature environment in production to test the waters, and then ship it to prod after we have tested without errors?
In that post, I’m talking about why and how to setup feature environments in all your environments, so you can become a release machine.
What is a feature environment?
A feature environment is a feature branch hosted on as a separate environment enabling QA to test that feature separately before deploying it to production. More technically, this is a feature branch deployed as a subfolder to your application server, so you can go to a feature using eg. *application-server-url*/*feature-branch-name*.
Why should I create feature environments?
Feature environments enable you to have a staging environment for every single feature. This means that QA can access and test that feature separately. Often you see a setup with a shared staging environment, where a lot of features are mashed together, often motivated by an ineffective release process, making the team bulking features for every release.
Faster delivery of value by shorter deployment pipeline and smaller badges
You want to decrease your lead time from writing the user story to releasing the feature as much as possible because a feature is worthless until it is released. How do you do this? By making the path from a to b shorter and by shipping a smaller badge from a to b.
Making a shorter path from a to b
Small and simple is good when it comes to IT systems. Especially a CI/CD pipeline as this will move the feature faster to the end goal: production. With feature environments, the only environments you need is dev/sandbox environment with fake dev data and the production environment. Having this simple setup simplifies the maintenance a lot and I have yet to see a use case this setup does not support.
As a contrast, you see organizations that have 4 environments between dev and prod! No wonder that these organizations are the ones that have the biggest problems with the release process and don’t release more than once a month. Using feature environments you can test the feature you are about to release in dev and prod without impacting customers and then release when the feature has been successfully quality assessed.
Ship small badges
The more a release contains the riskier it is, so what is the logical way to make release less risk? Ship smalle badges.
Shipping a smaller badge makes everything easier: less to test in QA, easier tech review and in case of errors, easier to see what change caused a problem and recover.
Having feature environments in all environments
Now we know why feature branches are beneficial and I have recommended a simple setup with only two environments, why is it good to have feature environments in all environments? By having feature branches in all environments you are able to test a feature, staged in a pull request, in both the dev branch and the production branch before it is even released! This is way easier than shadow deployments with feature toggles, as it requires no changes in the application code to set this up.
My recommended release flow
My recommended process to go from picking a task and releasing it is as follows:
- Developer picks a task
- Developer implements task
- Developer create pull request and assigns QA and tech (by creating pull request feature environment is ready for QA and is automatically being end-to-end tested)
- QA and Test comes with feedback until the pull request is accepted
- The pull request is merged to master, which makes the feature branch package being deployed to production
- The production environment is automatically smoke tested using automatic end-to-end testing.
How to set up feature branches in all environments
If you already have a CI/CD pipeline setup it is very easy to extend it to support feature environments.
What you want first, you want a trigger on your CI server when a code is pushed to a feature branch. This trigger will do the usual build and test step but when it comes to deployment is where the difference is. On your deployment server, you want to create a new deployment project for deploying the feature branch as a subfolder of the application server. The only thing that you want to know here is what the name of the feature branch is. You can get that by doing a simple PowerShell script on the TeamCity server for getting the branch name without a prefix, such as
CI systems usually have some variable to get the branch name, in TeamCity, it is eg.
%teamcity.build.branch%. When you have the full branch name you can get only the feature name by using a PowerShell script such as:
From here you write this branch name to a file you send to the deployment server, so it now knows what to name the feature environment.
In this post, we looked at the benefits of having feature environments available in all your environments so you can easily test a feature in eg. the production environment, which enables faster and safer deployments. We looked at how feature environments fit in my recommended workflow for enabling continuous deployment.
Lastly, we saw how to set this up in the CI CD pipeline by extracting the feature name on the CI server, doing build and tests and then use that feature name on the deployment server to deploy the feature environment as a subfolder on the application server.
If you liked this post make sure to comment, follow me on Twitter and subscribe for weekly posts about how to become a better Angular developer.
Pingback: End-To-End Testing with Protractor: A Pragmatic Guide to Get Started in Your Team – Christian Lüdemann IT()
Pingback: Why Angular Teams Fail at Code Sharing and How This Monorepo Approach Will Fix It – Christian Lüdemann IT()
Pingback: Why I Moved from Protractor to Cypress and the 7 Steps to Cypress E2E Testing Success – Christian Lüdemann()