Cruise Control .Net Self Updating Config

Posted January 19, 2013

I’m a massive advocate of continuous integration (CI). I set up a build server for my team a few years ago and it really changed the way we worked for the better. Cruise Control .Net was the first CI software I used and despite flirting with the likes of TeamCity, FAKE and even TFS I always end up returning to Cruise Control because at the moment it does just enough for what I need and is easy to extend with plugins or Powershell when my requirements are a bit more complex.

When you first set up a build server the config is normally pretty basic but as you and your colleagues get used to it you start to realise quite what it can do for you. My current team have our CI server: pulling source code, grabbing Nuget packages, building, testing, minifying, zipping, deploying, running SQL updates, flashing our office traffic lights and updating our HipChat room every time we commit code. As you can imagine the config for this is now fairly big. A few times in the last year I’ve needed to roll back config changes and struggled so I eventually ended up shoving the config in source control. This is great but pushing the latest version into source control and then copying it onto the server seemed weird so I started to investigate whether Cruise Control could update itself.

Fortunately on Thoughtwork’s CCNet pages there is an article on just that. I quickly modified our config and ran it to try it. It works great but unfortunately if you push bad config to your source control it will trash your CCNet setup and worse, if CCNet is running you might not even find out about this till next time it restarts.

I wanted a more robust mechanism for updating the config, one that validated my config instead of blindly overwriting the master one. Fortunately CCNet ships with CCValidator.exe which is built for just this purpose.

I found that by using an exec task with a specific successExitCodes section I could create a build that failed if the config was invalid. The important task is:

<exec>
	<executable>$(CCNetValidatorPath)</executable>
	<description>Validate Config File</description>
	<baseDirectory>C:\</baseDirectory>
	<buildArgs>c:\CI\CruiseControl\ccnet.config --nogui --logfile=c:\CI\Logs\ConfigValidation.log</buildArgs>
	<buildTimeoutSeconds>30</buildTimeoutSeconds>
	<successExitCodes>0</successExitCodes>
</exec>

Note that I specify a log file. This is useful for tracking what the problem in the config actually is. You can merge it into your build output using the File publisher:

<publishers>
	<merge>
		<files>
		  <file>c:\CI\Logs\ConfigValidation.log</file>
		</files>
	</merge>
	<xmllogger/>
</publishers>

Now I know my config is under source control and I don’t even have to log onto our build server to update it.

Full config file can be downloaded from: https://bitbucket.org/colethecoder/cruise-control-auto-update-demo

continuous-integration

Simplifying Documentation In MVC With Markdown

Posted September 17, 2012

Recently I’ve been building an API for work with the new ASP.Net Web API features and needed to document the functionality for 3rd Party users. I defaulted to cranking open Word and started typing, but it felt clunky. As soon as I started to create a table to track version history I started to foresee the confusion often caused in keeping the documentation in sync with the version of the API. Add to that the API is likely to be used on multiple customer sites which may not all be on the same version of the software and there is a recipe for issues in the future.

I decided instead to opt for web based documentation built into the API to ease the potential for syncing issues. I previously posted about my new-found love of Markdown for simplifying publishing for this blog and whilst there are loads of wiki packages out there I opted for a simple Markdown based solution. Fortunately there’s already a Nuget package available to aid with this: Kiwi.Markdown.

To include in a Web API project (I’ve assumed the Razor view engine) you can start by using the Package Manager console:

PM> Install-Package Kiwi.Markdown

to keep it nicely formatted I also threw in Twitter Bootstrap:

PM> Install-Package Twitter.Bootstrap

The Kiwi.Markdown package creates a new view for you for formatting the Markdown.

Views\Wiki\Doc.cshtml

By default this file will be picking up its layout from:

Views\Shared\_Layout.cshtml

To incorporate Bootstrap into your Markdown pages, change Layout.cshtml to:

<!DOCTYPE html>
<html>
	<head>
	    <meta charset="utf-8" />
	    <meta name="viewport" content="width=device-width" />
	    <title>@ViewBag.Title</title>
	    <link href="@Url.Content("~/Content/bootstrap.min.css")" rel="stylesheet" />
	    <style type="text/css">
	      body {
	        padding-top: 60px;
	        padding-bottom: 40px;
	      }
	    </style>
	    <link href="@Url.Content("~/Content/bootstrap.responsive-min.css")" rel="stylesheet" />
	</head>
    <body>
        <div class="navbar navbar-fixed-top">
            <div class="navbar-inner">
                <div class="container">
                    <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </a>
                    <a class="brand" href="#">DOCUMENTATION NAME HERE</a>
                    <div class="nav-collapse">
                        <ul class="nav">
                            <li class="active"><a href="#">Home</a></li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
        <div class="container">
            @RenderBody()
        </div>
            @Scripts.Render("~/bundles/jquery")
            @RenderSection("scripts", required: false)
    </body>
</html>

and your Doc.cshtml to:

@using Kiwi.Markdown
@model Document

