Jake Ginnivan's blog

My Typical TeamCity Build Setup

I posted Simple Versioning and Release Notes a few weeks ago talking about how to simplify release notes and versioning. This post is a bit of a cheat sheet for how I set up my builds.

Structure

I normally have two but sometimes three builds for each project. The structure is something like this:

  • TeamCity Project
      1. CI
      1. Acceptance/UI Tests (optional)
      1. Release

1. CI builds the solution with correctly versioned assemblies (update assembly info files with version before build), runs all unit tests then creates any packages which are required. This includes NuGet packages, Chocolatey packages, zipped binaries, clickonce installers etc. This build monitors pull requests and is triggered automatically when there are new commits/branches.

2. Acceptance/UI Tests is an extra I use when I have long running or UI tests, for example TestStack.White on TeamCity (sign in as guest) has this build setup and it runs Whites UI tests. The reason I separate it is for speed reasons, I want my CI build to fail fast and only if it is successful do I run this slow build. This build triggers whenever 1. CI succeeds

3. Release (or 2. Release if there is no acceptance/ui test build) is run manually and it releases the artifacts build by 1. CI, if that is a NuGet package it is pushed to NuGet.org, chocolatey packages get pushed to chocolatey.org, zip files get pushed as a GitHub release etc. Once this build succeeds it should tag the VCS root and push that tag.

Build Configuration

VCS Root

First step is to create our VCS root.
Type: Git
VCS Root Name: Project Name (all branches + pull requests)
Default branch: master
Branch specifications:

