And, without modifying your project “*.*proj” files.
And, without storing nuget.exe in your project’s source control.
NuGet 1.6 is out and with it is a new update to Visual Studio that will update your solution and projects with some extra code and even the NuGet.exe application so that your build process will dynamically download the required NuGet packages. Rightly so, this is in response to the request that NuGet packages not be stored in source control as they just take up space since they are always available via download.
I understand the approach that was taken (including a .targets file as well as the nuget.exe as well as updating the **proj files) however, I think all of that is unnecessary clutter if your build process can handle it alone.
So, I looked at the NuGet commands and updated the standard TFS 2010 build template to manage this additional step automatically. With this new template, there is no need to update your solution or projects or include NuGet.exe in your project source.
The only thing you really need to change in your project source control is remove the “packages” folder from source control. That folder will automatically be created during the build.
Even if you already have custom build templates, you should be able to copy the NuGet restore section over since it is all contained in a single sequence.
The one thing this solution does not do is download the packages locally on your dev machine. So, if you are getting a solution from source control for the first time, you won’t get all of the references you need since the packages folder isn’t in TFS. That is easily fixed with a simple PowerShell script that you can run locally to set you up. All of this is provided below.
Download the “NuGetRestoreTemplate.xaml” template and add it to source control. This can be anywhere - it doesn’t need to be part of your Team Project, it just needs to be in a location where your build can access it.
You have 3 options here.
- The easiest and least intrusive your build machine is to add NuGet.exe to source control. Like the template, this does not need to be in your Team Project. Just put it in a location where your build can access it. You then tell the build definition where it exists in source control. This approach makes updating NuGet.exe easy since it’s all done through source control. You never have to get on the build machine which in some environments is next to impossible.
- Put it on your build server and remember the exact file path. You can tell the build definition exactly where to look for it.
- Put it on your build server and add that folder to your PATH environment variable. If you do this, then you will leave the location blank in the build definition. It will be found automatically. One note here: if you do this, you may have to reboot your machine so the build process realizes the right path.
One suggestion for the template and the NuGet.exe location in source control: Create a general Team Project that will house all of your build goodies such as custom templates, custom activities and support applications. I generally create a “BuildActivities” project and put everything in there. You just need to give everyone read access to it.
To follow along with this recommendation, I created a “BuildActivities” Team Project. In it I have a “BuildProcessTemplates” folder where I keep all of the generally available build templates. I have a “NuGet” folder where I keep the “NuGet.exe” application. I also have subfolders in here for previous releases (just in case). I also have a folder called “Custom Activities” for all of the custom activities that my templates require. Note: the template I created for the solution I am describing does not require any custom activities. I just included that suggestion for completeness.
Creating the Build Definition
Creating the build definition is pretty straight forward.
- When you get to the Process, click “New…” next to your “Build process file:”.
- Click “Select an existing XAML file”
- Click “Browse” and navigate to where you placed the template in source control
- Click “OK”
The “NuGet Restore/Install” section will appear in the build process parameters
Enter the location of the NuGet.exe file. In this example I placed it in source control but you can just as easily enter the full path on the build machine if that’s where you placed it. Leave this blank if you put NuGet.exe on the build machine and in the “Path”.
Next, you can add the locations of where to look for the NuGet packages during download. You can enter multiples here – just delimit with a semi-colon “;”. If you leave this blank, NuGet will attempt to look at “%AppData%\NuGet\NuGet.config” for NuGet repositories. Keep in mind that if you leave the parameter blank and expect the build machine to look in the config file, that location is account specific. The ID of the build process will need to have that file available.
In my example, I included a local network share I set up as a gallery as well as the official NuGet Gallery.
The “Additional Install Arguments” is there if you want to include other parameters like “-Prerelease” or “-ExcludeVersion”. Note: include the “-“ before each parameter.
That’s it. You can now remove the “packages” folder from source control and do a build.
Of course, and as always, I would recommend testing this first on a sample app within your environment just to see how it works.
When you run the build, you will see in your log file something similar to this:
This shows that the build process has dynamically downloaded all of the required NuGet packages.
Here’s the templates and PowerShell Script:
The 2nd template I’ve provided will do the same “restore” process but will also update to the latest version of the NuGet packages rather that just the versions listed in the projects. It is called NuGetRestoreUpdateTemplate.xaml. Note: it may or may not break your code to use the update template depending on the version of the package that is downloaded. See the NuGet documentation for more details. You can include the “-safe” option in the build definition to avoid the breakage.
The PowerShell script will restore all of the NuGet packages locally if you are not storing the “packages” folder in source control: NuGetRestore.ps1