@{
    ViewBag.Title = @Model.Title;
}

<div class="span12">
    <h1>@Model.Title</h1>

    @Html.Raw(Model.Content)
</div>

Now adding md files to:

App_Data\MarkdownFiles\

will result in nice neatly formatted good looking documentation.

markdown mvc twitter-bootstrap writing

Web API - Getting Started - Paging, Page Size and Result Size

Posted September 16, 2012

I’ve built a few RESTful APIs in recent years as an alternative to SOAP web services. Over that time it’s got much easier to build them in .Net, firstly MVC v3 added the JsonResult allowing you to just return JSON simply from Controllers and more recently Web API has emerged alongside MVC v4 as a way of building this type of API really simply.

One of the first things I often need to do is get some type of result paging working to support returning only parts of large result sets. The beta versions of Web API had a couple of ways of doing this, using either an OData style syntax or handcrafting it through the querystring but in the final RTM version the Queryable attribute was dropped and this OData support omitted so for now we are left with handcrafting

To build a paged Web API we first need to:

  • Start a new Project in VS2012
  • Choose “ASP.Net MVC 4 Web Application”
  • In the MVC4 dialog choose “Web API”

VS will generate a new project for you and immediately give you a ValuesController.

Hit F5 to debug and in the browser navigate to:

http://your debug server/api/values

This will do a GET request which goes through the ValuesController and hits the method:

public IEnumerable<string> Get()
{
    return new string[] { "value1", "value2" };
}

Note that if you’ve used Chrome to do the query you get the result as XML, this is because the default GET header contains the line:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

You would get the same result if you simply passed in:

Accept: application/xml

e.g.

<ArrayOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
	<string>value1</string>
	<string>value2</string>
</ArrayOfstring>

Or you could switch it to JSON with:

Accept: application/json

which would give you:

["value1","value2"]

You can try this out with the excellent Fiddler. Re-perform the action in the browser with Fiddler running and then drag the request into the Composer where you can manipulate and “Execute” it. This is much easier than trying to do it through the browser over and over and looking in the Inspector -> Raw views you can see exactly what’s going on. I’ll stick with the JSON requests for now.

So once you start to dip your toes into the world of REST you’ll find a lot of arguments over what is and isn’t RESTful. I’m going to handle my paging in the querystring, I think this looks clean and feels REST-y enough for me, I’m sure other people will have differing opinions. What I want to do is be able to limit the query using a url like:

http://your debug server/api/values?page=1&pageSize=2

To do this I add a couple of optional parameters to the Get method along with default values incase they are not specified. By doing this I stop anyone ever returning the whole result set unless they intentionally do so by overriding the pageSize with a big enough number.

List<string> values = new List<string>
        {
            "value1", "value2", "value3", "value4", "value5"
        };

public IEnumerable<string> Get(int page = 0, int pageSize = 3)
{                
    return values.Skip(page*pageSize).Take(pageSize);
}

Debugging now I can see that:

http://your debug server/api/values?page=1&pageSize=4

returns:

["value3","value4"]

This is great but it does give you a bit of a problem if you want to do something based on the size of the entire result set e.g. have links for all the pages for navigation, since you would not know how many pages worth of data there was. I’ve seen numerous approaches for this that involve either a second call to another resource for a count or that modify the result set to add the count in. Neither feel particularly clean to me and my preference is to add it into it’s own custom HTTP header, so that irrespective of the limitations you have implemented through the querystring the entire count is always available e.g.

X-Result-Count: 5

would highlight that there are 5 results in total.

To implement this we have to make a few alterations to our previous method to expose the HttpResponseMessage so that we can access the headers.

public HttpResponseMessage Get(int page = 0, int pageSize = 3)
        {
            var returnValue = values.Skip(page * pageSize).Take(pageSize);
            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, returnValue);
            response.Headers.Add("X-Result-Count",values.Count.ToString());
            return response;
        }

Note the return type is now a HttpResponseMessage and we wrap the data up inside it through the Request.CreateResponse. We then simply add the header and return the response.

This does everything we need to simply return paged results and know the overall size the entire response message for:

http://your debug server/api/values?page=1&pageSize=4

looks something like:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-Result-Count: 5
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RTpcSW5mb3JtXEFQSVRlc3RcQVBJZGVzdFxhcGlcdmFsdWVz?=
X-Powered-By: ASP.NET
Date: Sun, 16 Sep 2012 22:16:18 GMT
Content-Length: 19

["value3","value4"]

We are still left with one final awkward scenario, what if we want to retreive the result set size without any data, well we could compromise and return a single result but this seems clumsy. Fortunately there is the HTTP verb HEAD for just this sort of thing. We can implement it so that a HEAD request includes the result size parameter. Web API makes this really simply since we can just add the following method:

public HttpResponseMessage Head()
{
    HttpResponseMessage response = Request.CreateResponse();
    response.Headers.Add("X-Result-Count", values.Count.ToString());
    return response;
}

now a HEAD request will include the X-Result-Count.

web-api c# rest