10

我已经为我的公司设置了一个自定义NuGet 服务器。一切都很好——我可以发布、查看包等。

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

关于我如何做到这一点的任何线索?

4

3 回答 3

9

我也非常感谢不允许覆盖现有的包。但是,开箱即用的 NuGet 服务器似乎是不可能的。大约两年前,一个类似的功能请求已被关闭。

但是查看源代码会打开一些选项。看看CreatePackage()方法。它使用IPackageAuthenticationService来检查是否允许添加指定的包(仅检查 API 密钥)和IServerPackageRepository来实际添加包:

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

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

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

从持续集成的角度来看,不允许覆盖现有包是完全有意义的,因为 NuGet 遵循语义版本控制。因此,新版本应该包含错误修复、新功能或重大更改。但是,我会选择允许覆盖快照/预发布。

更新:似乎 v2.8 将有一个选项allowOverrideExistingPackageOnPush默认为 true 以实现向后兼容性。它已与 1e7345624d 一起提交。分叉后我意识到了这一点。看来我又来晚了;-)

于 2013-07-21T21:23:47.503 回答
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%
于 2014-08-05T16:37:59.317 回答
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 调用不会抱怨太多,并且不会影响包版本。

于 2019-01-30T21:15:31.307 回答