NuGet - 禁止覆盖包(具有相同的名称和版本号)

时间:2013-07-12 04:28:22

标签: nuget-server

我为自己的公司设置了自定义NuGet server。一切都很好 - 我可以发布,查看包等。

我唯一担心的是我可以发布一个名称和版本号相同的包,从而覆盖现有的包。这并不理想,如果已经存在具有相同名称和版本的软件包,我希望NuGet服务器返回错误。

关于如何实现这一目标的任何线索?

3 个答案:

答案 0 :(得分:9)

我也非常感谢不允许覆盖现有的软件包。但是,现在似乎不可能使用NuGet服务器。一个similar feature request has been closed about two years ago

但是看source code会打开一些选项。看一下 CreatePackage() -method。它使用 IPackageAuthenticationService 检查是否允许添加指定的包(仅检查API密钥)和 IServerPackageRepository 以实际添加包:

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

两者都是使用构造函数注入传递的,因此通过传递自定义实现很容易扩展行为(为此修改Ninject bindings)。

乍一看,我会选择自定义 IServerPackageRepository 。当前实现使用 IFileSystem.AddFile(...)来添加包。您可以使用 IFileSystem.FileExists(...)来检查包是否已存在。

从持续集成的角度来看,由于NuGet遵循Semantic Versioning,因此禁止覆盖现有包是完全合理的。因此,新版本应该包含错误修正,新功能或突破性更改。 不过,我会选择允许覆盖快照/预发布。

更新:似乎v2.8会有一个选项 allowOverrideExistingPackageOnPush ,默认为true以实现向后兼容性。它已被1e7345624d所述。我意识到分叉后。似乎我太迟了; - )

答案 1 :(得分:1)

我遇到了同样的问题。我运行自己的SymbolSource服务器。我决定维护已发布包的日志。在我发布包之前,我可以检查日志以查看它是否已经发布,然后不发布它。这都是在MS-DOS批处理文件中完成的。见下文。

@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%

答案 2 :(得分:0)

我编写了一个PowerShell脚本,该脚本删除了现有的软件包版本,但前提是该版本与我要推送的版本匹配:

param (
    [string]$buildconfiguration = "Debug"
 )

function Update-Package ([string]$package,[string]$version,[string]$path)
{
    dotnet nuget delete $package $version -s https://<mynugetserver>/nuget -k <my access code if used> --non-interactive
    dotnet nuget push "$path\bin\$buildconfiguration\$package.$version.nupkg" -s https://<mynugetserver>/nuget -k <my access code if used>
}

Update-Package -package "My.Package" -version "2.2.0" -path "MyPackage"

主要缺点是有可能在更改软件包的同时忘记更新NuSpec或vsproj软件包部分中的软件包版本,以及忘记更改脚本文件中的版本号。

我永远不会在公共NuGet服务器上使用这种技术。

我还使用了不推送此文件的版本,只是删除了它,这在我的Azure DevOps(VSTS)版本中用作PowerShell任务。

我知道NuGet会列出可用的版本,但是我并不是真的想编写一个脚本,该脚本可以读回列表的结果以确定我要构建的版本号是否已经存在。

一件好事是,如果新版本号不存在,则删除的CLI调用不会抱怨太多,并且不会影响软件包版本。