I wanted to let everyone know that William Bartholomew and I are working to update our MSbuild book. This will be the third edition. We are going at this a bit different than our second edition. Instead of doing a complete rewrite of the previous book, we have decided that we will release a small book to supplement the existing book. We did this for a number of reasons but it boiled down to the fact that most of the existing content is still accurate. So it would be better to release a small update just covering new stuff. This is going to be really great for everyone who already owns the second edition. You can quickly learn all the new material, and it will be much cheaper than a full sized book. I’m not sure of the cost yet but I will keep you all posted.
For more info on the book please checkout out my new site msbuildbook.com. At that site you can get info on the second edition as well as the third. You can get info on downloading samples for both versions of the book as well. FYI the source for the msbuildbook.com site is available at https://github.com/msbuild-book/msbuildbook.com.
Sayed Ibrahim Hashimi @SayedIHashimi
Sunday, December 30, 2012 1:35:13 AM (GMT Standard Time, UTC+00:00)
A while back I blogged about how to setup SlowCheetah on a Build server. The solution was good but it was a bit unwieldy and error prone, especially those who are not comfortable with MSBuild (this solution still works and is still a good approach for some scenarios). I’ve made this much easier, but wasn’t able to make it as easy as what I wanted. The solution that I choose is using NuGet. Ideally you’d be able to install the SlowCheetah NuGet package into a project, enable package restore and the check in your code. Unfortunately due to how NuGet package restore is implemented this flow is not currently possible. Hopefully in the near future Nuget will better support these scenarios. For now we will have to work with the solution below.
The transformations are executed when your project is built. The way that this works is that when you use the SlowCheetah VS add-in to enable transformations, your project file is modified to import an additional MSBuild .targets file which knows how to do the transformations. This .targets file is placed in your %localappdata% folder. When you add the SlowCheetah NuGet package to your project, the .targets file (and supporting files) are downloaded to the packages folder. Your project is also modified to look at the packages folder for the .targets file which is imported.
For build server scenarios, when using NuGet for this it’s a bit of a chicken and egg problem. Let me clarify, we are using NuGet to update the build process for your project. If a solution is using NuGet, you will need to enable NuGet Package Restore. This is what will enable your NuGet packages to be download during build.
Package Restore is implemented to restore NuGet packages for each project whenever it is built. This is accomplished by adding an Import into your project to NuGet.targets. This works beautiful for the majority of cases, but fails completely if you are trying to update the build process for a given project with NuGet. When the build for a project starts if the the imported .targets file do not exist on disk they are not imported. You can visualize this flow as.
We need to find a way to get the packages restored, before your project is built. We can achieve this by executing a build which will be used to simply restore our packages. Now let’s see how we can workaround this issue.
We need to find a way to restore the packages before the project is built. The easiest way to do this is to add a dummy solution to be built before your actual solution/project. Follow these steps.
1. Install the SlowCheetah NuGet package into the project using SlowCheetah.
You can do this by using the Package Manager Console, and executing the command Install-Package SlowCheetah –pre. Note: after the package is released you can remove the –pre.
2. Enable Package Restore for the solution
You can do this by right clicking on the solution and selecting Enable NuGet Package Restore.
3. Configure build server to build restorePackage.proj before your solution
As described we need a new solution that can be used to restore the required packages. When you install SlowCheetah it will automatically create a packageRestore.proj file in the root of your project. You can use this to easily restore your NuGet packages. All you need to do is to build this file before you build your solution or build script. If you are using Team Build this is pretty easy. Edit the build definition and then add packageRestore.proj to the Items to Build list. You can find this on the Process tab.
Make sure that packageRestore.proj is above (built before) your solution.
With these changes when the empty solution is built, it will restore the SlowCheetah .targets file. Then the target solution will be built, the .targets file will already be downloaded and your transforms will execute as needed.
I will work with the NuGet team to see if there is something better that can be done here. I will keep you all posted if there is any update.I would love if you tried out this new support and let me know if you have any issues with it.
Sayed Ibrahim Hashimi | @SayedIHashimi
I received a customer email and one of the things that he wants to be able to do is sync multiple folders. I thought I’d share with you what I wrote to him.
From: Sayed Hashimi
Sent: Tuesday, December 18, 2012 11:28 PM
You actually can do this, but it’s not based on skips, it’s an opt-in approach. What I mean is that you would have to specify all the folders that you wanted to sync.
MSDeploy is a provider based model. There is an composite provider, manifest, which can be used when multiple providers are required. In your case the actual provider that you want to use is contentPath. This is the provider that knows how to sync folders. If you want to sync multiple folders you can create a source manifest which has the source folders and a dest manifest which has all the target folders.
In my example I have the following folders.
I only want to sync 01 and 03 so I create the manifest with the following content.
<?xml version="1.0" encoding="utf-8"?>
The dest manifest file will contain.
<?xml version="1.0" encoding="utf-8"?>
Then to do the sync you can use the command.
msdeploy -verb:sync -source:manifest="C:\Temp\publish\SourceManifest.xml" -dest:manifest="C:\Temp\publish\DestManifest.xml" -enableRule:DoNotDelete -useCheckSum -disableRule:BackupRule
You can see that I use the manifest provider for both the source and the dest. A few things to note.
- -enableRule:DoNotDelete - Pass this to ensure that other content in the dest is not deleted
- -useCheckSum – Pass this to ensure that only the minimal set of files is synced
- -disableRule:BackupRule – When using MSDeploy v3 I was getting errors relating to the auto backup feature, just pass this to avoid that (this could be an issue with my machine setup)
Drawbacks from this approach
- You must use full paths in the source/dest manifests.
- Your source/dest manifests must have matching contentPath elements
- This approach requires two files; source manifest & dest manifest
How you can make this even better
The real issue I have with this approach is that it requires both a source & dest manifest. If you can easily auto generate these files from a list of shares that would be great. If you are maintaining these files “by hand” you should be careful to make sure both files are updated.
With a bit of more work you can boil it down to a single source manifest if you have a common root folder, and you want the files to be reflected in the same relative structure underneath that. They way that you would do this is to use the MSDeploy auto provider trick. With MSDeploy you can pass –dest:auto and MSDeploy will essentially reflect the source settings to the destination. You can then create an MSDeploy parameter which will be used to update the path of that common root folder.
If you want to go down this option it will be a bit more complex. I’d be willing to walk you through it if you’d be willing to blog about it afterwards J
Sayed Ibrahim Hashimi | @SayedIHashimi
Wednesday, December 19, 2012 7:34:19 AM (GMT Standard Time, UTC+00:00)