Jeremy Davis
Jeremy Davis
Sitecore, C# and web development
Article printed from:

Automatic packages from TFS: #5 – Wrap up

Published 01 September 2014
Updated 25 August 2016
This is post 5 in an ongoing series titled Automatic packages from TFS

Having looked at all the pipeline components for package generation last week, now it's time for a wrap up for this series.

As I mentioned in one of the earlier posts, as I worked through the code for this prototype, I changed my mind a bit on some of the basic architecture for the core program from the first post. I ended up re-working the configuration from the original idea and making the source control input and package saving output into configurable options.

Revised configuration

I changed the configuration to make sure that all of the "things that stay the same for a whole project" got loaded in the configuration xml file, and stuff that could change with each run of the tool came from the command line. The XML configuration got described in the third part of this series, but I kind of skipped over the changes to the command line.

The model class for the command line options became this:

public class CommandLineParameters
    [Argument(ArgumentType.Required | ArgumentType.AtMostOnce, HelpText="The xml configuration file", ShortName = "c", LongName = "config")]
    public string ConfigFile;

    [Argument(ArgumentType.Required | ArgumentType.AtMostOnce, HelpText = "Starting changeset number", ShortName = "s", LongName = "start")]
    public int StartChangeSet;

    [Argument(ArgumentType.AtMostOnce, HelpText = "Ending changeset number", ShortName = "e", LongName = "end", DefaultValue = -1)]
    public int EndChangeSet;

    [Argument(ArgumentType.AtMostOnce, HelpText = "The file name for the generated package", ShortName = "p", LongName = "package", DefaultValue = "GeneratedPackage.xml")]
    public string PackageFileName;


First of all, the XML configuration file is a required parameter, as if this file cannot be loaded the tool cannot proceed. The starting and ending changeset numbers and the package file name stay the same. And the package name itself has moved to the config file.

The configuration for the input and output in the XML file rely on finding types that inherit from two new interfaces:

public interface IInput
    void Initialise(ProjectConfiguration config);
    IDictionary<string, SourceControlActions> ProcessWorkItems(string workingFolder, int firstChange, int lastChange);
public interface IOutput
    void Initialise(ProjectConfiguration config);
    void Store(XElement data, string filename);


For the moment, all I've done is add the initialise method to pass in the configuration and extract the pre-existing processing behaviour into the interfaces. But I'm thinking about how these might be refactored to make them more generic in future work. Maybe allowing fetching source changes from GIT, or using a web service call out to a Sitecore instance to generate the actual package file rather than just generating the definition.

The code

If you're interested in looking at the source in more detail, and running this prototype yourself, then you can download the source here. But remember, it's just a prototype, so best not to rely on it for critical stuff until you're satisfied it does what you need.

My next steps

I've done some basic testing while I've been writing these posts, using change sets from existing projects, and compared the output generated to the packages I had used for deployments. So far – touch wood – the tool is generating the right things.

My next goal for this tool is to use it as my primary means of generating deployments for an upcoming project. Testing it against a real-world project should do two things: Firstly it will validate whether the overall approach of the software meets the requirements of the development projects I'm running. And secondly, it should help find any issues with the prototype code itself.

Other things I'm thinking about that could be done to improve the tool include:

  • Update the pipeline components that generate package sources so that if their source is empty, they don't add it to the package.
  • A sensible approach to error handling across the code base
  • Refactoring the code to better support automated tests, and providing some sensible tests.
  • Allowing the output plugin to directly generate the package file from the definition created. Perhaps using something like the Sitecore Rocks webs services.
  • A pipeline component to automate deletions – perhaps via the package's post-install steps.

So chances are I'll drag the odd further blog post out of this bit of work...

↑ Back to top