Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / DevOps / TFS

Integrate NuGet Package Restore TFS Build 2013 or Older

5.00/5 (1 vote)
20 Nov 2016Ms-PL6 min read 9.6K  
Learn how to modify the default TFS builds' template and add options for NuGet packages restore. Add a dedicated restore packages settings' section.

If you write .NET application most probably you use NuGet packages. There are a couple of ways to restore them during the build process. The old ways required a special .nuget folder to be included in every solution with a couple of other files. I will show you how not to pollute your projects and solutions with additional MSBuild targets. However, you will need to integrate the NuGet restoration on a build level. So I will show you how to edit the default TFS build template and add a new step for NuGet packages restore. This will work for TFS 2013 or older builds' templates since the new ones have a built-in capability to restore NuGet packages. However, lots of folks don't have the advantage of using the new TFS.

Old Way of Restoring NuGet Packages

Previously all solutions needed to have included a .nuget folder where nuget.targets and nuget.exe were placed. They needed to be added under source control too. Moreover, you were required to include something like the below MSBuild to each one of the solutions' projects.

<RestorePackages>true</RestorePackages> <Import Project="$(SolutionDir)\.nuget\nuget.targets" />

<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

<PropertyGroup>

<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>

</PropertyGroup>

<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />

</Target>

Drawbacks MSBuild-integrated Restore Approach

  • It requires additional files within the solution folder.
  • It requires importing a .targets file into all projects in the solution, which this can introduce issues when projects are shared among multiple solutions.
  • Projects will fail to load if nuget.targets cannot be found.
  • Projects won't build successfully if any of the restored NuGet packages extend MSBuild through a targets file import.
  • Packages are automatically added to Team Foundation Version Control, when in use, unless specifically disabled.

"To avoid all these issues, it's recommended to migrate any project using MSBuild-integrated restore to use the automatic restore capabilities of NuGet 2.7 and above." Read more on the subject on the official NuGet site. There is a short tutorial how to migrate your projects and links to PowerShell scripts that can migrate all of your projects. In short, you need to delete the .nuget folder and delete the previously mentioned MSBuild statements. The last step is to integrate the NuGet.exe restore into your builds. This is the main topic of the article.

TFS Build Restore NuGet Packages

Default Template

1. Locate and open the default Windows Workflow Foundation build template

2. Locate the sequence where your projects are built. This is happening in the Run MSBuild for Project activity

Image 1

We need to include the new activity before the actual build of the projects. 

Default Arguments

I will add a few new parameters (arguments) to the build template. 

3. Click on the Arguments tab and add the new arguments

Image 2

Add New Arguments

Below you can find the new parameters, their type and default values.

Image 3

ShouldRestorePackages- You can specify whether the NuGet restore is enabled.

NuGetFeedSources- Specify the feed URLs which nuget.exe will use to restore the packages. You can specify more than one URL using ";" as a delimiter.

NuGetExeServerPath- The default TFS server path to NuGet.exe. The build will download it if the restore of packages is enabled.

TeamCollectionUrl- The URL of the TFS team collection where the NuGet.exe is placed.

Once declared we could use these settings through our WWF activities.

Add New Build Sequence

4. Add a new sequence and place For Each Project in BuildSettings.ProjectsToBuild inside it

Image 4

Add Download NuGet.exe Sequence

5. Add a new If statement, deciding whether to download the NuGet.exe or not, based on the ShouldRestorePackages argument

Image 5

It is a good practice to change the DisplayName of the if statements. This will give you better troubleshooting capabilities during template's debugging. Also, makes the template more readable.

Image 6

You can change the DisplayName to If ShouldRestorePackages- Download NuGet.exe.

6. Add a new Download File Activity to download the NuGet.exe from TFS (of course, you need to download it from the official site first and then check-in it)

7. Configure LocalPath (where the file will be downloaded)

It will be saved in a temp folder. However, as you can see from the image below the Path class could not be resolved.

Image 7

8. Add an import to System.IO (click on the Imports tab)

Image 8

9. Configure Version parameter

Image 9

You need to set the Version to the following statement- TfsTeamProjectCollectionFactory.GetTeamProjectCollection(New Uri(TfsCollectionUrl)).GetService(Of VersionControlServer)().GetLatestChangesetId().ToString()

For this one to work you need to add another import.

10. Add an import to Microsoft.TeamFoundation.Client

11. Configure VersionControlServer parameter

Image 10

You need to set the VersionControlServer to the following statement- 

TfsTeamProjectCollectionFactory.GetTeamProjectCollection(New Uri(TfsCollectionUrl)).GetService(Of VersionControlServer)()

Create Restore NuGet Packages Activity

The next step is to add the primary activity that will restore the NuGet packages. It will call the downloaded NuGet.exe with a few parameters.

12. Add a new InvokeProcess activity and wrap it again in a new If statement

Image 11

13. Set the Arguments parameters

Set Arguments to String.Format("restore {0} -source ""{1}""", localBuildProjectItem, NuGetFeedSources)

This way you will tell the NuGet.exe to restore the packages of the currently built project from the specified feed URLs.

Image 12

This is how finally your template should look like.

Image 13

Create NuGet Restore Packages Section

If you want to add a new settings tab in your build configuration, you need to add new metadata.

14. Locate the Metadata Argument and click the button at the end of the row.

Image 14

15. Add a new metadata for each of the new arguments that we previously created. 

First, specify the exact name of the argument, then you can assign a display name. The category should be equal for each of the parameters, this will be the name of the section, for example- Restore Packages. Finally, set some proper description so that the people can orient themselves when using your template. 

Image 15

This is how your new settings' section will look like if you edit a build definition that uses the new template.

Image 16

So Far in the TFS Series

1. Connect to TFS Team Project C# Code
2. Manage TFS Test Plans C# Code
3. Manage TFS Test Cases C# Code
4. Manage TFS Test Suites C# Code
5. TFS Associate Automated Test with Test Case C# Code
6. Test Cases Statistics with SSRS and TFS Data Warehouse
7. SSRS SQL Server Reporting Services- Subscriptions for Reports

The post Integrate NuGet Package Restore TFS Build 2013 or Older appeared first on Automate The Planet.

All images are purchased from DepositPhotos.com and cannot be downloaded and used for free.
License Agreement

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)