1
2
+:refs/pull/*/merge
+:refs/heads/*

If you are using stash it would be

1
2
+:refs/pull-requests/*/merge-clean
+:refs/heads/*

You should also put a username/password in to authenticate with the VCS root so we can tag in the release build

1. CI

This has two build steps, for this to work you should install GitVersion on your build server via chocolatey.

Build steps

  • GitVersion
    Runner Type: Command Line
    Step Name: GitVersion
    Run: Executable with parameters
    Command executable: GitVersion
    Command parameters: . /updateAssemblyInfo /output buildserver

  • Build project
    This should be setup however you used to do it, build your solution, run your build scripts etc.

Triggers

Add trigger VCS Trigger with the default settings which has a branch spec of +:*

Build Features

I have the report status to GitHub plugin installed, this plugin tells github the build status of pull requests so it can display warnings if a pull request will break the build

2. Acceptance test

This build varies greatly, if you need this build it has the same triggers and dependencies setup as 3. Release. I won’t repeat those settings here.

3. Release

VCS Root

The same VCS root which is referenced by 1. CI should also be referenced by this build

Build steps

Normally for me this just a NuGet push step. But whatever you normally do, use the artifact dependencies to get at the artifacts from your CI build to publish

Build Features

Add feature VCS Labelling
Labeling pattern: %system.build.number%
Label builds in branches: +:* (we want to label any release)
Check Label successful builds only

Dependencies

This is the important part, we want to setup a proper TeamCity build chain. 1. Add snapshot dependency for CI build and previous build in chain, so if you have 2. Acceptance tests then add a snapshot dependency for both CI and Acceptance test builds
Tick Do not run new build if there is a suitable one and Only use successful builds from suitable ones
The snapshot dependency is really important, it means that you release the artifacts associated with a specific git commit. If you don’t you can deploy artifacts which came from another branch =/ 2. Add Artifact Dependency to CI Build with these settings:
Get artifacts from: Build from the same chain
Artifacts rules: MyPackage.*.nupkg (or whatever artifacts you need to publish

General Settings

I put this last because you need the dependencies setup before configuring this page. Build Number Format: %dep.MyProject_Ci.build.number% (MyProject_Ci is the project ID of the CI build)

Wrap up

Hopefully this helps you get your TeamCity builds setup, I have found this setup works quite well and is easy to setup and keep running.

Updating Chocolateys Release Notes With GitReleaseNotes

Today I saw a tweet from Rob Reynolds today that Chocolatey 0.9.8.24 RC1 was released so I clicked the link which was straight to the closed issues list on GitHub.

I also noticed that many of the RCs and betas were not tagged in Git so you can’t see what was fixed each beta.

I have been working on a little utility to solve exactly this problem called GitReleaseNotes, the idea is that you install it via Chocolatey, then run GitReleaseNotes /outputFile ReleaseNotes.md /allTags and it will connect to your issue tracker (if the issue tracker is a REMOTE in your Git repository) fetch all the closed issues since it was last run and append them into your release notes. For public GitHub repos using GitHub issues these are the same so it just works, for Jira and YouTrack you will need to specify additional command line parameters

You then can manually edit, group and do whatever you want. All your modifications will not be changed when you run GitReleaseNotes again.

Using Approval Text in Tests

Using Approval Text in tests

I am currently using TestStack.BDDfy as my BDD testing framework. v4 has some great changes which make BDDfy really really awesome.

One of the things I am testing is generated confirmation text based on a number of selected form inputs. I want the approved generated text to be put into the BDDfy output. First steps are to read the approved file, here is a quick snipped which does this:

protected string GetApproved()
{
    var namer = new UnitTestFrameworkNamer();
    var basename = string.Format("{0}\\{1}", namer.SourcePath, namer.Name);
    var approvalFilename = new ApprovalTextWriter(string.Empty).GetApprovalFilename(basename);
    var approved = !File.Exists(approvalFilename) ? string.Empty : File.ReadAllText(approvalFilename);
    return approved;
}

Then I can just add my step in BDDfy .Then(_ => ApprovedGeneratedConfirmationShouldMatch(sut.DealSummary.ToString()), string.Format("Approved generated confirmation should be:\r\n{0}", GetApproved()))

Low Friction Octopress/GitHub Pages Setup

My blog uses Octopress which is basically Jekyll plus a whole bunch of plug-ins preconfigured and it is hosted on GitHub Pages. But sometimes I really miss being able to simply create or edit posts online. I started looking around and found Prose.io.

Prose is an awesome open source online Jekyll site editor for GitHub. Then if we setup TeamCity to automatically regenerate and deploy our blog when we make any commits we have a really simple way of making quick blog posts online.

Cannot Type Capital v on Sculpt Keyboard

At the MVP summit last year I picked up a Sculpt Ergonomic Desktop pack, mainly because I cannot stand the UK keyboard layout and wanted to stay on the US layout while working in London.

I just had a very strange issue, I could not type a capital V, lowercase worked fine. Plugging into another machine showed the same issue.

One of the problems with the Sculpt is that the function keys get stuck. Apparently if the F5 key gets stuck, then you can no longer type a capital V. If the F2 key is stuck then you won’t be able to type a capital C.

If you hit this random issue, hopefully you will read this post before returning your keyboard.

Disable thumbs.db

Thumbs.db is created by windows whenever a folder has images in it as a cache for the thumbnails for the images. But it gets locked and stops me switching branches in git and I have to restart my PC sometimes.

Save this as KillThumbsDb.reg and run it as administrator:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Explorer]
"DisableThumbsDBOnNetworkFolders"=dword:00000001

I have no idea why thumbs.db is being created in local folders, but this fixes it for me.

Unknown Git Mergetool

Today my git mergetool stopped working. When I ran git mergetool I was greeted with:

git config option merge.tool set to unknown tool: --global
Resetting to default...

This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
tortoisemerge emerge vimdiff
No known merge tool is available.

Somehow (seriously, I have no idea how I did this) I had created a setting in one of my repositories set my mergetool to --global.

If you happen to get yourself into the same issue, run git config --list to see what your config settings are.

For me, I had a rogue merge.tool entry, so I just had to run git config --unset merge.tool which deleted the entry and I was off again.

BDDfy v4.0 Beta 1 Released

We are excited to announce v4 beta 1 of BDDfy! To give it a spin just change your NuGet settings to include pre-release and update. v4 has a bunch of new stuff included which takes BDDfy from not only the simplest BDD framework for .NET but also one of the most powerful!

Please give it a go and report any issues/feedback you have so can fix them before the final v4 release.

BDDfy v4.0 Examples Support

One of the major features in BDDfy v4 is the inclusion of examples

Scenario: Successful rail card purchases
Given: the buyer is a <buyer category>
And: the buyer selects a <fare>
When: the buyer pays
Then: a sale occurs with an amount of <price>

Examples:

| Buyer Category | Fare          | Price |
| Student        | Monthly Pass  | $76   |
| Senior         | Monthly Pass  | $98   |
| Standard       | Monthly Pass  | $146  |
| Student        | Weekly Pass   | $23   |
| Senior         | Weekly Pass   | $30   |
| Standard       | Weekly Pass   | $44   |
| Student        | Day Pass      | $4    |
| Senior         | Day Pass      | $5    |
| Standard       | Day Pass      | $7    |
| Student        | Single Ticket | $1.5  |
| Senior         | Single Ticket | $2    |
| Standard       | Single Ticket | $3    |

This is an example of a Cucumber test with examples, for each row in the examples table the test will run effectively giving us a data driven BDD style test.