Sprydon

Richard Harding's spot on the web

Custom activity to tag sources in git from TFS

The problem

I want to be able to trace an assembly back to the source that was used to build it, the way I usually accomplish this is to have the continuous integration server set the assembly version (including file version) based on some auto incrementing build number and incorporate that same build number in a source control label. Then given an assembly I can use its version to pull the source that built it.

However while there is a built in activity to label workspace files for the TFS Source control repository it doesn’t seem to support the Git repository option which seems like a strange omission.

The TFS Community extensions don’t have anything suitable either

The Solution – Custom Activity & Libgit2sharp

I took a look at the source of the built in activities that interact with Git – especially the InitializeEnvironment activity that clones the repository. They all use the libgit2sharp library to interact with the TFS git repository, so using the examples on project wiki I put together a quick test to check I could apply and push a tag

   1:  using (var repo = new Repository(@"c:\repos\MyTestRepo"))
   2:              {
   3:                  var tagName = "MyTagName";
   4:                  var tag = repo.ApplyTag(tagName);
   5:                  var remote = repo.Network.Remotes["origin"];
   6:                  var pushOptions = new PushOptions { Credentials = new DefaultCredentials() };
   7:                  repo.Network.Push(remote, string.Format("refs/tags/{0}:refs/tags/{0}", tagName, pushOptions));
   8:              }

 

That worked, so the next step was to build a custom activity that I could add to a build template - Martin Hinshelwood has a great blog post that helped me to get started with the custom activity and again referring to the source of the built in activities helped with extracting some of the arguments like source directory paths and build numbers.

Once you have your activity you need to get it deployed to the build agents, the process is to add the assembly and any dependencies (in this case the libgit2sharp.dll and the native binaries it uses) to a Git repository and configure the Custom Assemblies property of the build agents – this process is well documented on the Community TFS Extensions codeplex site.

Logging

This of course did not work first time….so I needed to add some logging I copied the example shown in this forum post 

context.Track(new BuildInformationRecord<BuildMessage>
                              {
                                  Value = new BuildMessage
                                              {
                                                  Importance = BuildMessageImportance.High,
                                                  Message = message
                                              }
                              });

This threw up an odd situation  - its possible for the call to Network.Push method to fail and not throw an exception – in my case it was because the service account that the TFS Build agent was running under did not have the necessary Write permission to create the tag – the PushOption object has an event handler to catch errors  - use this to see these kinds of issues and log them to the diagnostics log for the build.

I’ve put together a sample activity and the source is on my GitHub

Developer Developer Developer South West 5

Some notes from this weekends DDDSW and to mostly fill in the gaps from Nathan Gloyn’s write up.

Sessions I attended:

Session 1: Steve Sanderson's  - Architecting large Single Page Applications with Knockout.js

Lots of interesting background on the use of Typescript on the new Azure management portal – main takeaways

Beware preloading large amounts of data and check for memory leaks

New components feature in Knockout - https://github.com/knockout/knockout/issues/1273

Use of Yeoman Steve has a generator for a Knockout based web app - https://github.com/SteveSanderson/generator-ko this was worth a look at as it uses a number of JavaScript libraries I’d not come across including JsSignal for messaging and crossroads for routing

Good demo of the Karma test runner – like NCrunch for JavaScript tests

Session 2: Marc Gravell — Redis cluster— everything you need to know

Nathan was in the same session – check out his write up

Except to note that there are Nuget packages for including a Redis server in an ASP,Net app or you can use chocolaty to install

Session 3: Phil Trelford — F# eye for the C# guy

A very entertaining presentation by Phil with some great pointers on how to get started with F#, Phil’s approach is to start with writing tests in F# and then move on to writing the domain layer. He gave a compelling demonstration of how terse the F# code is compared to its C# equivalent.

Worth taking a look at his version of SpecFlow – TickSpec

Also for getting started he suggests taking a look at the F# Koans on GitHub

He also has a book coming out soon - F# Deep Dives

Session 4: Gary Short — Hadoop and Big Data for Microsoft Developers

Big Data is all the rage right? – Gary went on to explain what Data Science is really about and that size is not all that counts.

A couple of good demos on how C# can be used to write Map Reduce implementations and make the hadoop command line easier to write!

Plus a demo on using PowerView in Excel to connect to a hadoop file system to query results

