透过Azure管线还原本地NuGet包问题

4
我在Azure Pipelines中遇到了一个问题,我有一个本地的NuGet包存在于我的repo中,我希望将它与所有其他NuGet包一起包含在pipelines构建中(这些包通常都是从nuget.org获取的)。 我的项目基于ASP.NET Core构建,更具体地说,它是一个Blazor服务器端Web应用程序。
本地NuGet包“Breeze.Sharp.0.9.6.nupkg”存储在我的repo下:MySolution/packages 正在发生的情况是,在pipelines中,nuget.org包可以恢复,但尝试查找我的本地NuGet包位置时失败,并抛出以下错误:
     1>/usr/share/dotnet/sdk/3.1.402/NuGet.targets(128,5): error : The local source '/home/vsts/work/1/Nuget/MySolution/packages' doesn't exist. [/home/vsts/work/1/s/MySolution/MySolution.sln]
         NuGet.Protocol.Core.Types.FatalProtocolException: The local source '/home/vsts/work/1/Nuget/MySolution/packages' doesn't exist.
            at NuGet.Protocol.LocalV3FindPackageByIdResource.GetVersionsCore(String id, ILogger logger)
            at NuGet.Protocol.LocalV3FindPackageByIdResource.<>c__DisplayClass22_0.<GetVersions>b__0(String keyId)
            at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
            at NuGet.Protocol.LocalV3FindPackageByIdResource.GetVersions(String id, SourceCacheContext cacheContext, ILogger logger)
            at NuGet.Protocol.LocalV3FindPackageByIdResource.GetAllVersionsAsync(String id, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken)
            at NuGet.Commands.SourceRepositoryDependencyProvider.GetAllVersionsAsync(String id, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken)
            at NuGet.Commands.SourceRepositoryDependencyProvider.FindLibraryCoreAsync(LibraryRange libraryRange, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken)
            at NuGet.Commands.SourceRepositoryDependencyProvider.<>c__DisplayClass19_0.<<FindLibraryAsync>b__0>d.MoveNext()
         --- End of stack trace from previous location where exception was thrown ---
            at NuGet.Commands.SourceRepositoryDependencyProvider.FindLibraryAsync(LibraryRange libraryRange, NuGetFramework targetFramework, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken)
            at NuGet.DependencyResolver.ResolverUtility.<>c__DisplayClass9_1.<<FindLibraryFromSourcesAsync>b__0>d.MoveNext()
         --- End of stack trace from previous location where exception was thrown ---
            at NuGet.DependencyResolver.ResolverUtility.FindLibraryFromSourcesAsync(LibraryRange libraryRange, IEnumerable`1 providers, Func`2 action)
            at NuGet.DependencyResolver.ResolverUtility.FindLibraryByVersionAsync(LibraryRange libraryRange, NuGetFramework framework, IEnumerable`1 providers, SourceCacheContext cacheContext, ILogger logger, CancellationToken token)
            at NuGet.DependencyResolver.ResolverUtility.FindPackageLibraryMatchAsync(LibraryRange libraryRange, NuGetFramework framework, IEnumerable`1 remoteProviders, IEnumerable`1 localProviders, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken)
            at NuGet.DependencyResolver.ResolverUtility.FindLibraryMatchAsync(LibraryRange libraryRange, NuGetFramework framework, String runtimeIdentifier, IEnumerable`1 remoteProviders, IEnumerable`1 localProviders, IEnumerable`1 projectProviders, IDictionary`2 lockFileLibraries, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken)
            at NuGet.DependencyResolver.ResolverUtility.FindLibraryEntryAsync(LibraryRange libraryRange, NuGetFramework framework, String runtimeIdentifier, RemoteWalkContext context, CancellationToken cancellationToken)
            at NuGet.DependencyResolver.RemoteDependencyWalker.CreateGraphNode(LibraryRange libraryRange, NuGetFramework framework, String runtimeName, RuntimeGraph runtimeGraph, Func`2 predicate, GraphEdge`1 outerEdge, TransitiveCentralPackageVersions transitiveCentralPackageVersions)
            at NuGet.DependencyResolver.RemoteDependencyWalker.CreateGraphNode(LibraryRange libraryRange, NuGetFramework framework, String runtimeName, RuntimeGraph runtimeGraph, Func`2 predicate, GraphEdge`1 outerEdge, TransitiveCentralPackageVersions transitiveCentralPackageVersions)
            at NuGet.DependencyResolver.RemoteDependencyWalker.WalkAsync(LibraryRange library, NuGetFramework framework, String runtimeIdentifier, RuntimeGraph runtimeGraph, Boolean recursive)
            at NuGet.Commands.ProjectRestoreCommand.WalkDependenciesAsync(LibraryRange projectRange, NuGetFramework framework, String runtimeIdentifier, RuntimeGraph runtimeGraph, RemoteDependencyWalker walker, RemoteWalkContext context, CancellationToken token)
            at NuGet.Commands.ProjectRestoreCommand.TryRestoreAsync(LibraryRange projectRange, IEnumerable`1 frameworkRuntimePairs, NuGetv3LocalRepository userPackageFolder, IReadOnlyList`1 fallbackPackageFolders, RemoteDependencyWalker remoteWalker, RemoteWalkContext context, Boolean forceRuntimeGraphCreation, CancellationToken token, TelemetryActivity telemetryActivity)
            at NuGet.Commands.RestoreCommand.ExecuteRestoreAsync(NuGetv3LocalRepository userPackageFolder, IReadOnlyList`1 fallbackPackageFolders, RemoteWalkContext context, CancellationToken token, TelemetryActivity telemetryActivity)
            at NuGet.Commands.RestoreCommand.ExecuteAsync(CancellationToken token)
            at NuGet.Commands.RestoreRunner.ExecuteAsync(RestoreSummaryRequest summaryRequest, CancellationToken token)
            at NuGet.Commands.RestoreRunner.ExecuteAndCommitAsync(RestoreSummaryRequest summaryRequest, CancellationToken token)
            at NuGet.Commands.RestoreRunner.CompleteTaskAsync(List`1 restoreTasks)
            at NuGet.Commands.RestoreRunner.RunAsync(IEnumerable`1 restoreRequests, RestoreArgs restoreContext, CancellationToken token)
            at NuGet.Commands.RestoreRunner.RunAsync(RestoreArgs restoreContext, CancellationToken token)
            at NuGet.Build.Tasks.BuildTasksUtility.RestoreAsync(DependencyGraphSpec dependencyGraphSpec, Boolean interactive, Boolean recursive, Boolean noCache, Boolean ignoreFailedSources, Boolean disableParallel, Boolean force, Boolean forceEvaluate, Boolean hideWarningsAndErrors, Boolean restorePC, Boolean cleanupAssetsForUnsupportedProjects, ILogger log, CancellationToken cancellationToken)
            at NuGet.Build.Tasks.RestoreTask.ExecuteAsync(ILogger log)
       Done executing task "RestoreTask" -- FAILED.
     1>Done building target "Restore" in project "MySolution.sln" -- FAILED.
     1>Done Building Project "/home/vsts/work/1/s/MySolution/MySolution.sln" (Restore target(s)) -- FAILED.

