NuGet Tip #2: Run your own package feed
Now that you’re using NuGet to manage the 3rd party code dependencies in your project and you’ve configured Visual Studio and MSBuild to restore missing packages as a pre-build step you can safely remove those packages from source control.
This provides a number of advantages, but it does expose you to a few risks:
- The public NuGet feed may be unavailable when you need to download a missing package;
- The specific version of a package that you depend on may be no longer available publicly;
- The specific version of a package that you depend on may contain different code!
And so on; in other words, that convenience you gained by leaning on NuGet to manage your dependencies required you to give up a bit of control.
Reduce your risk with a private feed
Giving up control is a good thing in many situations, but when it comes to ensuring that you can reliably build and release your software it is sure helpful to make your process repeatable. When it comes to NuGet standing up a private package feed is one way to regain some of that stability.
Thankfully there are a number of options for creating a private NuGet feed:
- myget is a software-as-a-service offering that provides externally hosted package feeds</p>
the official NuGet docs describe two ways to Host your own nuget feed internally, one by standing up an in-house ASP.NET web site to serve packages and the other by simply pointing the NuGet tooling at a file share.
I experimented a while back with making it dead-simple to stand up a local NuGet server but I haven't kept up with NuGet releases. When I revive that code I'll be sure to write about it here.
Once you're hosting your own internal feed you can configure Visual Studio's NuGet tools or the NuGet command line app to include your feed when it looks for packages. For example, in the Visual Studio Tools --> Options menu, open the Package Manager --> Package Sources node:
Back up your dependencies into your internal feed
Now that you are hosting your own package feed it's a good idea to back up the packages that your projects depend on onto that internal feed. This is what enables you to take on management of the uptime of those particular packages rather than depending on the external state of the offical NuGet package feed. Maarten Balliauw has a great post on how to Copy packages from one NuGet feed to another. I personally recommend Rob Reynolds Nuget.Copy.Extension as I've used it several times:#!!{"brush":"bash","toolbar":"false","highlight":"[5]"}
NuGet.exe Install /ExcludeVersion /OutputDir %LocalAppData%\NuGet\Commands AddConsoleExtension
NuGet.exe addextension nuget.copy.extension
NuGet.exe copy castle.windsor –destination \\companyshare\nuget_packages
Prefer your local feed to the
Now that you have your own feed, you can tell MSBuild to use only your internal feed when downloading packages for a build. This will reduce the risk that a new build will mistakenly pull down a new version of a package dependency behind the scenes. Open the NuGet.targets file: And change the following code:#!!{"brush":"xml","toolbar":"false","first-line":"19"}
<ItemGroup Condition=" '$(PackageSources)' == '' ">
<!-- Package sources used to restore packages. By default, registered sources under %APPDATA%\NuGet\NuGet.Config will be used -->
<!-- The official NuGet package source (https://nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->
<!--
<PackageSource Include="https://nuget.org/api/v2/" />
<PackageSource Include="https://my-nuget-source/nuget/" />
-->
</ItemGroup>
to:
#!!{"brush":"xml","toolbar":"false","first-line":"19","highlight":"[20]"}
<ItemGroup Condition=" '$(PackageSources)' == '' ">
<PackageSource Include="http://myserver:8090/dataservices/packages.svc/" />
</ItemGroup>
with that middle line pointing to your internal feed; this will ensure that MSBuild only pulls packages from your feed.