Apr
30
2012

Using Github hubot and Appharbor service hook to get deployment status in Campfire/HipChat rooms

STA_0178Appharbor provides a service hook which let’s you get informed when a build is finished sending both succeeded and failed builds.

We wanted to use this to get informed in our Campfire / HipChat room so that our distributed team can be informed about builds status without having to go to AppHarbor web site.

The idea was to extend our GitHub Hubot hosted on Heroku.

From AppHarbor support here is the information we need about “Developing a service hook

We will send a POST request content-type "application/json" and the following body:

{
  "application": {
    "name": "Foo"
  }, 
  "build": {
    "commit": {
      "id": "77d991fe61187d205f329ddf9387d118a09fadcd", 
      "message": "Implement foo"
    }, 
    "status": "succeeded"
  }
}

We need to build a Hubot script; which are CoffeeScript, to have an HTTP endpoint listening to this Post payload. Then it needs to read the payload and format it to be able to send it in readable message to the Campfire / HipChat room.

With the release 2.1.3 of Hubot there is a new easy way to have an HTTP Listener:

HTTP Listener

Hubot has a HTTP listener which listens on the port specified by the PORT environment variable.

You can specify routes to listen on in your scripts by using the router property on robot.

module.exports = (robot) ->
  robot.router.get "/hubot/version", (req, res) ->
    res.end robot.version

There are functions for GET, POST, PUT and DELETE, which all take a route and callback function that accepts a request and a response.

We can use this easily in our Hubot script which is called appharbor-listener.coffee.

module.exports = (robot) ->
  robot.router.post "/hubot/appharbor", (req, res) ->
    robot.logger.info "Message received for appharbor"

Now that we are able to listen to POST payload on the url …/hubot/appharbor we need to send a message to the Campfire / HipChat room, which is a bit different from the other scripts. The http listener scripts doesn’t get msg which is normally used to send the response from our bot to the room. Here we have to do it differently and use robot.send which I found on the post ‘Hubot HTTP Daemon Support

user = robot.userForId 'broadcast'
user.room = 'Your Room Id'
user.type = 'groupchat'

message = "AppHarbor build '#{buildStatus}' for application: '#{builtApplicationName}'"

robot.logger.info "User: '#{user.room}','#{user.type}'"
robot.logger.info "Message: '#{message}'"

robot.send user, "#{message}"

Currently this is working only with the Campfire adapter, the HipChat one is crashing as described here.

Here is the whole script

And finally here is the result of posting a sample payload using fiddler

github hubot appharbor integration

Apr
28
2012

Running Github Hubot on a Windows machine

IMG_0063I finally managed to get Github Hubot running on my Windows 7 64 bits machine. Thanks to  Sean Copenhaver & Thomas Kahlow which pointed me to the correct direction on the ‘Run hubot on windows’ discussion.

So here is how I did it.

First of all download and install nodejs 0.6.15. This will also install npm 1.1.16 which is the node package manager.

Then start Powershell and create a new folder e.g. HubotWorking

mkdir HubotWorking

cd .\HubotWorking

npm install hubot

You should see the following output

npminstallhubot

Go on with the following

cd .\node_modules\hubot

node .\node_modules\coffee-script\bin\coffee .\bin\hubot

And the magic!

hubotonwindows

You might want also to run it through JetBrains WebStorm 4.0, so here is the configuration you will need

webstorm hubot

And here is the result in the WebStorm nodejs runner

runhubotfromwebstorm
Apr
13
2012

Sending your Git branch changes as an email attachment

IMG_1586The other day I wanted to send per email some code to a friend which doesn’t use Git. He is using Svn and I use Git Svn in front of this Svn repository. Why I do that? Don’t get me started…

So he couldn’t pull from my repo and we were kind of stuck. Really?!? For sure not, here was the goal I set as I am sure this will happen some other time: having the computer work for me. What a strange idea you would say! Yeah, the computer working for you. At the end aren’t we here to make the cool things and let the computer do the boring things?