There are Microsoft authored packages on nuget

MS Supported Hadoop on windows server

Session 5: Mauro Servienti —​A gentle introduction to AngularJS

This was a good contrast to Steve Sanderson's talk in the first session with further clarification of when Angular is a good fit, impact on page size etc

Slides from the presentation

Mauro’s blog

Closing

All in all a great day and another year when I didn't win anything in the raffle Sad smile

Working with AChartEngine and Xamarain Android

I’m starting a new mobile project on android using Xamarin and needed a charting engine to display some data, there are a few existing component choices in the Xamarin component store one free one – bar chart but it (as the name suggests) only does bar charts and as far as I can tell can’t display multiple series at the same time. The other choices look great but cost real money and I needed to spike something without investing too much cash. A quick search for any open source options revealed a few options but none with any xamarin bindings as part of the existing code base leaving a final option of building a binding library myself.

According to the docs creating a binding library should be a fairly simple process but they do hint at having to fix up issues by hand which is where I ended up with AChartEngine – I downloaded the 1.1.0 jar file, created a new bindling library project, added the jar and build

At first it looked like I almost got away with it as I only had a single error

C:\Users\richard\Documents\GitHub\AChartEngine.Xamarin\AChartEngine.Xamarin\obj\Debug\generated\src\Org.Achartengine.Tools.Pan.cs(29,29): Error CS0542: 'Pan': member names cannot be the same as their enclosing type (CS0542) (AChartEngine.Xamarin)

So according to the docs I needed to do a bit of renaming using the metadata.xml file in the transforms folder so I added the following to the metadata mapping file to rename the event handler

<attr path="/api/package[@name='org.achartengine.tools']/class[@name='Pan']/method[@name='addPanListener']" name="eventName">PanEvent</attr>

and it turns out this is going to be an iterative process as it just allowed the compile to move into the next errors

obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(206,9,206,46): error CS0019: Operator '!=' cannot be applied to operands of type 'Org.Achartengine.Renderer.XYSeriesRenderer.FillOutsideLine.Type' and 'System.Type'

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(208,8,208,160): error CS1502: The best overloaded method match for 'Android.Runtime.JNIEnv.StartCreateInstance(System.IntPtr, System.IntPtr, params Android.Runtime.JValue[])' has some invalid arguments

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(208,60,208,70): error CS1503: Argument 1: cannot convert from 'Org.Achartengine.Renderer.XYSeriesRenderer.FillOutsideLine.Type' to 'System.IntPtr'

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(208,72,208,142): error CS1503: Argument 2: cannot convert from 'string' to 'System.IntPtr'

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(208,144,208,159): error CS1503: Argument 3: cannot convert from 'Android.Runtime.JValue' to 'Android.Runtime.JValue[]'

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(263,10,263,37): error CS0019: Operator '==' cannot be applied to operands of type 'Org.Achartengine.Renderer.XYSeriesRenderer.FillOutsideLine.Type' and 'System.Type'

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(274,10,274,37): error CS0019: Operator '==' cannot be applied to operands of type 'Org.Achartengine.Renderer.XYSeriesRenderer.FillOutsideLine.Type' and 'System.Type'

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(305,9,305,36): error CS0019: Operator '==' cannot be applied to operands of type 'Org.Achartengine.Renderer.XYSeriesRenderer.FillOutsideLine.Type' and 'System.Type'

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(335,9,335,36): error CS0019: Operator '==' cannot be applied to operands of type 'Org.Achartengine.Renderer.XYSeriesRenderer.FillOutsideLine.Type' and 'System.Type'

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(369,9,369,36): error CS0019: Operator '==' cannot be applied to operands of type 'Org.Achartengine.Renderer.XYSeriesRenderer.FillOutsideLine.Type' and 'System.Type'

 

So after a bit of googling looks like all I need to do is remove the offending types from the binding library (at this stage I’m not sure whether I’ll need to instantiate these types from the c# side but I hope not) so I added a few more lines to the metadata

<remove-node path="/api/package[@name='org.achartengine.renderer']/class[@name='XYSeriesRenderer.FillOutsideLine']"/>

And this time it compiles with no errors – I ran a quick test project to prove I could make use of the library and it worked, its not clear yet whether I’m going to need that class exposed in the binding or if there was a better way to resolve the binding errors.

Find the source on github