Feature Environments in All Environments – A Guide to Faster Delivery

Share on facebook
Share on google
Share on twitter
Share on linkedin

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:

  1. Developer picks a task
  2. Developer implements task
  3. 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)
  4. QA and Test comes with feedback until the pull request is accepted
  5. The pull request is merged to master, which makes the feature branch package being deployed to production
  6. 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 feature/ or bugfix/.

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.

Do you want to become an Angular architect? Check out Angular Architect Accelerator.

Related Posts and Comments

Angular Projects and Lessons Learned

Throughout my career, I have worked on quite a few Angular projects. In this post, I will go through some of the different projects I have worked on and explain the lessons learned in each so you can learn from them. Ionic + Cordova mobile app with AngularJS (2015) This app was about creating an

Read More »

The monorepo blueprint (live talk)

I just did this live talk at AarhusJS – a Javascript meetup in Aarhus (Denmark), my hometown 🙂 The talk extended upon the lessons learned after working with Angular monorepo projects and will teach you about: Creating a good Angular architecture Case study: Monorepo architecture Using Sandboxes/facades Organizing libs and conventions in a monorepo Enforcing

Read More »

Angular Automation: 6 Things That Should Be Automated in Enterprises

Handling anything at a big scale always is very different from when things are small. The differences can be in the number of people working with something, the business impact of decisions and the ability to enforce the execution of decisions at a large scale. I have in the previous post talked about different tools

Read More »

Implementing Continuous Delivery through Five Steps

These days everywhere I go people seem to talk about wanting to deploy to production more often. It seemed like an endless battle trying to deploy more often as the amount of code to deploy seemed to bulk up in big batches, while we were rambling about buzzwords such as “CI/CD” and “feature toggles“ without

Read More »