After digging through a lot of documentation, I believe I finally arrived at a convenient and reusable solution. So, here it is:
Set up a local NuGet feed
If you already have a local feed, you may skip this section.
-
Create the local NuGet feed directory, where your private packages will be stored. In my case, I created a directory called
LocalNugetFeed
inside my user profile directory. -
Add the directory as a NuGet source. You can do this in Visual Studio settings, or you can edit the file “AppData\Roaming\NuGet\NuGet.Config” and add your directory as a package source. In my case, I added
<add key="local" value="%UserProfile%\LocalNugetFeed" />
inside the<packageSources>
element. I used “local” as the name of the source, but you can use any name you wish. This name will be used later, to configure the build process.
Set up a scoped build process
This will allow you to automate the publishing of NuGet packages to your local feed at the scope of a directory and all solutions and projects inside it. For convenience, it will still be an opt-in, on a per-project basis, though.
- In the directory where your Visual Studio solutions and projects are stored (for example, “%UserProfile%\repos”), create a file called
Directory.Build.props
and add the following content to it:
<Project>
<PropertyGroup>
<PackagePublishLocalSource>local</PackagePublishLocalSource>
<PushPackageToLocalSource>false</PushPackageToLocalSource>
</PropertyGroup>
</Project>
The previous file provides default settings for your projects. PackagePublishLocalSource
specifies your local NuGet feed, and you can use the source name or a directory path. PushPackageToLocalSource
specifies whether the NuGet package of a project should be published to the feed when the project is built.
- In the same directory where you created the
Directory.Build.props
file, also create a file calledDirectory.Build.targets
and add the following content to it:
<Project>
<Target Name="PublishPackageToLocalSource" AfterTargets="Pack"
Condition="'$(PushPackageToLocalSource)' == true And '$(PackagePublishLocalSource)' != '' And '$(IsPackable)' == true And '$(Configuration)' == 'Release'">
<Exec Command="dotnet nuget push "$(PackageOutputPath)$(PackageId).$(PackageVersion).nupkg" --source "$(PackagePublishLocalSource)" --skip-duplicate"
WorkingDirectory="$(MSBuildProjectDirectory)"
StdOutEncoding="utf-8" />
</Target>
</Project>
The previous file adds a target to MSBuild, which pushes your NuGet package to your local NuGet feed whenever a package is packed.
The two files you just created will be automatically imported by MSBuild on any projects located in any of the subdirectories of the directory these files are located.
Enable automatic publishing for each of your projects
Now, to have your NuGet packages automatically published to your local NuGet feed, you just need to set PushPackageToLocalSource
to true
on the project file of the projects you want. Like on this example project file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>1.1.0</Version>
<PushPackageToLocalSource>true</PushPackageToLocalSource>
</PropertyGroup>
</Project>
Now, on these projects, you just need to build your project in release mode, or right-click on the project in Solution Explorer and select “Pack “.
Some considerations
Note that, NuGet packages will only be pushed to your local feed if you build or pack your project in release mode, and if the package version differs. If there is already a package with the same ID and version in your local feed, you will see a message in Visual Studio’s output console stating that.