There is good reason to create NuGet packages automated. This will eliminate the difficult and error-prone manual process. Creating and publishing of NuGet packages isn’t hard by the Team Foundation Server (TFS) build, except of prerelease versions.

Build and publish NuGet packages

As first you should choose the right versioning strategy. In this sample I’m using the standard Major.Minor.Build.Revision approach, where the last two numbers, Build and Revision are set by TFS during the build.

[assembly: AssemblyVersion("1.0.*.*")]

Next i will setup the Automated Build and call NuGet.exe to create and publish NuGet package.

TFS Build Process with NuGet

"C:\Program Files (x86)\NuGet\nuget.exe" pack "$(TF_BUILD_SOURCESDIRECTORY)" -OutputDirectory "C:\Nuget Packages"

As you can see I didn’t provided what to exactly should be packaged. This is easy to explain: per default NuGet.exe is searching appropriate project file, like .csproj and I included the folder where NuGet should searching for. Because I’m using .csproj file to generate NuGet, all information and dependencies would be recognized and set.

NuGet Calc.MathFunctions

This is nice, fast and in most cases appropriate way to provide NuGet packages. But there will be times, especially in large teams, where you would need to provide interim revisions. This is where NuGet packager don’t provide easy way to do it automatically and it can be good reason for this, but, still I will show you the way to achieve this.

Create and publish prerelease NuGet packages by TFS build

Interim revisions or prereleases are NuGet packages where version info is followed by arbitrary string.

NuGet Calc.MathFunctions Prerelease

The idea to generate prerelease NuGet packages is following:

  1. Building the project by TFS Build
  2. Pick out the output assembly version number
  3. Use the version number and some constant string to set NuGet.exe -Version parameter
Param(
[Parameter(Mandatory=$false)]
[string]$pathToNuGetCommandLine,
[Parameter(Mandatory=$true)]
[string]$pathToProjectFile,
[Parameter(Mandatory=$false)]
[string]$publishNuGetToFolder,
[Parameter(Mandatory=$true)]
[string]$assemblyOutputPath,
[switch]$isPreRelease = $false
)

sl $pathToProjectFile

$nugetExeName = "nuget.exe"
$fullPathToNuGet;

if([string]::IsNullOrEmpty($pathToNuGetCommandLine))
{
	$fullPathToNuGet = $($nugetExeName)
}
else
{
	$fullPathToNuGet = $pathToNuGetCommandLine
}

$nugetExeParameters = " pack -OutputDirectory `"$($publishNuGetToFolder)`" -Verbosity detailed"
$nugetExeProperties = " -Properties Configuration=Release``;OutputPath=`"$assemblyOutputPath`""

if($isPreRelease)
{
	#get assembly name from csproject file
	$csProjFileName = (Get-Item "*.csproj").Name
	[xml]$projectFile = Get-Content $csProjFileName
	[string]$assemblyName = "$($projectFile.Project.PropertyGroup.AssemblyName).dll".Replace(' ', '') #remove spaces

	#get assembly version
	[string]$fullPathToAssembly = Join-Path $assemblyOutputPath $assemblyName
	$assemblyVersion = (Get-ItemProperty $fullPathToAssembly).VersionInfo.FileVersion

	#set version parameter based on assembly version
	$nugetExeParameters +=  " -Version {0}-Prerelease" -f $assemblyVersion
}

$nugetExeCommandToExecute = "$fullPathToNuGet $nugetExeParameters $nugetExeProperties"

Write-Host "Running command: $nugetExeCommandToExecute"
iex "&$nugetExeCommandToExecute"

TFS Build Process with own PowerShell script

"C:\Build Scripts\CreateAndPublishNuGetPackage.ps1" -pathToProjectFile "$(TF_BUILD_SOURCESDIRECTORY)" -publishNuGetToFolder "C:\Nuget Packages" -assemblyOutputPath "$(TF_BUILD_BUILDDIRECTORY)\bin"

This script won’t win Miss Universe because I’m not very experienced PowerShell developer. I was most of the time disturbed by the fact that there are probably thousand ways how executable can be invoked. But this is another story.