Build FAILED.

       "/home/vsts/work/1/s/MySolution/MySolution.sln" (Restore target) (1) ->
       (Restore target) -> 


我的第一反应和大家一样...啊,路径肯定不对!然而...经过尝试各种不同的路径访问“packages”文件夹来获取本地NuGet包后,我似乎仍无法使其正常工作。

为了协助解决问题,以下是我的配置文件。

azure-pipelines.yml:

trigger:
- master

pool:
  vmImage: 'ubuntu-latest'

variables:
  buildConfiguration: 'Release'

steps:   
- task: NuGetToolInstaller@1
  displayName: 'Use NuGet 4.9.1'
  inputs:
    versionSpec: 4.9.1

- task: DotNetCoreCLI@2
  displayName: 'Restore NuGet Packages'
  inputs:
    command: 'restore'
    projects: '**/*.sln'
    feedsToUse: 'config'
    nugetConfigPath: 'MySolution/NuGet.Config'

- task: DotNetCoreCLI@2
  displayName: 'Build web project'
  inputs:
    command: 'build'
    projects: $(SolutionPath)
    

NuGet.Config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <packageSources>
        <clear />
        <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
        <add key="LocalPackages" value="MySolution/packages" />
    </packageSources>
</configuration>

我一直在尝试调整"LocalPackages"元素,但一直无法解决问题。我曾经尝试过各种路径组合来缩小范围,但都没有成功。这可能只是一个错误的线索,但也有可能是我做了什么愚蠢的事情。
我知道可以采用最佳实践,例如创建自己的NuGet软件包Artifacts feed以实现可维护性,但目前我的重点只是使流水线处于构建状态,以便进行部署和测试。
非常感谢您提供任何帮助或指导来解决这个问题。
如果需要更具体的信息,请告诉我。
谢谢。
1个回答

2

问题出在本地软件包路径上。您应该将值设置为:<add key="LocalPackages" value="../s/MySolution/packages" />

如果您检查dotnet restore任务日志,您会发现一个临时配置文件被创建,并且还要使用此临时配置文件来执行恢复任务。请参见下面的内容。

enter image description here

所以您在nuget.config文件中指定的本地软件包路径是相对于临时配置文件夹/home/vsts/work/1/Nuget的。

由于您的项目被克隆到文件夹/home/vsts/work/1/s(即$(system.defaultworkingdirectory)),因此您应该像下面这样指定本地软件包路径:

<add key="LocalPackages" value="../s/MySolution/packages" />


9
这不是解决方案,这只是一个临时方法。相对路径之所以存在是有原因的,建议别人根据可能随时更改该路径的虚拟构建系统来硬编码路径是错误的。而且这样做会破坏项目的本地构建。 - Krzaku

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接