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

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 ;-)


I ran into the same problem. I run my own SymbolSource server. I decided to maintain a log of published packages. Before I publish a package, I can check the log to see if it has already been published and then not publish it. This is all done in an MS-DOS batch file. See below.

@echo off

rem Requires that the Visual Studio directory is in your 
rem PATH environment variable. It will be something like:
rem C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE

rem API key for publishing to SymbolSource server
set apiKey=<<<GUID>>>

rem URL of the SymbolSource web app
set lib=http://<<<address>>>

rem Path to a simple text file on a file share - which happens to be the 
rem same place that the SymbolSource server web app is published.
set log=\\<<<path>>>\publish_log.txt

rem Path to the Visual Studio solution that contains the projects to be published.
set sln=..\<<<solution name>>>.sln

rem Build all projects in the solution.
devenv %sln% /rebuild Debug

rem Delete packages produced during last run.
del *.nupkg

rem Each line in projects.txt is a path to a .csproj file that we want to 
rem create a nuget package for. Each .csproj file has a corresponding .nuspec 
rem file that lives in the same directory.
for /F %%i in (projects.txt) do nuget.exe pack %%i -IncludeReferencedProjects -Prop Configuration=Debug -Symbols

rem Delete any local packages that have already been published.
for /F %%i in (%log%) do if exist %%i del %%i

for %%F in (".\*.symbols.nupkg") do nuget push %%~nxF %apiKey% -source %lib%

rem Log information about published packages so, in the next run,
rem we can tell what has been published and what has not.
for %%F in (".\*.symbols.nupkg") do echo %%~nxF >> %log%

Tags:

Nuget Server