Note that I’m using TeamCity 9.0 (build 32060) and GitVersion 2.0.1. These steps may be different in future versions. GitVersion seems to be slated for a 3.0 release very soon.
I’m setting up TeamCity using GitVersion for a new open source project that I want to deploy via NuGet. I’ve used TeamCity a few times to set up basic builds but I’ve never got SemVer working in a nice way before, so I thought this would be a nice opportunity to try GitVersion.
The Release configuration is triggered manually to deploy the last built version to NuGet. It would probably be nicer to do this from Octopus but for now I’ll just use TeamCity.
iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
Then install GitVersion:
You may also have to install msysgit. TeamCity has its own Git client built into the server but GitVersion needs to be able to access the Git history on the agent, which means the VCS checkout has to happen on the agent (configured below). Reboot the machine once this is done to make sure everything is on the path.
Now start setting up the project in TeamCity.
Now create the first build step for GitVersion. I used Jake Ginnivan’s post on his typical TeamCity build setup as a guide.
. /updateAssemblyInfo /assemblyVersionFormat MajorMinorPatch /output buildserver
Note that there is a space between the
. and the
Note with the 3.0 release of GitVersion the command parameters may be able to be removed in favour of a
GitVersionConfig.yaml configuration file. Stay tuned.
Now create another build step to build the solution.
PROJECT_NAME.sln. Select the step then clicked Use selected.
.gitfolder will exist and GitVersion should work properly.
To run GitVersion before building the solution:
Now select Triggers and Add a new trigger. Select VCS Trigger then Save.
Running the configuration worked for me at this point, resulting in a build versioned
0.1.0+21 (there were 22 commits, so that’s 21 commits since version
0.0.0). If you get an error about not being able to find
git.exe make sure the build agent has rebooted and that GitVersion and Git are on the path.
Next you can add a step to run tests. I’m using xUnit. This is just a Command Line runner with the following custom script:
First you need to add a
nuspec file alongside the library being released (add it to the project in Visual Studio) and push it up so TeamCity can see it. For example,
<?xml version="1.0" encoding="utf-8"?> <package> <metadata> <id>frankenwiki</id> <title>Frankenwiki</title> <version>0.0.0</version> <authors>Ben Scott</authors> <description>Markdown based statically generated wiki engine</description> <language>en-US</language> <licenseUrl>https://github.com/frankenwiki/frankenwiki/blob/master/LICENSE.md</licenseUrl> <releaseNotes>https://github.com/frankenwiki/frankenwiki/releases</releaseNotes> <projectUrl>http://frankenwiki.com</projectUrl> </metadata> <files> <file src="bin\release\Frankenwiki.dll" target="lib\net451"/> </files> </package>
The easiest way to generate the NuGet package (
.nupkg) seems to be Octopack. Install Octopack to the library being released and push the changes up to the repository. Now edit the CI configuration and in the Visual Studio (sln) step (the actual build step) show the advanced options and add this to the Command line parameters:
Now when a build happens, OctoPack will create the
.nupkg file named something like
Frankenwiki.0.1.0.nupkg. This package gets consumed in the next step. Trigger a build now to make sure everything works and the package is created as an artifact.
Create a new build configuration called Release or Promote or Fly, my pretties, ah hahahaha!:
.nupkgfile (so it is independent of the version). Eg.
The last few steps are directly based on Jake’s post. Go to Build Features to set up labelling:
build-%system.build.number%. Take out the
build-part so it is just
Now go to Dependencies to set up the build chain:
Go to General Settings and show advanced options. Change the Build number format to the following:
MyProject_Ci is the build configuration ID of the CI step. Once you type in
%dep it will suggest the available configurations.
Now you should be able to trigger a Release, which should successfully publish the package to NuGet! If everything works.
TeamCity can build feature branches and tags. This lets GitVersion version feature branches to reduce surprises.
+:refs/heads/*(Working with Feature Branches)
Jake’s post about Simple Versioning and Release Notes has some great info about changing the version but a good one seems to be using a feature branching strategy.
Push a branch with the new version number in the name. For example:
git checkout -b version-0.3.0 git commit ... git push
Note that just pushing the branch won’t trigger the branch build, there needs to be a non-empty commit.
You can see that TeamCity has built a new release from the feature branch and GitVersion has versioned it at
0.3.0-beta.1+4. Subsequent commits to this feature branch will increment the build number (eg.
0.3.0-beta.1+5). When the feature branch is merged into master, the master version will become
0.3.0 and you can just manually run the Release configuration to deploy to NuGet.
Don’t add a branch or a commit with a version number in it unless you expect it to bump the version number. I merged a branch called
change-to-dotnet-4.5.1 which GitVersion helpfully interpreted as a version bump to
4.5.1. I had to fix this by rewriting the commit comments to say
If GitVersion report a particular version but Octopack generates nuspec files with a different version, check in the
AssemblyInfo.cs file for a different version in the
AssemblyFileVersion attributes. This can be due to the versioning scheme, which can be set using the
/assemblyVersionFormat parameter as above (or in
GitVersionConfig.yaml once it is supported by GitVersion).