如何获取Nuke.Build推送NuGet至Azure DevOps内部源的API密钥?
使用Nuke.Build推送NuGet包到Azure DevOps内部源的授权问题解决
问题描述
我尝试用Nuke.Build将NuGet包推送到Azure DevOps内部源。在Azure Pipelines中使用内置的经典视图或YAML步骤都能正常完成推送,这两种方式会自动依赖内部变量或令牌完成授权:
经典视图生成的推送步骤
steps: - task: DotNetCoreCLI@2 displayName: 'dotnet push' inputs: command: push publishVstsFeed: 'faeeeeee-eeee-eeee-eeee-c48a92cb3804/2a06fd96-0000-0000-0000-643ff5710000'
YAML生成的推送步骤
- task: NuGetCommand@2 inputs: command: 'push' packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg;!$(Build.ArtifactStagingDirectory)/**/*.symbols.nupkg' nuGetFeedType: 'internal' publishVstsFeed: 'faeeeeee-eeee-eeee-eeee-c48a92cb3804/2a06fd96-0000-0000-0000-643ff5710000'
但使用Nuke.Build的Publish步骤时,执行出现401未授权错误:
Target Publish => _ => _ .DependsOn(Pack) .Executes(() => { DotNetTasks.DotNetNuGetPush(x => x .SetApiKey("????") .SetSource("https://pkgs.dev.azure.com/company/project/_packaging/feed/nuget/v3/index.json") .SetTargetPath(PackagesDirectory)); });
error: Response status code does not indicate success: 401 (Unauthorized).
我想请教两个问题:
- 这个API密钥应该从哪里获取?
- 除了使用个人访问令牌(PAT),有没有办法从流水线中导入密钥,以非交互方式在Nuke.Build的Publish步骤中使用?
解决方案
1. API密钥的获取途径
除了PAT,你可以通过以下两种方式获取适用于Azure DevOps内部源的授权密钥:
- NuGet提要专属密钥:进入Azure DevOps项目的「项目设置」→「包」→「提要」,选中目标提要后点击「连接到提要」,在「NuGet CLI」选项卡下会生成一个仅限当前提要使用的推送密钥,这个密钥是项目范围的专用令牌。
- 流水线服务连接令牌:如果流水线已配置对应NuGet源的服务连接,Azure Pipelines会自动生成临时授权令牌,可通过流水线变量直接调用。
2. 流水线内非交互使用密钥的方法
在Azure Pipelines环境中运行Nuke.Build时,无需手动输入密钥,可直接利用流水线内置的系统变量实现授权:
方式一:读取$(System.AccessToken)环境变量
Azure Pipelines会为每个流水线运行生成临时系统访问令牌,拥有当前流水线的权限,可直接用于NuGet推送。修改Nuke.Build代码如下:
Target Publish => _ => _ .DependsOn(Pack) .Executes(() => { var accessToken = Environment.GetEnvironmentVariable("SYSTEM_ACCESSTOKEN"); DotNetTasks.DotNetNuGetPush(x => x .SetApiKey(accessToken) .SetSource("https://pkgs.dev.azure.com/company/project/_packaging/feed/nuget/v3/index.json") .SetTargetPath(PackagesDirectory)); });
注意:需在流水线的「代理作业」设置中勾选「允许脚本访问OAuth令牌」,否则无法获取该变量。
方式二:利用Nuke.Build的Azure Pipelines原生集成
Nuke.Build对Azure Pipelines有原生支持,可直接通过AzurePipelines类获取系统令牌:
Target Publish => _ => _ .DependsOn(Pack) .Executes(() => { DotNetTasks.DotNetNuGetPush(x => x .SetApiKey(AzurePipelines.Instance.Environment.SystemAccessToken) .SetSource("https://pkgs.dev.azure.com/company/project/_packaging/feed/nuget/v3/index.json") .SetTargetPath(PackagesDirectory)); });
这种方式无需手动读取环境变量,Nuke会自动处理流水线上下文的变量获取。
也可以在流水线YAML中,将令牌作为环境变量传递给Nuke的执行步骤:
- script: ./build.cmd Publish env: SYSTEM_ACCESSTOKEN: $(System.AccessToken)
内容的提问来源于stack exchange,提问作者tridy
相关产品推荐
相关产品推荐

