Step 4: Invest in continuous integration and delivery
More often than not we see very limited automation in how environments are set up, how source code is built, and how deployments are handled from environment to environment.
A sample scenario would look something like this: engineers are working on local machines and checking code into a source repository (TFS, Git, etc.) Each developer tests their code, builds the solution locally to make sure it runs as expected, ad infinitum until the project is finished and ready for testing. SIT/UAT phase kicks off and all hell breaks loose. Integrations don’t work, defects come crushing down in endless Excel documents exported from the enterprise QA system, and timelines slip. Worst case, all projections of cost/timeline get thrown out the door because these problems were discovered once delivery was already finished (i.e., at the end of the project when a majority of the budget has been spent).
Continuous Integration (CI), a development practice and toolset that enables engineers to integrate their code into a shared repository on a daily basis, to the rescue. CI build servers run automated tests and build the product, allowing individual contributors to detect defects as soon source code is checked in.
For the sake of keeping this white paper shorter than Homer’s Odyssey I will assume your applications have separated environments for development, staging, QA/UAT, and production. If not, invest in infrastructure prior to standing up a build server and implementing continuous integration. Hardware requirements for dev/staging are likely a fraction of your production instance, so costs should be reasonable.
A word of caution: setting up continuous integration involves infrastructure teams, hardware, and software licensing. It’s important to note, however, that environment setup costs are very small when compared to lower QA costs, product quality, and increased delivery velocity. Let’s look at a specific working example as a guideline for CI costs/configuration.
Two leading platforms are TeamCity (licensed) and Jenkins (Open source). In either scenario you will need to set up a build server, as well as agent servers for your end-points (e.g. web application, native mobile apps, etc.).
So what are the benefits?
You avoid a lot of the conflicts when merging code because everyone is using a single repository, committing, and building every day (and often several times a day).
Deployment is automated. Single click. You go to the TeamCity control panel, initiate deployment and watch as you production environment is updated to a copy of the application in your QA/UAT environment. Or isn’t if there are build errors, but likely there aren’t because you have been building every day, multiple times a day, across multiple machines, and running automated tests.
Your delivery becomes predictable. There are no last minute hot-fixes. No calls at night or on the weekends.
Your infrastructure, support, and QA costs go down because you get more done quicker, with less.
I touched on several important subjects in this section a very conceptual level. More detail can be found in our article
Continuous Integration, Delivery and Deployment in .NET projects.