Ok so I came up with a quick hack. I wanted to have a way to send all the new, or modified, files of my current Git branch per email as a zip attachment. Guess what it was quite easy even for a PowerShell beginner like me.

First of all I needed first to be able to determine on which Git branch I was curently. I googled and find the following

function Get-GitBranch {
    $symbolicref = git symbolic-ref HEAD
    $branch = $symbolicref.substring($symbolicref.LastIndexOf("/") +1)
    return $branch
}

Then I wanted to be able to Zip all the files, but to achieve I had to determine which were the files to Zip. this is done using the following

git diff --name-only HEAD..master

And making a Zip out of the list of files is done like this

function Zip-GitBranch([string]$zipFilename) {

    $branch = Get-GitBranch
   
    if (!$zipFilename) {
        $zipFilename = [string]::Format(".\{0}.zip", $branch)
    }

    $files = git diff --name-only HEAD..master

    foreach($file in $files) {
         & 'C:\Program Files\7-Zip\7z.exe' a $zipFilename $file
    }
   
    return $zipFilename
}

Finally I wanted to be able to send the zip as an attachment of an email using Outlook

function MailZip-GitBanch($Recipient) {
   
    if (!$Recipient) {
        Write-Host "You need to pass the email of the recipient as parameter"
        return
    }
   
    $branch = Get-GitBranch
    $zipFilename = [string]::Format(".\{0}.zip", $branch)
    $attachement = [IO.Path]::GetFullPath( $zipFilename )

    Zip-GitBranch($attachement)
       
    $ol = New-Object -comObject Outlook.Application
    $Mail = $ol.CreateItem(0)
    $Mail.Recipients.Add($Recipient)
    $Mail.Subject = "Changes for the branch: " + $branch
    $Mail.Body = "Check out the email attachement to see the changes made to the branch: " + $branch
    $Mail.Attachments.Add($attachement)
    $Mail.Send()
}

Now I can type the following command to send my changes to my friend

MailZip-GitBranch myemail@email.com

You can find the whole script on the following gist.

Mar
25
2012

Writing a first Node.js application on Windows

Plage de la Grande Anse du Diamant

I started some weeks ago to play with Github Hubot and hosted one version on Heroku to start learning about all those new technologies.

The next step was to go a bit onto Node.js and write a first small application.

First you need to download Node.js and install it on your machine. I downloaded the Windows version 0.6.14.

When Node.js is installed on your machine you should find it on the folder C:\Program Files (x86)\nodejs for 64 bits machines and on C:\Program Files\nodejs for the 32 bits.

Then start a PowerShell window and type “node -v” you should see v0.6.14.

Now start you preferred text editor and create a new file server.js and copy paste the code from the home page of Node.js

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

Go back to your PowerShell window and type “node server.js” which should display “Server running at http://127.0.0.1:1337/

Now run your preferred browser and enter the url http://127.0.0.1:1337/

nodejs

I went a little further following the Node Beginner site and created a first module.
To do so I used JetBrains WebStorm 3 which you can easily configure to run and debug your Node.js application.

You need to configure it this way

nodejs2

Then you can add a Run/Debug configuration for Node.Js

nodejs3

Finally you can run your Node.js application in Debug mode

nodejs4

and for sure hit the breakpoints and watch the values of your variables

nodejs5

Which will help during my learning of this new technology!

Mar
22
2012

Installation and first experience with the Ergotron WorkFit-D

New Ergotron Workfit-D desk

In late 2010 I reworked my home office and installed a new Ergotron LX Dual Side-by-Side Arm, to gain some place on my desk.

Some months ago, after different discussions with my colleague Bojan I decided to go on and try to find an height adjustable desk, which he just installed in his home office. I didn’t quite like his one because it was with an electrical motor and I prefered to find a mechanical one. It started to be important for me to stand during the day/night that I spend in front of a computer. I have back pains since years, and it is really time that I do something about it. You might read more about the topic on “JustStand.org” or on “Sitting is killing you”.

I also wanted to have something which fits nicely with my LX Dual Side-by-Side Arm and finally I found what I was looking for; the WorkFit-D, Sit-Stand Desk from Ergotron.

