Jake Ginnivan's blog

Release NuGet SemVer Packages From Teamcity

I have a number of open source projects and I do not really have a good release process. So I spend the arvo trying to figure out a good way to do it.

My goals were

  • Use GitHubs releases feature - https://github.com/blog/1547-release-your-software
  • I want to release from NuGet
  • Preferably write release notes before I click the button in TeamCity, this way i can add them on github to build up a release
  • Support SemVer, including pre-release packages
  • Assembly versions should be stamped with informational version as well as a version
  • Be able to link to the project GitHub releases from the NuSpec

My Solution

1. Setup the VCS Root to be authenticated


Then tell TeamCity to Label Successful builds Release-NuGet-SemVer-packages-from-Teamcity11

2. Setup some additional build parameters


2.1. AssemblyVersion

This is the assembly version, only change this for major releases, this will save people adding binding redirects when different projects rely on different versions Release-NuGet-SemVer-packages-from-Teamcity1

If you want the text version of the spec, it is

text description='The assembly version which will be stamped (assembly info version/nuget version will be the build number)' display='prompt' label='AssemblyVersion' validationMode='not_empty'

2.2. Prerelease

This is a checkbox, when ticked it’s value is -pre so we can just use it in the version Release-NuGet-SemVer-packages-from-Teamcity3

Once again the text version of the spec is

checkbox checkedValue='-pre' description='Check this box if you want a pre-release' display='prompt' label='PreRelease?'

2.3. Version

This is the version which you will pass to NuGet when you are creating your package Release-NuGet-SemVer-packages-from-Teamcity5

text description='This is the version number, adjust the major/minor as needed to conform to semver' display='prompt' label='VersionNumber' validationMode='not_empty'

2.4. env.Version

This is just so the version gets set as an environmental variable so my build scripts can pick it up


I am not sure if this is actually needed.

3. Build Steps

I always have a .proj file checked in for all of my projects which contain all logic to build the solution, I just have to tell teamcity what targets to invoke. If you want to view my build script, check out https://github.com/TestStack/ConventionTests/blob/master/ConventionTests.proj


The Test target builds and runs my unit tests, then the Publish Target builds the NuGet packages, step 2 of my TeamCity build is Publish to NuGet


Finally, the assembly info stamping build feature. Click Add build feature

We want to use two different versions from our config, remember from above we have


4. Update the build version

Finally go to the General Settings of your build, and update the build number format to be: %Version% and we set the build counter to 0

Releasing a new version

So now, we have to stick to SemVer, let us run through a scenario of releasing a minor release (new non-breaking feature) of TestStack.ConventionTests. The current release is v2.0.0. I first need to reset the build counter back to 0, if you don’t want to mess with the build counter, just change the VersionNumber variable to have a manually updated patch version. This actually is probably better because then the version numbers are more predictable.

Create release definition in GitHub

Release-NuGet-SemVer-packages-from-Teamcity16 Release-NuGet-SemVer-packages-from-Teamcity17

Specify the release notes for this release Release-NuGet-SemVer-packages-from-Teamcity18

Do not have the Publish Release box ticked, otherwise GitHub will create the tag for you.


Release from TeamCity

I click Run in TeamCity, and I will be prompted to confirm everything


Because this is a minor release, I increment the minor version number Release-NuGet-SemVer-packages-from-Teamcity15

Now hit run, this will publish to NuGet and create the tag in Git. The final step is to go back to GitHub and publish the release (this is not done automatically, and I’m sure it could be automated through the GitHub API).

This is my first attempt at making it easy for me to release my open source projects with SemVer and GitHub Releases