A few months ago I published a Visual Studio add-in, SlowCheetah – XML Transforms, which enables you to transform any XML file during a build in the same way that you can transform the web.config during publish/package for web projects. Since then I’ve received numerous requests to demonstrate how the transforms can be kicked in from a CI server. It’s actually pretty easy because all the logic from a transform perspective is contained inside of MSBuild tasks/targets. The Visual Studio add-in itself is only delivering the support for gestures/preview.
Before I dive into how to enable this for a CI server let me explain how the plugin works and then the CI integration will be come much clearer. When you load a project/solution in Visual Studio for the first time after you installed SlowCheetah a set of files will be written to %localappdata%\Microsoft\MSBuild\SlowCheetah\v1. Those file are:
|Install-Manifest.xml||An XML file which describes the files that are installed. This is used by the plugin itself, you should never have to do anything with this file.|
|SlowCheetah.Tasks.dll||The assembly which contains the MSBuild task which transforms XML files.|
|SlowCheetah.Transforms.targets||The MSBuild file which enables XML file transformation|
The add-in adds the following menu command to any XML file for supported project types.
When you click on this for the first time the add-in needs to make some changes to your project file so you are prompted to accept that. After you do the following changes are applied to your project file.
- A new MSBuild property SlowCheetahTargets is added to the project and it points to the SlowCheetah.transforms.targets file in %localappdata%
- An import for that file is added
More specifically the elements added to your project file are.
<PropertyGroup> <SlowCheetahTargets Condition=" '$(SlowCheetahTargets)'=='' ">$(LOCALAPPDATA)\Microsoft\MSBuild\SlowCheetah\v1\SlowCheetah.Transforms.targets</SlowCheetahTargets> </PropertyGroup> <Import Project="$(SlowCheetahTargets)" Condition="Exists('$(SlowCheetahTargets)')" />
Note: If you look at your project file they will not be next to each other. The property will be towards the top of the project file and the import towards the bottom.
So now you might have an idea of why this won’t work on your CI server, the file SlowCheetah.Transforms.targets will not exist in the %localappdata% folder. There is an easy to way to fix this which doesn’t require any changes to your CI server. Check in the files and update your import. Here is what I did:
- Create a folder named SlowCheetah in the same folder as my solution
- Added SlowCheetah.Tasks.dll and SlowCheetah.Transforms.targets to that folder
- Create a solution folder named SlowCheetah in the solution
- Drag and drop the files from your SlowCheetah folder into the SolutionFolder
- Updated my project file to point to these files
Now your solution should look roughly like the following image.
Note: Steps #3/#4 are not strictly required
For #5 you’ll have to edit your project file, don’t worry its an easy modification. Just follow these steps:
- Right click on the project and select unload
- Right click on the unloaded project and select Edit
- Update the value for the SlowCheetahTargets import
In my case the folder that I placed the files into is 1 directory above the project itself. So the new value for the property is as follows.
After that I checked in all the files, kicked off a build and viola the files are transformed. Let me know if you need any more info.
Sayed Ibrahim Hashimi – @SayedIHashimi
Note: I work for Microsoft, but these are my own opinions