Here is the impressive packaging I received

Ergotron WorkFit-D

And what was inside the box

Ergotron WorkFit-DErgotron WorkFit-DErgotron WorkFit-DErgotron WorkFit-DErgotron WorkFit-D mounting

The mounting documentation was really easy to follow and after almost an hour I had my new Ergotron WorkFit-D assembled and my LX Dual Side-by-Side Arm with it’s two 24 inches monitor mounted on it. As for the mounting of the arm there was really nothing that I disliked during the mounting, easy and clear.

Ergotron WorkFit-D mountingErgotron WorkFit-D mountingErgotron WorkFit-D mounting

So over the past month, I had the chance to use this new working environment while working from home.

First of all I tend to use more the LX Dual Side-by-Side Arm to adjust my monitors when I change from standing up to sitting or the opposite. Before on the fixed desk with the chair, the arm saved quite some place on the desk, so I didn’t had really to move them when I needed to do something else then being on the PC. This is really easy and fast with the arm.

Going from the sitting position to the standing is really fast, smooth and easy. I just have to deal better with the cables behind which sometime cause problem, but I think I have a solution which I will try by end of this week. I was quite surprise that it was that easy, because the two monitors aren’t that light weight.

I used at the beginning the Neo-Flex® Underdesk Keyboard Arm to have my wireless keyboard and mouse. But I stopped at the moment because the whole set was shaking too much when I was typing. I still need to fine tune the foots of the WorkFit-D, which I think will improve the stability and reduce the shaking.

What was a surprise to me was the speed at which I went from a whole day sitting to almost a whole day standing. It took me less than a month. For example today I worked the whole day standing. I still have some pain in my legs after a full day but I think it improves slowly.

During Christmas I worked with my brother Mathieu on our new personal project and we found that it was a fantastic setup for pair programming.

So, I like very much my new Ergotron WorkFit-D and the LX Dual Side-by-Side every day and night I am working home.

Here are some more pictures

I still have some work to do to have my home office the way I want it, but this is work in progress.

Disclaimer: I was provided these materials free, so my opinion might be biased.

Feb
7
2012

Starting TeamCity builds from HipChat using Github Hubot

La table du diable depuis la Savane des Pétrifications

After writing about “Running your TeamCity builds from PowerShell for any Git branch” I’d like to talk about another integration which is using Github Hubot so that the build could be started directly form a chat room.

So using the same idea, which is to extend our development environment, we implemented a way to start TeamCity builds directly from our HipChat room. You could do the same from Campfire for sure.

The main idea of this is to have our daily tools right at our disposal where we spend a good part of our days, chat rooms.

First we had to install Github Hubot and we have chosen to use Heroku which offer free hosting for one of their web dyno. They even offer what they call Hubot Factory which is a way to allow people to easily and quickly deploy new instances of Hubot to Heroku. In fact we went with a manual installation described on this page “Hubot for HipChat on Heroku”.

The idea is still the same we need to run TeamCity builds by “Accessing the Server by HTTP”.

This time we want to have Hubot calling the TeamCity server so we need to add a new CoffeeScript to the scripts of Hubot which will launch the HTTP request needed.

Our script is heavily inspired from the TeamCity.coffee script, and here is a first version:

# Starts a build on TeamCity.
#
# You need to set the following variables:
# HUBOT_TEAMCITY_USERNAME = 
# HUBOT_TEAMCITY_PASSWORD = 
# HUBOT_TEAMCITY_HOSTNAME = 
#
# start build buildId -- Starts TeamCiyt build using buildId
module.exports = (robot) ->
  robot.respond /start build (.*)/i, (msg) ->
    username = process.env.HUBOT_TEAMCITY_USERNAME
    password = process.env.HUBOT_TEAMCITY_PASSWORD
    hostname = process.env.HUBOT_TEAMCITY_HOSTNAME
    buildName = msg.match[1]

    msg.http("http://#{hostname}/httpAuth/action.html?add2Queue=#{buildName}")
      .headers(Authorization: "Basic #{new Buffer("#{username}:#{password}").toString("base64")}",
               Accept: "application/json")
      .get() (err, res, body) ->
        if err
          msg.send "Team city says: #{err}"
          return

