Over the last few months as Tech Lead I've had the pleasure of implementing the Continuous Integration and deployment solution in our workplace. Having done this previously in another company, I was the natural choice to champion the project especially as there was no-one taking overall responsibility for QA (Quality Assurance).
Why have a Continuous Integration solution?
With no CI solution in place no-one knows whether code currently checked in builds.
A CI solution helps developers get away from the 'well it builds on my machine' mind set. The build state on the build server becomes the 'single source of truth'.
It helps quickly identify any code checked in that causes compilation or unit tests to fail.
Why have a deployment / release management tool?
Our old release process had manual steps and an in house deployment tool (which just called WebDeploy/called Powershell scripts). With over 40 websites across 3 environments (Test/UAT/Live) deployment was becoming so time consuming it was almost someone's full time job. Rolling back was a slow/manual process
So we decided that the new CI and deployment solution
- Must be able to automatically check dozens of projects
- Must be able to run automated unit tests
- Must fail fast if applicable
- Must notify developers of compilation errors
- Must notify developers of failing unit tests
- Must work with Subversion (initially)
- Must work with Git (presently)
- Must provide mechanism for deploying websites to Test, UAT and Live environments
- Must interact with our load balances servers, enabling/disabling where necessary
- Must run integration tests post deployment but pre enabling of servers
- Must allow easy rollback if a release is found to have issues
We looked at some open source options and considered rolling our own (in fact the previous deployment tool was written in house) but settled on the following commercial tools.
TeamCity for CI
Developed by JetBrains (the same people that bring us ReSharper), TeamCity is a Continuous Integration solution. Building is done on separate build agents which can be on different machines. Multiple build agents mean more projects can be built concurrently. By default I believe a typical license comes with 3 build agents, so if you kick off 5 projects to be built at the same time 3 will start immediately and the remaining 2 queued until a build agent becomes available.
Octopus Deploy for deployments
Octopus Deploy is deployment / release management tool developed by Paul Stovall.
The product comprises of server service and web dashboard which once installed and running can deploy code to and administer any target machine with Octopus 'tentacles' installed.
Here is our new improved process now (give or take a few details)
- Every time code is pushed to the Git repository it is
- checked out by TeamCity
- MSBuild ran to ensure all code compiles
- Unit Tests are ran
- When a release is required to be put on the test server, a project is ran on TeamCity that precompiles the code and packages it into a NuGet package which is published onto the TeamCity NuGet feed. At this point a tag (the project name and build number) is automatically created in the Git repository denoting what code is present in which release.
- In OctopusDeploy a 'release' is manually created that by default uses the last relevant NuGet package from TeamCity
- That release/NuGet package/code is then deployed to the Test server by OctopusDeploy and any manual tests done against that.
- Upon testers approving the tests, the release is 'promoted' to the UAT environment with OctopusDeploy.
- When the version is approved during UAT then the release is 'promoted' to the live environment with OctopusDeploy.
- Once the code has been deployed to the Live environment but before the hidden server is made visible again, selenium integration tests are ran against a selenium grid that tests that the UI responds in an expected manner when interacted with (i.e. That a customer can log in and place an order)
- Octopus deploy has steps that disable/enable appropriate load balanced servers to ensure that the release does not effect any current users of the websites.
- Assuming that the integration tests pass, the 'hidden' server is made visible and the process repeated on the other load balanced server.
Next steps I want to do
- Automatically update Test environment whenever there is a check-in (continuous deployment)
- Also run automated selenium UI integration tests on the Test & UAT environments
- Automatically include release notes in OctopusDeploy release based upon Git commit messages
- Make the buildserver easier to tear down/re create (perhaps via VM or similar) as the build server has a number of dependencies that need installed in order for TeamCity to build our solutions
- Install additional build agents. Whilst we currently manage with 3 build agents, additional build agents (at ~£250 per additional agent) would reduce the amount of builds being queued especially as I see us including more of our projects in this process.
- Create a better 'at-a-glance' build status dashboard which calls the TeamCity REST API to retrieve and display project build statuses.