Automatically determine a version using GitFlow or GitHubFlow

I am a big fan of automating builds. Even for simple and small projects, the builds should be fully automated. This makes sure that the software is built on a different machine than it is developed on. A great side effect is that the unit tests are really ran (because how many developers actually run the unit tests before checking in the code?). I am also a big fan of GitFlow. I won’t go into details, but I like that fact that you can always release a hotfix on the master branch while keeping a separate development branch.

After reading this blog post, you can automatically determine the version of software that follow GitFlow or GitHubFlow:

image

Stop versioning the software yourself

One issue though is that you have to manage the versioning in the Continuous Integration (CI) software. Managing the versions of all software projects I contribute to is almost a daytime job. Then I came along an awesome project called GitVersion. It can automatically determine the version of your software based on your repository. This means you no longer have to manage any states of the software, but you can simply ask GitVersion to determine the version for you following the GitFlow / GitHubFlow:

Copyright notice: image originally comes from the GitVersion website

To determine the version of a repository, use the following command line:

This will result in this version for the 8th commit in the develop branch:

Integration in your favorite CI software

The CI software I prefer to use is Continua CI. The reason I like it is that it is very easy to understand but in the same time it is really, really powerful. Another great advantage is their support: they implement features / fix bugs within a week which is nice compared to other companies where you have to wait until the next major release to hopefully find your feature request implemented.

To integrate GitVersion into Continua CI, use the steps below.

1) Add GitVersion.exe to your repository

Add GitVersion.exe to your repository (or put it on the build server, whatever you prefer). I like to put it in the tools directory of my repository:

image

2) Define version variables in the Continua CI configuration

Note that you can use all versions that GitVersion exposes in the example above. The naming convention must be GitVersion_[VariableName]. Below is an example of versions that I find useful during builds:

image

3) Call GitVersion.exe at the start of the build

In Continua CI, add the Execute Program action to a stage and use the settings below:

image

Don’t forget the set the arguments as well:

4) Update the AssemblyInfo

I prefer to put the version of a solution in a centralized SolutionAssemblyInfo which is shared over all the projects that are part of a solution. After calling GitVersion.exe, you can update the version in the AssemblyInfo of your project:

image

Running code in a XAML designer at design-time

Recently I needed to show dynamic values in the XAML designer (WPF, Silverlight, Windows Phone, WinRT) to show real-time translations through a LanguageService that were wrapped in a markup extension. That sounds complex, but below is an image that shows what I wanted to achieve:

image

As the image shows, I needed quite some dynamic content to be loaded during design-time. When running the application, I can easily customize the IoC container in App.xaml.cs, but that doesn’t work at design-time.

After some searching on the internet, I found this article by Josh Smith.Unfortunately the Visual Studio 2013 designer (and maybe other versions as well) doesn’t load the assembly attributes thus it was not working for me. Though the solution represented below is part of Catel, it can be used without it as well.

Introducing the DesignTimeCode attribute

To allow users to run code in the designer (Visual Studio or Blend), we first need to introduce the DesignTimeCodeAttribute. This is an assembly-wide attribute which will specify the class to create at design time (just like Josh Smith recommended). This means that it is possible to create multiple attributes. Below is the class definition:

Below is an example of the usage of the attribute:

Introducing the DesignTimeInitializer

The DesignTimeCodeAttribute contains the types that are constructed during design-time. The problem is that every type specified in the DesignTimeCodeAttribute must check whether it is running in design mode, otherwise it might also fire at runtime. The DesignTimeInitializer base class will aid developers in process and check for this in the constructor.

Below is an example of the usage of the DesignTimeInitializer:

Making it actually run code at design-time

So far, we haven’t done much different from the solution Josh Smith provided. However, it was still not working at this level for me. The reason is that the Visual Studio 2013 designer does not read the assembly attributes and thus will not create our design time initializers.

The solution here is a two-step process, and requires the use of ModuleInit.Fody. If you are not familiar with ModuleInit.Fody, you can read about it here. Basically it allows you to run code as soon as an assembly is loaded (a.k.a. assembly-wide constructors). Installing it is really simple via NuGet.

The next step we need to take is to add initialization code as soon as our assembly is loaded. The code below reads the attribute from all loaded assemblies and initializes the code:

Checking out the final result

Below is a short gif showing that the designer now runs code at design-time. It does this by registering a custom source in the LanguageService. Then every time the project is rebuilt, the LanguageService is updated and will reflect the changes at design time.

Running code at design time

Fast(er) restore of NuGet packages

As you probably know from my previous blog posts, I never liked the NuGet package restore and always used Pepita instead. However, the NuGet team decided it was a good idea to hook into the Build Solution event of Visual Studio and restore packages so no other (pre-build) tasks can interfere any longer to do a better job.

Now we are back at square 1, and I got tired of waiting minutes to restore a few packages using the NuGet integration in Visual Studio:

image

It is better to restore your packages outside Visual Studio. Simply use the following command:

NuGet.exe restore [SolutionFile] –PackagesDirectory [PackagesDirectory]

In Catel, I use the following

..\tools\nuget\nuget.exe restore ..\src\Catel.VS2013.sln -PackagesDirectory .\