By the way I started to learn CoffeeScript so this is more hacking then something really productive.

And here is the result in our HipChat room asking hubot to start a build with the command:

hubot start build bt21

TeamCity, GitHub Hubot and HipChat

I will talk in another post about the last part which shows the status of the build in the chat room.

Feb
7
2012

Running your TeamCity builds from PowerShell for any Git branch

Plage le long de la Savane des Pétrifications

I love TeamCity and use it since a while to automate my build/release processes. As human we should never do the work a machine can do, we have certainly better and more interesting things to do.

The habit I saw in the different projects I worked for is to create new TeamCity builds for the branches you work on. It take quite some work to do, even with templates…

So I came with another way of doing it. It is leverage Git, PowerShell and the possibility to run TeamCity builds by “Accessing Server by HTTP”. Basically you just need to make a HTTP request to an Url like this:

http://testuser:testpassword@teamcity.jetbrains.com/httpAuth/action.html?add2Queue=bt10&system.name=<property name1>&system.value=<value1>&system.name=<property name2>&system.value=<value2>&env.name=<environment variable name1>&env.value=<environment variable value1>&env.name=<environment variable name2>&env.value=<environment variable value2>

We will also use the possibility to pass custom parameters (system properties and environment variables) through the HTTP request.

The parameter we want to pass is the Ref name of the Git VCS Root, so we start by setting it using a configuration parameter called BuildRefName, as this:

 

Git, PowerShell, TeamCity

Then we need to add a configuration parameters for our TeamCity project with the name BuildRefName which we currently set to master, so that if the parameter is not defined it will default to this value:

Git, PowerShell, TeamCity 2

Now that we have configured this you can already start a build from your browser by calling the URL!

http://testuser:testpassword@teamcity.jetbrains.com/httpAuth/action.html?add2Queue=bt10

Be sure to replace bt10 with your build id.

Nice ,but we want to get a step further and be able to start the build from PowerShell, which is quite easy!

To achieve this goal you add those two functions to your PowerShell profile:

function Get-Web($url, 
    [switch]$self,
    $credential, 
    $toFile,
    [switch]$bytes)
{
    #.Synopsis
    #    Downloads a file from the web
    #.Description
    #    Uses System.Net.Webclient (not the browser) to download data
    #    from the web.
    #.Parameter self
    #    Uses the default credentials when downloading that page (for downloading intranet pages)
    #.Parameter credential
    #    The credentials to use to download the web data
    #.Parameter url
    #    The page to download (e.g. www.msn.com)    
    #.Parameter toFile
    #    The file to save the web data to
    #.Parameter bytes
    #    Download the data as bytes   
    #.Example
    #    # Downloads www.live.com and outputs it as a string
    #    Get-Web http://www.live.com/
    #.Example
    #    # Downloads www.live.com and saves it to a file
    #    Get-Web http://wwww.msn.com/ -toFile www.msn.com.html
    $webclient = New-Object Net.Webclient
    if ($credential) {
        $webClient.Credentials = $credential
    }
    if ($self) {
        $webClient.UseDefaultCredentials = $true
    }
    if ($toFile) {
        if (-not "$toFile".Contains(":")) {
            $toFile = Join-Path $pwd $toFile
        }
        $webClient.DownloadFile($url, $toFile)
    } else {
        if ($bytes) {
            $webClient.DownloadData($url)
        } else {
            $webClient.DownloadString($url)
        }
    }
}

function tcBuild([string]$branch) {

	$url = "http://YourServerUrl/httpAuth/action.html?add2Queue=YourBuildId"

	if ($branch) {
		$url = $url + "&name=BuildRefName&value=" + $branch
    }
	
	$credentials = New-Object System.Net.NetworkCredential("Username", "Password")

	Get-Web $url -credential $credentials
}

Please adapt the tcBuild script by replacing the YourServerUrl, YourBuildId, Username, Password by your personal values.

