Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Automagically update NuGet packages in .NET projects.
NuKeeper is a global tool on NuGet. Install with
dotnet tool install nukeeper --global
NuKeeper automates the routine task of discovering and applying NuGet package updates.
NuKeeper will compare the NuGet packages used in your solution to the latest versions available on NuGet.org, and:
- List available NuGet package updates on .NET code on the local file system or on a GitHub server.
- Apply NuGet package updates to .NET code on the local file system.
- Make pull requests containing updates to code on a GitHub server.
Package update automation is necessary because .NET developers are bad at applying NuGet package updates. To increase visibility of package updates, and decrease cycle time.
Why do we deploy code changes frequently but seldom update NuGet packages? In Continuous delivery, we know that there is a vicious cycle of "deploys are infrequent and contain lots of changes, therefore deploys are hard and dangerous, therefore deploys are infrequent and contain lots of changes" and a virtuous cycle of "deploys are frequent and contain incremental changes, therefore deploys are easy and low risk, therefore deploys are frequent and contain incremental changes" and so we work hard to move into the second cycle, and afterwards, life is easier.
But NuGet package updates are a form of change that should be deployed, and we likewise want to change the cycle from "NuGet package updates are infrequent and contain lots of package changes, therefore NuGet package updates are hard and dangerous..." to "NuGet package updates are frequent and contain small changes, therefore NuGet package updates are easy and routine...".
NuKeeper is written in .NET Core 2.1, using HTTP APIs and command-line tools. It runs on Linux and on Windows.
NuKeeper was designed from the start to work on .NET Core and .NET Full Framework solutions. It can work on the new "Visual Studio 2017" format of
.csproj files, with
<PackageReference> elements, and on the older "Visual Studio 2015" format, with a
NuKeeper will also work in
.fsproj project files.
Private package sources are supported. To specify package sources other than the public NuGet.org feed, it is recommended that you use a
NuGet.config file in your repository. It will be used by NuKeeper, and by other tools. NuKeeper also allows these sources to be specified on the command line.
- LibGit2Sharp for git automation.
- Octokit for GitHub automation.
- NuGet.Protocol for NuGet api queries.
NuGet.CommandLine for updating
- McMaster.Extensions.CommandLineUtils for command line parsing.
Command lines called:
Limitations and warnings
NuKeeper works with git, no other source control systems are supported for raising pull requests. You can however use the public
github.com, or an internal hosted GitHub instance by specifying its location with the
--api option. You can also apply changes locally with the
When the package version used is a prerelease (AKA a beta), later betas or release versions will be found and applied. When the package version used is not a beta, they will not.
Package tools required
You will need the command line version of
dotnet installed. NuKeeper can run on all platforms where
dotnet runs, including Windows, linux and MacOS. Inspection should work on all of these platforms.
However not all update cases work on all platforms. In short: You can update windows-only code on windows, and update cross-platform code on any platform.
NuKeeper will invoke
dotnet or the
NuGet.exe tool as needed to update packages. The "windows only" restriction is due to the older
packages.config file format requiring
NuGet.exe, which is windows only. There are no plans to port
dotnet is the portable replacement. This is another reason to update these projects to the new
<PackageReference> style, so that they can be worked with using
For projects using
NuGet.exe no longer runs
uninstall.ps1 scripts from command line.
Those are still executed from Visual Studio, resulting in different behaviour for packages relying on this functionality.
An example of this is StyleCop.Analyzers which (when used with a
packages.config style project) will not update the
<Analyzers> node in the project file.
This does not affect projects using
<PackageReference> project file format, as that format replaces install scripts with content transformations, which are supported.
When to use NuKeeper
Scope of NuKeeper
NuKeeper, right from the start, aimed to be a package updater for all .NET scenarios. This means both .NET Core and .NET Full framework are supported; old and new project file format, and
.fsproj files are all supported. Additional custom package feeds are supported, as many larger companies use internal nuget feeds to manage internal artefacts.
We do not plan to make NuKeeper a general update tool for multiple languages and package managers such as Node.js NPM and Ruby gems. Such update management tools already exist, and some are listed here. These tools tend to have only basic .NET Core support and are not coded in c#. We feel that we would rather embrace the .NET project and package system to the exclusion of others, since no other tool covers this case as well.
NuKeeper was initially created raising Pull Requests for the GitHub collaboration platform, in both the public and internal enterprise versions, as this is what we used. The code was tightly coupled to GitHub Octokit. However, due to demand for other back ends, and the submitted code; it is now a model where the source control platform is selected at runtime. Supported platforms are:
NuKeeper is free open source, but you will have to run it yourself to update your code.
If the project is a library that itself produces a NuGet package, it is usually best not to update it aggressively without cause. Consider carefully whether you want to force your users to also update entire dependency chains.
MyFancyLib depends upon
9.0.1 then an application that depends upon
MyFancyLib can use
9.0.1 or a later version. Updating the reference in
10.0.3 takes away some flexibility in the application using
It might even cause problems.
Libraries should, however, update their packages when there is a breaking change in the features that they use or another compelling reason. e.g. If
8.0.1, but since it only calls
JsonConvert.DeserializeObject<> many versions of
Newtonsoft.Json can be used.
But now I am converting
MyFancyLib to NetStandard for use in .NET Core. The lowest version of
Newtonsoft.Json that supports this is
9.0.1, so we use that.
Although there are later versions of
Newtonsoft.Json, this gives
MyFancyLib what it needs and allows clients the most choice within the constraint of supporting NetStandard. Another compelling reason to update a dependency would be if there is a bug fix that impacts the working of
MyFancyLib, so users of
MyFancyLib really should apply it.
In an end-product deployable application, frequent updating of packages is a better tactic. Supported by comprehensive automated testing, regular updates will keep your application up to date with security fixes and prevent it from relying on potentially outdated libraries.
This is an application of Postel's Law: Packages should be liberal in the range of package versions that they can accept, and applications should be strict about using up to date packages when they run.
It is similar to this rule of preferring to use a parameter of a base type or interface as it allows wider use.
Inspired by Greenkeeper.