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
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
Add New Arguments
Below you can find the new parameters, their type and default values.
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
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
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.
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.
8. Add an import to System.IO (click on the Imports tab)
9. Configure Version parameter
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
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
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.
This is how finally your template should look like.
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.
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.
This is how your new settings' section will look like if you edit a build definition that uses the new template.
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