The first function Get-Web is from this blog post: “Microcode: PowerShell Scripting Tricks: Scripting The Web (Part 1) (Get-Web)”.

The second, tcBuild, is quite easy and is the one you will use to start a build on the TeamCity server.

My workflow now is the following one:

  1. I commit on my local Git repository then
  2. when I want to run a build I push to the centralized Git origin repository in my branch then
  3. I start my build on the Git Branch from PowerShell by typing :

> tcBuild Jobping-10-NewFeature

where Jobping-10-NewFeature is the name of my Git branch.

This is quite cool and give me also the possibility to run kind of personal builds!

Jan
20
2012
DVCS // TDD // BDD

Improved my development workflow

Fleur d'hibiscus à la villa cannelleFor some time now I slightly modified my development workflow and I have seen a great improvement in my developers life:

  • it started by using Git Svn in front of our central Svn
  • then I introduced NCrunch in my TDD/BDD

NCrunch is an automated parallel continuous testing tool for Visual Studio .NET. It intelligently takes responsibility for running automated tests so that you don't have to, and it gives you a huge amount of useful information about your tests (such as code coverage) inline in your IDE while you work.

 I am a fan of Test Driven Development and Behavior Driven Development, I think there are great tools in a developer toolset in quite some circumstances.

I am also a great fan of JetBrains ReSharper which I use every development day and I couldn’t work as efficiently without it. But…

So what’s the point? NCrunch propose only an automated parallel continuous run of your test. Big deal, it saves you only some keystrokes! Yeah I believed that too, but the difference was quite impacting.

I don’t need to think anymore about running the tests I just run through my TDD thinking only of my tests and code, no distraction just seeing the result of my changes directly aligned with my code.

What I really liked about NCrunch is:

  • the possibility to run only a part of the tests
  • the feedback given in the code window
  • let me focus on the code
  • the risk/progress bar
  • the impact it had on my productivity

I really encourage you to try NCrunch which is free during the beta period.

Supported testing frameworks are:

  • NUnit
  • MS Test
  • Xunit
  • MbUnit
  • MSpec

The Xunit and MbUnit test runners are provided with thanks to The Gallio Project.

Supported languages and .NET versions are:

  • C#
  • VB.NET
  • F#
  • .NET Framework v2.0 and above
  • Visual Studio 2008
  • Visual Studio 2010
  • Visual Studio 11 Developer Preview
Jan
5
2012

Extending existing .NET API to support asynchronous operations

Palmier sur la plage de la grande anse du diamant

The other day I needed a way in a project I am working on to turn a .NET API, RestSharp to name it, so that I could use it in an asynchronous way.

The goal was to have the API returning a Task<TResult> so that I could use it if I want with the Async CTP. I also wanted to have something running both on .NET 4.0 and on Windows Phone 7.5. 

To achieve this goal I used

TaskCompletionSource<TResult> Class

.NET Framework 4

and defined two helper extension methods on the RestClient class of RestSharp as this:

#region using

using System;
using System.Threading;
using System.Threading.Tasks;
using RestSharp;

#endregion

namespace Sharper
{
    public static class RestClientExtensions
    {
        public static Task<TResult> ExecuteTask<TResult>(this RestClient client,
                                                         RestRequest request) where TResult : new()
        {
            var tcs = new TaskCompletionSource<TResult>();

            WaitCallback
                asyncWork = _ =>
                                {
                                    try
                                    {
                                        client.ExecuteAsync<TResult>(request,
                                                                     response => tcs.SetResult(response.Data));
                                    }
                                    catch (Exception exc)
                                    {
                                        tcs.SetException(exc);
                                    }
                                };

            return ExecuteTask(asyncWork, tcs);
        }

        public static Task<TResult> ExecuteTask<T, TResult>(this RestClient client,
                                                            RestRequest request,
                                                            Func<T, TResult> adapter) where T : new()
        {
            var tcs = new TaskCompletionSource<TResult>();

            WaitCallback
                asyncWork = _ =>
                                {
                                    try
                                    {
                                        client.ExecuteAsync<T>(request,
                                                               response =>
                                                               tcs.SetResult(adapter.Invoke(response.Data)));
                                    }
                                    catch (Exception exc)
                                    {
                                        tcs.SetException(exc);
                                    }
                                };

            return ExecuteTask(asyncWork, tcs);
        }

