Introducing GitHubLink: let everyone step through your GitHub code!

Last week I have been working on a new project called GitHubLink. It let’s users step through your code hosted on GitHub! This makes symbol servers obsolete which saves you both time with uploading source files with symbols and the user no longer has to specify custom symbol servers (such as symbolsource.org).

GitHubLink_example

The idea is based on the SourceLink project. However it requires FAKE and not everyone likes to write code in F#. GitHubLink is available as console application and can be references as assembly as well to be used in other .NET assemblies.

The advantage of GitHubLink is that it is fully customized for GitHub. It also works with GitHub urls so it does not require a local git repository to work. This makes it perfectly usable in continuous integration servers such as Continua CI.

Updating all the pdb files is very fast. A solution with over 85 projects will be handled in less than 30 seconds.

When using GitHubLink, the user no longer has to specify symbol servers. He/she only has to enable the support for source servers in Visual Studio as shown in the image below:

visualstudio_enablesourceserversupport

How to use it?

Using GitHubLink is very simple:

  1. Build the software (in release mode with pdb files enabled)
  2. Run the console application with the right command line parameters

Below are a few examples:

Running for the default branch

This will use the default branch (which is in most cases master). You can find out the default branch by checking what branch is loaded by default on the GitHub page.

Running for a specific branch

This will use the develop branch.

Running for a specific branch and configuration

This will use the develop branch and the debug configuration.

How to get it?

You can grab the first official release at GitHub:

https://github.com/GeertvanHorrik/GitHubLink/releases

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