June 2011 Archives

As you have probably heard by now, Eclipse 3.7 shipped today.  Congratulations to everyone involved.  From a personal point of view I’m secretly pleased to see that one of my own bug reports manage to sneak it’s way in to this release as well which I think means I have managed to do my bit and contribute a little something to every Eclipse since 3.4

We’ve been tracking the Indigo release internally through the latter milestone builds and so far we’ve yet to discover any issues when using Eclipse 3.7 with Team Explorer Everywhere 2010 SP1 (as many of the team do every day).

Eclipse 3.7 with Team Explorer Everywhere 2010 SP1

Let me know if you think you do find something but as we don’t use any internal Eclipse API’s, we stick to the standard Eclipse contributions and install via the standard update site model - Eclipse 3.7 is looking very good with TEE 2010 SP1.

I’ll be showing off Team Explorer Everywhere 2010 SP1 in Indigo at the following events over the next few days:

This weekend I thought I would get round to a project that I’ve been meaning to do for a long time – a new website for the Radio TFS podcast that I do with Mickey and Paul.  I haven’t had the chance to play with WebMatrix before so thought that I would give it a try when building the new Radio TFS site.  I’m also behind in my learning's around ASP.NET MVC, WebDeploy and IIS 7 so it’s going to be a good weekend! 

One thing that I wanted to do was make sure that all the old episode links redirect to the new locations.  To do this I’m building a HttpHandler that listens for all the requests ending in *.aspx (which is what the episode links did) and then look up that link in the database to redirect them to the new link.  However it took me a while to figure out how to create a HttpHandler in Webmatrix.  As with everything – once you know the answer it is easy but as it took me a while to figure out I’m documenting it here in case others try searching for the answer with the same keywords I was using.

The first step is to create your HttpHandler class.  In the App_Code directory in your WebMatrix site create a new C# file (mine is called LegacyUrlHandler.cs).  A very simple HttpHandler is below.

using System;
using System.Collections.Generic;
using System.Web;

namespace RadioTFS
{
    public class LegacyURLHttpHandler : IHttpHandler
    {
        public bool IsReusable
        {
            // The same instance of this class can be re-used so we return true.
            get {
                return true;
            }
        }

        public void ProcessRequest(HttpContext context)
        {
            HttpResponse response = context.Response;
            response.Write("<html><body><h1>Hello World!</h1></body></html>");
        }
    }
}

You then have to register this HttpHandler in the web.config.  Assuming this is being deployed to IIS7 you register it as follows:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        .....
        <handlers>
            <add name="LegacyUrlHandler" verb="*"
                path="*.aspx"
                type="RadioTFS.LegacyURLHttpHandler"
                resourceType="Unspecified" />
        </handlers> 
    </system.webServer>
    ....
</configuration>

Hope that helps you.  I’ll probably be blogging again over the weekend as I discover more – and I’ll definitely let you know when the new site is live.

When you create a new build definition with TFS 2010 by default it does a clean build for you every time.  That is to say that between builds all the source from the previous build is deleted along with the compiled outputs and then the source is downloaded fresh, built and you are good to go.  There is a good reason for this to be the default – it is the safest option.  If your build script messes around with the files in your source directory at all (perhaps baking in a build number into the AssemblyInfo files etc) then you want to get a clean workspace to ensure that you are back to a known good state.

However, if you know what you are doing then there are couple of really good reasons why only building the things that changed between builds would be very useful:

  1. Speed – if you are doing CI builds (which you should be doing if you are not BTW) then the only thing that will have changed between builds to the same build agent are the contents of a single check-in – a single changeset.  If you are checking in regularly (which you should be doing BTW) then these changesets usually contain a small number of changes.  Downloading only the files that have changed between builds speeds things up but also only compiling new versions of assemblies that have been affected saves even more time.
  2. Differential Deployment – For websites it makes a lot of sense to use something like robocopy to deploy the output of a build to a directory used by a test IIS instance.  By using robocopy you can specify that only the files that have changed should be copied over.  When TFS does a get into a clean workspace the files did not previously exist in that location on disk.  Therefore the creation date and modification dates of the source files are taken as the time at which they are downloaded to the machine – i.e. the time of doing a get.  By switching to incremental builds files which haven’t been touched are left alone so older files keep their timestamps.  Only the changes files have a new timestamp.  Utilities such as robocopy can therefore easily identify these and therefore only deploy the changes files over to IIS.  IIS then sees that the file is new and so compiles it first time that page is accessed or a page references an assembly that has been updated.

Traditionally, in the world of build solutions, incremental builds were always treated with a bit of “Here be dragons”.  Many version control systems can leave orphan files around in your local working copy when you update to the latest version from the server (for example in the case that a file was deleted, moved or renamed on the server).  TFS however cleans up your workspace as you go along so that when you do a get deleted files are deleted from your local file system, as are the old versions when you do a rename/move etc.

Enabling Incremental Builds with TFS 2010

To enable incremental builds, edit the build definition in Visual Studio 2010 and set the Clean Workspace property to “None”.

Default Template build process properties shown when editing the build definition in Visual Studio 2010

Note that there are a few options for Clean Workspace, All; Outputs; None – take a look at the handy property help text to learn more about what they mean. For example Outputs is useful if you want the benefit of not downloading all your source every time but are not able or do not trust the ability to incrementally compile your binaries.

Your mileage may vary depending on your build process and what you do during it.  Depending on assumptions made during and build customization work you have done you may indeed need to re-engineer the way that you do your build to be able to reap the benefits of incremental builds.  Also, you may want to do things like incremental builds to a dev test instance but a full clean build for your nightly drop to a QA test environment.  Also remember that even with a CI build set for incremental builds, you can at any time Queue a manual build from Visual Studio by right clicking on the build definition in Team Explorer.  From there you can (if you wanted) set the Clean Workspace property to All for your manual build if something funny was going on and you just wanted to reset everything – and if you are really fancy you might even do it so that a deployment of a clean build to IIS not only copies all the files over fresh but forces an IIS Reset for the true belt and braces approach.

Archives

Creative Commons License
This blog is licensed under a Creative Commons License.