        private static Task<TResult> ExecuteTask<TResult>(WaitCallback asyncWork,
                                                          TaskCompletionSource<TResult> tcs)
        {
            ThreadPool.QueueUserWorkItem(asyncWork);

            return tcs.Task;
        }
    }
}

Now I can write asynchronous code like this:

public Task<List<Project>> GetAllProjects()
{
    var request = new RestRequest { Resource = "/httpAuth/app/rest/projects", RootElement = "project" };
    request.AddHeader("Accept", "application/json");

    return _restClient.ExecuteTask<List<Project>>(request);
}

So TaskCompletionSource<T> is a nice class to know about!

You might also watch this short video by Phil Pennington to get a better idea about it:

Dec
15
2011

Shortening namespace declarations in XAML files

Vue sur la tête de la femme couchée de la terrasse de la villa cannelleThis afternoon I was working on Innoveo Skye Editor which is a WPF application written in C#.

The application is using Telerik RadControls for WPF.

I was facing the issue of having more and more namespace declarations like the following for RadInput and Rad:

 

<Window x:Class="skyeEditor.View.Dialogs.ProductSettingsDialog"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:RadInput="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Input"
        xmlns:Rad="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls"

Searching for a solution I thought of ASP.NET in which you can declare in the web.config things like that:

<pages pageBaseType="System.Web.Mvc.WebViewPage">
  <namespaces>
    <add namespace="MyNamespace" />

My goal was to have one namespace declaration for example telerik and be able to use it in all my XAML files without having to declare too much.

So I started an online discussion with Laurent Bugnion who has always shown me the good direction, which in this case is the

XmlnsDefinitionAttribute Class

Followed by an article from Sandino Di Mattia about “A Guide to Cleaner XAML with Custom Namespaces and Prefixes (WPF/Silverlight)”.

Using the idea I was able to add the following to the AssemblyInfo.cs of my own project:

[assembly: XmlnsDefinition("telerik",
                           "Telerik.Windows.Controls",
                           AssemblyName = "Telerik.Windows.Controls")]

[assembly: XmlnsDefinition("telerik",
                           "Telerik.Windows.Controls",
                           AssemblyName = "Telerik.Windows.Controls.Input")]

[assembly: XmlnsDefinition("telerik",
                           "Telerik.Windows.Controls",
                           AssemblyName = "Telerik.Windows.Controls.Navigation")]

[assembly: XmlnsDefinition("telerik",
                           "Telerik.Windows.Controls",
                           AssemblyName = "Telerik.Windows.Controls.RibbonView")]

And then my XAML file declaration looks like that:

<Window x:Class="skyeEditor.View.Dialogs.ProductSettingsDialog"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"

And I can use everywhere for all Telerik RadControls for WPF with the prefix telerik

<telerik:RadComboBox ItemsSource="{Binding ProductNodeLabels}"
                        SelectedItem="{Binding SelectedProductNodeLabel}"
                        Margin="0,0,0,5" />

A little step but a nice improvement!

About Laurent

Laurent Kempé

Laurent Kempé is the editor, founder, and primary contributor of Tech Head Brothers, a French portal about Microsoft .NET technologies.

He is currently employed by Innoveo Solutions since 10/2007 as a Senior Solution Architect and certified Scrum Master.

Founder, owner and Managing Partner of Jobping, which provides a unique and efficient platform for connecting Microsoft skilled job seekers with employers using Microsoft technologies.

Laurent is awarded by Microsoft since Avril 2002: Most Valuable Professional (MVP).

MVP
Certified ScrumMaster
JetBrains Academy Member

My status

Twitter

Flickr

www.flickr.com
This is a Flickr badge showing public photos and videos from Laurent Kempé. Make your own badge here.

Month List

Page List