Search code examples
nuget-server

NuGet - disallow overwriting packages (with same name and version number)


I have setup a custom NuGet server for my company. It all works great - I can publish, view packages, etc.

My only concern is that I can publish a package with the same name and version number, thereby overwriting the existing package. This is not ideal and I would like the NuGet server to return an error if a package with the same name and version already exists.

Any clues on how I can accomplish this?


Solution

  • I would also greatly appreciate disallowing to overwrite existing packages. However, it does not seem to be possible using the NuGet server out of the box. A similar feature request has been closed about two years ago.

    But looking at the source code opens some options. Have a look at the CreatePackage()-method. It uses an IPackageAuthenticationService to check if the specified package is allowed to be added (only checks the API Key) and a IServerPackageRepository to actually add the package:

    // Make sure they can access this package
    if (Authenticate(context, apiKey, package.Id))
    {
        _serverRepository.AddPackage(package);
        WriteStatus(context, HttpStatusCode.Created, "");
    }
    

    Both are passed in using constructor injection so it is easy to extend the behaviour by passing custom implementations (Modify the Ninject bindings for that).

    At first sight i would go for a custom IServerPackageRepository. The current implementation uses IFileSystem.AddFile(...) to add the package. You can use IFileSystem.FileExists(...) to check whether the package already exists.

    From a continuous integration perspective it makes totally sense to disallow overwriting an existing package since NuGet follows Semantic Versioning. Thus, a new build should incorporate a bugfix, a new feature or a breaking change. I would choose to allow overwriting snapshots/pre-releases, however.

    Update: It seems v2.8 will have an option allowOverrideExistingPackageOnPush which defaults to true for backwards compatibility. It has been comitted with 1e7345624d. I realized that after forking. Seems i was too late again ;-)