A clean, automated and reliable build and release process is every good developers dream as well as being a cornerstone of any agile development methodology. Fortunately for .NET developers this dream can become a reality with unbelievable ease by combining Team City and Octopus Deploy.
In this post we will go through the finer points of configuring Team City and Octopus Deploy to do just that. I’ll assume you know the basics of both systems and that they are already installed in order for us to focus on the more important details.
In this setup Team City is the driver of the process and does all the hard work of pulling the source, building, running tests, managing version numbers and creating the release in Octopus. For each build configuration the build steps look pretty much like this:
We will now look at some of these build steps in more detail.
If you haven’t already you will need to install the Octopus Team City plugin.
Managing Version Numbers
We let Team City manage the version numbers. The critical part is to ensure the version numbering is consistent between Team City and Octopus Deploy. That way when we talk about a version of the code, we know exactly which release on Octopus, exactly which build on Team City and exactly what point in history the source code was at.
In order to make sure the release number in Octopus is the same as that in Team City we get Team City to instruct Octopus to create the release and explicitly pass in the version number.
Build Number Format
Each time a build runs the fourth part of the build number is automatically incremented. Any changes to major, minor and patch versions are controlled manually.
Build, OctoPack and Publish to Octopus Feed
This build step does quite a bit of work: compiling the solution, packaging it using OctoPack and finally publishing the nuget packages to the Octopus feed.
Pass in the
%build.number% variable as the nuget package version number. This is how we use Team City to ensure the version numbers match.
Deploy to Octopus Feed
In this build step we also push the nuget packages created by the build to the nuget feed hosted by the Octopus server.
It’s important to note that you can’t really use the Team City nuget feed here because the packages are not available for the next steps. The only way to get it working with the Team City feed would be to have a second build configuration trigger off the first one. I like to keep the build configurations to a minimum and the approach adopted here is clean and works well.
In order to instruct MSBUILD to publish the packages to the Octopus feed we provide additional command line arguments that point to your Octopus server and publish to the Octopus feed using the provided API key (you can create these from the Octopus administrative interface).
Using the OctopusDeploy: Create Release step provided by the plugin we again point Team City to the Octopus server.
Provide the name of the project you wish to create a release for as well as the release number, which matches the build number.
It’s also vitally important to instruct Octopus to select the correct package versions from its nuget feed. Do this by passing in
--packageversion %build.number% as an additional command line argument. If you do not do this Octopus will simply pick the last package based on version number. This is not what you want to happen when creating a release build if more recent packages are available on the feed.
AssemblyInfo of the build so that the version matches the build number. This is a very neat trick as it allows to display the actual release number in your application. In order to do this we use Team City’s Assembly Version patcher to set the assembly version to the build number.
Tagging / Labelling in TFS
Add a build feature to label the version of the source that was used to create the build. This makes it easy to get back to the original source associated with any release.
Using the Lifecycles feature of Octopus 2.6 we can automatically deploy the release to the first environment automatically after it is created by Team City:
I’ve tried to keep this short and sweet maintaining a focus on the key pieces that tie these two technologies together. From this post you should have enough information to create your own automated release process.