mark-nugetgo

Updated: How To Use NuGet With ThoughtWorks Go

Developers using the Microsoft technology stack have adopted NuGet as a primary dependency manager. NuGet provides a clean way to acquire interesting reusable components from a reliable public source, stay up to date with new versions of the components (or not), and even use your own NuGet private NuGet repository internally.

One of Go’s strengths is its extensibility. Almost anything that can be run from a command line can be integrated into a Go pipeline and value stream.

mark-nugetgo

This blog shows you how to use NuGet with Go to:

  • Build and publish NuGet packages to public and internal repositories. You can choose to publish manually or automatically as part of a full-up continuous delivery value stream. Mingle.NET is an example of a NuGet package that is built, tested and published this way.
  • Acquire NuGet packages on the fly at build time from public and private repositories. You can choose whether to get the most recent versions of such packages or not.

Publishing Packages

You publish NuGet packages from Go using the NuGet command line utility. This is true for both public and private repositories. To use the NuGet command line you need to have its software on each machine running Go agent(s). Here you have choices:

  • Put nuget.exe in a folder.
  • Check nuget.exe into source control. You probably do this if you have “Allow NuGet to download missing packages during build” enabled.

Note: “Allow NuGet to download missing packages during build” fetches package versions as listed in packages.config in your project. It does not download the latest available versions of packages. We’ll deal with this issue under Acquiring Packages below.

Assuming you have defined your package(s) with appropriate .nuspec files, you can publish from Go using a command line like this:

nuget push MingleNET.1.5.%GO_PIPELINE_COUNTER%.nupkg %NUGETAPIKEY%

Where,

%GO_PIPELINE_COUNTER% is the Go environment variable with a monotonically increasing value each time the pipeline runs. I use this to set a newer version number each time the package is published. %NUGETAPIKEY% is a secure environment variable defined in the pipeline specification that holds the secret API key.

Done. We’re now publishing a NuGet package to either a private internal repository or a public repository.

Acquiring Packages

Packages are easily acquired from NuGet using the command line utility’s install command. It is easy yet leads to a less robust solution. NuGet places the acquired package(s) into a directory containing the package version as part of its name. So, if you “install” the MingleNET package using NuGet you’ll see it land in a directory named MingleNET.1.5.21 or something similar. We can see how this leads to difficulty with assembly references in other projects since the reference needs to be aware of the version number of the dependency. Sometime this is fine. But, if you want to build with the “latest” package binaries then it is better to have the references pointing to a well known location. In our example here we’d prefer the MingleNET package be reliably placed in a folder called MingleNET regardless of its version.

Enter a tool name Sidewinder. Sidewinder pulls down a NuGet package and deploys it into any folder. So, what we’ll do is script Go to run Sidewinder, get our dependencies, and place them in locations known to the dependency references in the project.

sidewinder /p MingleNET /i .\MingleNET