我正在通过 Azure DevOps Pipelines 构建一个 .NET 6 项目。其中一个步骤是安装实体框架工具,以便后续步骤可以生成 SQL 迁移脚本。
但是,安装步骤失败并出现
401 Unauthorized
异常,即使该包似乎是在公共 nuget.org
源中找到的。由于指定了 --ignore-failed-sources
,即使私人提要无法找到包,至少有一次命中也应该标志着整个调用成功。
我什至尝试添加
--version 6.*
,因为该项目位于 .NET 6 中,但调用的总体结果保持不变。
为什么我会遇到异常?如何解决这个问题?
"C:\Program Files\dotnet\dotnet.exe" tool update --verbosity diagnostic --global --disable-parallel --version 6.* --ignore-failed-sources dotnet-ef
[NuGet Manager] [Info] GET https://api.nuget.org/v3/registration5-gz-semver2/dotnet-ef/index.json
[NuGet Manager] [Info] GET https://pkgs.dev.azure.com/<private>/_packaging/<private>/nuget/v3/registrations2-semver2/dotnet-ef/index.json
[NuGet Manager] [Info] GET https://nuget.<private>.com/v3/registration/dotnet-ef/index.json
[NuGet Manager] [Info] OK https://api.nuget.org/v3/registration5-gz-semver2/dotnet-ef/index.json 70ms
[NuGet Manager] [Info] GET https://api.nuget.org/v3/registration5-gz-semver2/dotnet-ef/page/0.0.1-alpha/3.1.28.json
[NuGet Manager] [Info] OK https://api.nuget.org/v3/registration5-gz-semver2/dotnet-ef/page/0.0.1-alpha/3.1.28.json 32ms
[NuGet Manager] [Info] Unauthorized https://pkgs.dev.azure.com/<private>/_packaging/<private>/nuget/v3/registrations2-semver2/dotnet-ef/index.json 149ms
[NuGet Manager] [Info] Unauthorized https://nuget.<private>.com/v3/registration/dotnet-ef/index.json 164ms
[NuGet Manager] [Info] GET https://api.nuget.org/v3/registration5-gz-semver2/dotnet-ef/page/3.1.29/6.0.23.json
[NuGet Manager] [Info] OK https://api.nuget.org/v3/registration5-gz-semver2/dotnet-ef/page/3.1.29/6.0.23.json 37ms
[NuGet Manager] [Info] GET https://api.nuget.org/v3/registration5-gz-semver2/dotnet-ef/page/6.0.24/9.0.0-preview.6.24327.4.json
[NuGet Manager] [Info] OK https://api.nuget.org/v3/registration5-gz-semver2/dotnet-ef/page/6.0.24/9.0.0-preview.6.24327.4.json 36ms
Unhandled exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 401 (Unauthorized).
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
at NuGet.Protocol.HttpSource.<>c__DisplayClass15_0`1.<<GetAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at NuGet.Common.ConcurrencyUtilities.ExecuteWithFileLockedAsync[T](String filePath, Func`2 action, CancellationToken token)
at NuGet.Common.ConcurrencyUtilities.ExecuteWithFileLockedAsync[T](String filePath, Func`2 action, CancellationToken token)
at NuGet.Protocol.HttpSource.GetAsync[T](HttpSourceCachedRequest request, Func`2 processAsync, ILogger log, CancellationToken token)
at NuGet.Protocol.PackageMetadataResourceV3.LoadRegistrationIndexAsync(HttpSource httpSource, Uri registrationUri, String packageId, SourceCacheContext cacheContext, Func`2 processAsync, ILogger log, CancellationToken token)
at NuGet.Protocol.PackageMetadataResourceV3.GetMetadataAsync(String packageId, Boolean includePrerelease, Boolean includeUnlisted, VersionRange range, SourceCacheContext sourceCacheContext, ILogger log, CancellationToken token)
at NuGet.Protocol.PackageMetadataResourceV3.GetMetadataAsync(String packageId, Boolean includePrerelease, Boolean includeUnlisted, SourceCacheContext sourceCacheContext, ILogger log, CancellationToken token)
at Microsoft.DotNet.Cli.NuGetPackageDownloader.NuGetPackageDownloader.GetPackageMetadataAsync(PackageSource source, String packageIdentifier, Boolean includePrerelease, Boolean includeUnlisted, CancellationToken cancellationToken)
at Microsoft.DotNet.Cli.NuGetPackageDownloader.NuGetPackageDownloader.GetMatchingVersionInternalAsync(String packageIdentifier, IEnumerable`1 packageSources, VersionRange versionRange, CancellationToken cancellationToken)
at Microsoft.DotNet.Cli.NuGetPackageDownloader.NuGetPackageDownloader.GetBestPackageVersionAsync(PackageId packageId, VersionRange versionRange, PackageSourceLocation packageSourceLocation)
at Microsoft.DotNet.Cli.ToolPackage.ToolPackageDownloader.<>c__DisplayClass8_0.<InstallPackage>b__0()
at Microsoft.DotNet.Cli.TransactionalAction.Run[T](Func`1 action, Action commit, Action rollback)
at Microsoft.DotNet.Tools.Tool.Install.ToolInstallGlobalOrToolPathCommand.<>c__DisplayClass20_0.<Execute>b__1()
at Microsoft.DotNet.Tools.Tool.Install.ToolInstallGlobalOrToolPathCommand.RunWithHandlingInstallError(Action installAction)
at Microsoft.DotNet.Tools.Tool.Install.ToolInstallGlobalOrToolPathCommand.Execute()
at Microsoft.DotNet.Tools.Tool.Update.ToolUpdateGlobalOrToolPathCommand.Execute()
at System.CommandLine.Invocation.InvocationPipeline.Invoke(ParseResult parseResult)
at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, TimeSpan startupTime, ITelemetry telemetryClient)
##[error]Error: The process 'C:\Program Files\dotnet\dotnet.exe' failed with exit code 1
Info: Azure Pipelines hosted agents have been updated and now contain .Net 5.x SDK/Runtime along with the older .Net Core version which are currently lts. Unless you have locked down a SDK version for your project(s), 5.x SDK might be picked up which might have breaking behavior as compared to previous versions. You can learn more about the breaking changes here: https://docs.microsoft.com/en-us/dotnet/core/tools/ and https://docs.microsoft.com/en-us/dotnet/core/compatibility/ . To learn about more such changes and troubleshoot, refer here: https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/build/dotnet-core-cli?view=azure-devops#troubleshooting
##[error]Dotnet command failed with non-zero exit code on the following projects : [ '' ]
Finishing: Install dotnet-ef
yml
文件摘录:
variables:
- name: BuildParameters.RestoreBuildProjects
value: '**/*.csproj'
- name: BuildParameters.TestProjects
value: '**/*[Tt]ests/*.csproj'
- name: BuildConfiguration
value: 'release'
trigger:
branches:
include:
- refs/heads/master
name: $(date:yyyyMMdd)$(rev:.r)
jobs:
- job: Job_1
displayName: Agent job 1
pool:
vmImage: windows-2022
steps:
- checkout: self
- task: DotNetCoreCLI@2
displayName: Restore
inputs:
command: 'restore'
projects: '$(BuildParameters.RestoreBuildProjects)'
feedsToUse: 'config'
nugetConfigPath: 'nuget.config'
externalFeedCredentials: 'Telerik NuGet source'
- task: DotNetCoreCLI@2
displayName: Build
inputs:
projects: $(BuildParameters.RestoreBuildProjects)
arguments: --configuration $(BuildConfiguration)
- task: DotNetCoreCLI@2
displayName: Test
enabled: False
inputs:
command: test
projects: $(BuildParameters.TestProjects)
arguments: --configuration $(BuildConfiguration)
- task: DotNetCoreCLI@2
displayName: Publish
inputs:
command: publish
publishWebProjects: True
projects: $(BuildParameters.RestoreBuildProjects)
arguments: --configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)
zipAfterPublish: True
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: drop'
condition: succeededOrFailed()
inputs:
TargetPath: '\\my\share\$(Build.DefinitionName)\$(Build.BuildNumber)'
- task: DotNetCoreCLI@2
displayName: Install dotnet-ef
inputs:
command: 'custom'
custom: 'tool'
arguments: 'update --verbosity diagnostic --global --disable-parallel --version 6.* --ignore-failed-sources dotnet-ef'
代理人自我身份证明:
Starting: Initialize job
Agent name: 'Hosted Agent'
Agent machine name: 'fv-az510-690'
Current agent version: '3.241.0'
Operating System
Microsoft Windows Server 2022
10.0.20348
Datacenter
Runner Image
Image: windows-2022
Version: 20240723.1.0
Included Software: https://github.com/actions/runner-images/blob/win22/20240723.1/images/windows/Windows2022-Readme.md
Image Release: https://github.com/actions/runner-images/releases/tag/win22%2F20240723.1
Runner Image Provisioner
2.0.373.1
Current image version: '20240723.1.0'
Agent running as: 'VssAdministrator'
任务的自我识别:
Starting: Install dotnet-ef
==============================================================================
Task : .NET Core
Description : Build, test, package, or publish a dotnet application, or run a custom dotnet command
Version : 2.242.0
Author : Microsoft Corporation
Help : https://docs.microsoft.com/azure/devops/pipelines/tasks/build/dotnet-core-cli
==============================================================================
C:\Windows\system32\chcp.com 65001
Active code page: 65001
如果当前工作目录中存在 NuGet 配置文件 (
nuget.config
),在其中运行命令“dotnet tool install
”或“dotnet tool update
”,该命令将使用 nuget.config
默认情况下为
文件。因此,该命令还将验证 nuget.config
文件中设置的包源(提要)的凭据。如果 nuget.config
文件设置了私有包源,则运行该命令时可能会收到 401 Unauthorized 错误。
要避免此问题,您可以尝试以下方法之一:
将命令的工作目录更改为另一个不包含任何
nuget.config
文件的目录。这样,任务就会在指定的目录下运行命令。指定的目录仅适用于当前 DotNetCoreCLI@2
任务,不能更改其他任务的工作目录。
- task: DotNetCoreCLI@2
displayName: 'dotnet custom'
inputs:
command: custom
custom: tool
arguments: 'install dotnet-ef --global --version 6.*'
workingDirectory: '$(Agent.BuildDirectory)'
NuGetAuthenticate@1
任务,运行命令“dotnet tool install
”或“dotnet tool update
”以生成可以访问私有包源的凭据。
- task: NuGetAuthenticate@1
displayName: 'NuGet Authenticate'
inputs:
nuGetServiceConnections: 'Connection_outsideFeed01, Connection_outsideFeed02'