Continuous Integration using TFS, NuGet, and Artifactory

This blog shows how Artifactory, a binary repository manager, can be used a) as the storage location for remotely located build references, b) as a drop site for locally built CI artifacts, c) and in a future blog how it can also function as a storage and of all these binaries.

For this demo we will use the MyLogger solution. MyLogger .sln consumes third-party references during its build process and produces a library exposing a simple logging method. This library which will later be consumed from Artifactory by a second solution in a follow-up blog. The third party remotely located resources used by MyLogger will be cached in Artifactory.

Artifactory, combined with NuGet, allows TFS users to retrieve the latest binaries from their local CI builds while automatically updating referenced binaries coming from multiple remote repositories. Using Artifactory in this manner will limit the downtime of CI builds due to limited internet access.

First, Let’s Download the Source Code Example

You can clone, fork and clone, or use thetab to get a zip file of the code. After downloading the source code, create a TFS project (TFVC or GIT) using the Default Scrum Template in TFS 2013. Add the source to the TFS project.

Your source code tree should look like this:

source code tree

WARNING: You should wait before opening the solution in Visual Studio. NuGet and Artifactory needs to be installed first or there may be some attempts to find the packages from other sources.

Second, Let?s Setup of an Artifactory Pro Server

Standard Setup:

For integration with NuGet, the Pro version will be needed. The Java SDK 1.7+ is a requirement for running Artifactory. The Artifactory Pro Server may be located on one?s local workstation, the TFS host, an unrelated machine, or even exist in a cloud. For our purpose here our local TFS server will host the Artifactory Pro services.

  1. Download and install Java SDK 1.7+ (create an environment variable for $JAVA_HOME)
  2. Download and install an evaluation copy of Artifactory Pro to run as exe


After the server is installed with a valid Pro temporary license (license will be emailed from JFrog), and before starting the Artifactory services replace the following two files with the onesetup the user accounts.

  • security.xml = $(Artifactory-Home)etcsecurity.import.xml
  • .xml = $(Artifactory-Home)etcartifactory.config.import.html

To manage TFS related remote and locally produced binaries in Artifactory, we will need some custom repositories (see below – these were automatically created when you replace the artifactory.config.xml file above). A reference of instructions can be found at: custom repositories

local built libraries prior to QA testing and approval. The latest libraries here can be used for integration into the latest development code for testing.

versions of all packages. This repository will be the final storage for the locally built and QA tested/approved for consumption or production.

nuget-staging-local repository. These symbols will be pulled and deployed for debugging purposes by the developers.

JCenter gallery. This repository will cache the libraries that will be consumed in the builds from This provides a local source for these libraries and maybe be useful for use with TeamCity plugins and the Artifactory Remote Search.

nuget gallery. This repository will cache the libraries that will be consumed in the builds from This provides a local source for these libraries.

Now, Create a Build Definitions in Visual Studio

After the source code for the MyLogger solution has been downloaded and is in a TFS project, we need to create a build definition.  This default settings with the exceptions highlighted and described below.

MyLogger Build Definition

MyLogger Build Definition
NuGetExampleMyLoggerMyLogger.sln is the solution that will build and store the MyLogger.dll

/.targets file. The DistribPackages task is mean to “push” the Nuget packages from the build site to the local Artifactory repository.

When .targets file is customized to contain the MSBuild targets needed to deploy to Artifactory.

\tfsbuildssymbols — creates a drop site for the symbols that are generated for this build. In this example we do not capture all the generated symbols and test results.

$.Build number. This revision number allows TFS to increment the Revision number used in the “get last revision” of MyLogger when building the Multi-Example project.

Time to Integrate NuGet with Visual Studio

After the build definition has been created, we need to integrate thewith Visual Studio solutions. Install instructions follow below:

  • In Visual Studio, go to Tools –> NuGet Package Manager –> Package Manager Settings
  • General –> Package Restore – Turn ON “Automatically check for missing packages during build in Visual Studio”

Package Restore
Package Sources – Make sure only the local Artifactory is being used for package sources. We want everything used in the build to be cached inside of the local Artifactory server.  Changes made here will be reflected in the %APPDATA%RoamingNuGetNuGet.config.

Package Sources

By creating the integration of the follow files have been modified as described below and will need to be checked in. The project and solution files should also be checked in after the integration.

.config file

The Artifactory server path will be added. Make sure the Artifactory key is pointing to the correct location and only one exists.

.targets file

The .targets file.

  • New Command UpdateCommand
  • New Command DistribCommand
  • Set Build to Depend on DistribPackages
  • New Target .config if needed.
  • New Target DistribPackagesruns the NuGet push command to Artifactory
  • New Target TFSEnvVarTestget the path to msbuild.exe on the build server
  • New Task TFSEnvVar

*sln file

The nuget project will be added to the solution file.

*csproj files

During the VScsproj file found in the solution:

<Import Project=”$(SolutionDir).nugetNuGet.targets”

<Target Name=”EnsureNuGetPackageBuildImports”

Next, Build MyLogger and Deploy to Artifactory

Verify that the third party reference is coming from Artifactory and is managed by NuGet.
To verify the NuGet packages are actually coming from Artifactory, view the Artifactory logsrequest.log. Since we are doing a clean build the packages folder will be empty and should now be populated only from Artifactory.

nuget gallery cache

Execute the build definition. If the build definition has been correctly setup, after queuing, we should see a .Json file was correctly updated during the build.

BuildDefinition name
The TFS drop site, if it was nuget-staging-local repository.

TFS drop site

In the MSBuild log find a RestorePackages section. References to NuGet packages, regardless of where they originate, are stored in the csproj file.

Here we are reading the package.targets file will download these files to the Packages folder.

During the build of the multiple-example project, we use a pre-build .config would already be loaded and will not get updated prior to the build.

powershell script
The BuildPackage section, in the MSBuild log, will show which NuGet packages have been created during the build and where the references to the dependencies packages are derived from.

BuildPackage section
The DistribPackages section in the MsBuild log file shows where the NuGet application.

DistribPackages section
The teams. These concepts will be demonstrated in a follow-up blog.

This concludes the first section of this blog.
A future continuation blog will cover the promotion of this package to a “release-local” repository, security and access, and the consumption of this package by other builds to produce new packages which will be delivered into a CI production pipeline.