One thing we’ve run into while developing our .NET core test automation framework is dealing with local nuget packages. If your workflow remotely resembles the one that we use around here for our framework, then you’ve undoubtedly run into the same issues.
Imagine that you have multiple projects, one of those projects generates a nuget package that you need to use in your other projects. You want this setup to be available to you even without internet. This rules out pushing the package to a remote location or cloud. Perhaps we can install the nuget package into the project directly from the nuget package project build folder? Bonus points if nuget manager keeps working with the online repository as well.
We’ll be focusing on Linux and .NET core, as that is what I’m using at the time of writing this blog post. To keep things short, we’ll assume that you have the .NET core SDK installed and a project or two set up and ready to go. Let us also avoid using Mono and its way of managing nuget packages, as that will only complicate things further.
Method 1: passing the source as parameter
We can just tell dotnet where to go looking for the package. For this we use the source flag followed by the directory our nuget packages reside in. The full command would look something like this:
dotnet add package seleniumdotnetcoreframework --source /mnt/shared/source/SeleniumCoreFrameworkNet/ClassLibrary1/bin/Debug
or
dotnet add package --source
Method 2: configuration file
If, for some reason, you are lazy like me and don’t want to add a source parameter behind every command; then this is a solution for you. This method relies on a config file that needs to be set in the root of your project directory (that is where your csproj file resides). Do note that the filename is CaSe SeNsiTive, including the extension part. If you mess this part up then it will not work as dotnet will not be able to find the file. When the file has been created, we add some magic sauce within this file. If you’ve used dotnet to create your project from scratch, then this file might already exist. In that case, edit the file to look like the example below.
In nuget.config, add the following lines:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="local-packages" value="../SeleniumCoreFrameworkNet/ClassLibrary1/bin/Debug" />
</packageSources>
</configuration>
Now try adding the package again as you normally would, but omit the --source
parameter this time. The command would then look like dotnet add package seleniumdotnetcoreframework
. Do not forget to change the value
to the correct path. As far as I’m aware, the path can only be relative to the nuget.config file and cannot be an absolute path. (may change in future versions of .NET core)
dotnet new nugetconfig
is an alternative way to let dotnet generate the file with template inside for you.
As already declared above, nuget.config is case-sensitive and the path you put within the value
parameter must be a relative path to your nuget.config file. Still doesn’t work? There are some other things to take into account. When your local package ID matches a package ID on the online repository of nuget.org, then the online repository takes precedence over your local package. This can have a myriad of side effects from installing the wrong package to throwing odd errors like `error:
Package 'seleniumdotnetcoreframework' is incompatible with 'all' frameworks in project '/mnt/shared/source/demo-dotnetcoreframework/demo-dotnetcoreframework.csproj'
Setting up a local nuget package source is not that hard in retrospect. There are a few gotchas you need to keep in mind, but with some Google-fu or this post, it should be smooth sailing. I have not yet found a way to set a package source globally instead of on a per-project basis. Perhaps that can be the subject for a future post.
I can’t guarantee that this method works on Windows or macOS, seeing as I only tested this out on Linux, but I don’t see an immediate issue that would cause different behavior under those operating systems. I’d wager that it just works on those as well.
Microsoft, in their infinite wisdom, changed the casing of this file. The file is now named nuget.config all lower case. This blog post has been edited to reflect that change.
Microsoft dotnet documentation
Very helpful Stackoverflow answer