At HSD we are constantly striving to improve our processes across as aspects of the business especially in the software development space. While we have used TeamCity (https://www.jetbrains.com/teamcity/) for Continuous Integration (CI) for a number of years now, we constantly review our CI/CD (Continuous Integration/Continuous Delivery) pipeline tooling to ensure that the automation process doesn’t become more of a hindrance than a help. For instance, last year we successfully implemented Octopus Deploy (https://octopus.com/) at HSD and by splitting CI, the domain of TeamCity, and CD, the domain of Octopus Deploy, has helped HSD tighten the feedback loop for our Development and Testing teams. A symptom that we have been noticing on a last few projects is the amount of time needed to set up TeamCity to allow for CI. As the number of .NET projects increased to meet the clients requirements it became more time consuming to hand craft the MSBuild xml files for each project and then set up all the build steps in TeamCity to do NuGet package restores, Builds, running Unit , Integration and UI tests, creating internal NuGet packages for consumption by Octopus Deploy and creating the Octopus Release. The portability of the builds were becoming a major issue as well with so many build steps and TeamCity plug-ins being used if we (or the client) wanting the builds to be moved to Jenkins for instance, how would we achieve this? We decided that by using a build automation tool we could isolate the build processes to each .NET project or Commercial Off The Shelf (COTS) system and simplify our lives somewhat.
What was our story for our BDR (Behaviour Driven Research):
As a development team
When choosing a build automation tool
Then it should be easy to use
And be feature rich
And have good documentation
And have a rich eco-system of plugins
Our first attempt at solving the problem was psake (https://github.com/psake/psake). psake is a build automation tool written in PowerShell. The advantage that we saw with psake is that it is written in PowerShell and that means we had the power of .NET and all the features of PowerShell at your disposal within your build script. Having the power of PowerShell certainly improved the automation process of our builds and fitted in with our Dynamics CRM/365 and SharePoint build scripts that were written in PowerShell. As we progressed through the evaluation phase, one underlying “issue” began to occur again and again. To solve the problems of ‘how do we do run Unit Tests’ or ‘how do we run NuGet restore’, we continuously had to go back and learn the command line for NUnit or xUnit or Nuget. For simple use cases such as running Unit Tests or Restoring NuGet it seemed that we were still writing a lot of code (even if the functions were reusable) and we were trying our best to ensure that if we had to write code to solve a problem, the time spent was best utilised. In short we felt that psake failed to meet one (and only one) key aspect of our BDR and that being “And have a rich eco-system of plugins”.
Next we evaluated Cake (https://cakebuild.net/). Cake (C# Make) is a cross platform build automation system with a C# DSL automate the build process. The eco-system of Cake was the deal-maker for HSD. The built-in and Add-in eco-system for Cake is expansive (https://cakebuild.net/dsl/). Want to run Unit test using Fixie (https://cakebuild.net/dsl/fixie/) or NUnit (https://cakebuild.net/dsl/nunit-v3/) or xUnit (https://cakebuild.net/dsl/xunit-v2/)? No problems. Want to integrated with SonarQube (https://cakebuild.net/dsl/sonarqube/) or Octopus Deploy (https://cakebuild.net/dsl/octopus-deploy/) or DotCover (https://cakebuild.net/dsl/dotcover/)? No problems. While I am sure that we will encounter issues as we utilise Cake but so far it’s been an excellent experience apart from one small thing…..
- Visual Studio Code
The blog post, https://cakebuild.net/blog/2017/11/intellisense-vscode outlines steps that shows how to set up intellisense in VS Code for Cake files. I can tell you that this “simple” addition has made Cake scripting so much more productive. Therefore a retrospective thank you to the all of the contributors that made this possible.
The use of Cake has enabled HSD to isolate each build process and map the processes to one Team City build step per process group. In the case of a .NET WebAPI project the build step will now do the following:
- NuGet Restore
- Start the Sonar MSBBuild Scanner
- Build the solution file using MSBuild
- End The Sonar MSBuild Scanner
- Build the Test/s project
- Run the Tests
- Create the OctoPack package
Then once all of the build steps have completed, there is one final build step that invokes Cake to create an Octopus Deploy release using the current build version from TeamCIty. This process can not only be re-used in the UAT release build process but easily re-used across other TeamCity projects, which is ultimately the goal for a modern Development team.