It’s common when writing an API to publish a set of samples. This is a great way to give users an idea of the intended usages of your API. Now samples that are intended for publishing are essentially another production application you need to develop, and therefore should go through the same quality checks and processes that the rest of your code does, including version control.
This can raise a couple of challenges once you start to look at how you publish these samples. The issue is that a server based system will need some way to track the client side changes and with most popular version control systems this will involve the presence of extra files around the samples directories. As a consumer of the samples, the presence of these files in the published artefacts is far from ideal. I really don’t want to have the samples trying to connect to your remote server, or even a local instance of a version control provider I might not have installed.
So how do we break the dependency on the source control provider during the packaging of these samples for publishing? We could manually go through and delete all of the binding mechanisms, but that would expose us to the following types of waste:
- Defects – manual processes are more prone to defects
- Waiting – builds need to wait on the samples to be prepared for packaging
- Extra Processing – extra steps to make our packaging pick up our manually cleansed samples
We can avoid most of this waste by automating the process. So if it’s able to be automated, how do we do it?
Download the following script https://gist.github.com/967976. This script is written originally by Damian Maclennan, and essentially removes the TFS source binding files, solution and project elements that reference the TFS instance. My fork includes the ability to decide on if you want the files backed up before removal of the version control sections. I usually choose not to, I don’t want the backup files in the output and have the actual versions in version control if I need them. In addition you may want to do the following:
- Create a batch file wrapper for the script using the approach defined by Jason Stangroome at http://bit.ly/kmyfY2
- Commit the script to a path in your repository that is part of your build workspace with the same name as the PowerShell script
First Step: Create a custom build template
- Setup a build to create your packages, and when you get to choosing the process template clone the default template into a new template
- Check the new template into source control
Second Step: Set up a folder to publish to
- Open your cloned template and navigate to the point at which MSBuild is invoked with the ‘Build’ target
- Drop in a new sequence activity and name it ‘Publish Samples’
- Create an argument named ‘SampleDropFolder’.
- This will be the configurable name for the folder placed in the output directory with our samples inside.
- We’ll talk about how to surface this on the build configuration dialogue later.
- Create a variable to hold the full path to the output folder.
- I’ve named mine ‘SamplesDropFolder’ but that may be a bit close to the argument name for you.
- I also default this to a combination of the outputDirectory variable specified in the scope of the Compile and Test activity and the SampleDropFolder argument we’ve specified previously.
- Open up your ‘Publish Samples’ sequence activity and drop in a ‘Create Directory’ activity.
- Configure it with the ‘SamplesDropFolder’ variable we set up in the last step.
- This will set up a root directory we can copy all our samples to, and makes it easy to run our binding removal script later on.
Third Step: Copy the samples
Now we’ve got our directory, we need to work out what we want to put in it. In most cases, we’ll have more than a single set of folders to move, so we need to put some smarts around how we identify our targets.
- First create an Argument called ‘Samples’ and configure it to be of the type String.
- Drop a ForEach activity into the ‘Publish Samples’ sequence and configure it to iterate over our Samples argument we just created.
- Add a variable to contain the local path of the sample directory we’re currently working with as a string with the name ‘sampleLocalPath’
- Inside the ForEach activity drop a ‘ConvertWorkspaceItem’ activity. This will take our server paths and work out the local path for the directories for us. You’ll need to configure it as follows:
- Drop in a ‘CopyDirectory’ activity to copy our sample directory from the source to the output directory. Your ForEach should now look something like this:
Fourth Step: Remove the source control bindings
Now we’ve got our samples into the target directory, we need to strip out the source control bindings so our customers don’t try to connect to our server when they open the solutions.
- Add an Argument to specify the server path to the batch file we checked in back at the start of the process.
- Create a variable to house the local path of our binding removal script. I’ve named mine ‘SourceControlRemovalScriptLocalPath’
- Drop in another ‘ConvertWorkspaceItem’ activity after your ForEach activity. This will be used to convert the argument we just created with the server path to our source binding stripping script to its local path. It should be configured like this:
Note: While the variables look like they are the same item, they aren't I promise!
- Drop in an ‘InvokeProcess’ activity after the ‘ConvertWorkspaceItem’ you just added. A little care is required when configuring this activity to ensure we get a reliable execution, so I’ll list out how I’ve configured each property.
Arguments: Microsoft.VisualBasic.Chr(34) + SamplesDropPath + Microsoft.VisualBasic.Chr(34)
Display Name: Strip Source Control Bindings
File Name: Microsoft.VisualBasic.Chr(34) + SourceControlRemovalScriptLocalPath + Microsoft.VisualBasic.Chr(34)
Working Directory: BinariesDirectory
Any other properties remain unaltered from their default state
Your publish samples sequence activity should now look a little like this
Fifth Step: Surface the arguments
That’s nearly everything we need to do to support the publishing of samples into our output directory. However we’ve set up a few arguments in here to ensure our template is re-usable. We now need to surface them to users via the build configuration dialog. To do this:
- On the ‘Metadata’ Argument for the build workflow click the ellipsis. You should get a pop up dialog
- Configure the three arguments we’ve added as follows
- The samples list
- The samples drop folder name
- The source control removal script path
- These should be configured in the editor as follows:
The only thing that changes across the parameters are the Display Name - the name we surface to the editor, and the Parameter Name – the name we gave our argument that corresponds to this parameter
Final Steps: Configure the build!
Now we’ve got our template done, let’s go configure a build! The only real point of interest here are the custom parameters we set up on our way through, so we’ll focus on them – this is a long enough read already!
The points of interest are all on the process tab, so let’s skip there. If you expand your custom section you should see something like this:
All you need to do is fill in the values, so it looks more like this:
Once that’s done, kick off a build and you should be able to locate your samples, without the binding configuration in the drop directory of your build output!
In this article I’ve shown you how to create a reusable template for including useful samples in your build output. I’ve used this particular approach with a few customers and what I particularly like about it is we aren’t moving too far from the out of the box activity set that comes with Team Build. This saves us on overhead, and allows the template to be put together pretty quickly.