无法在Azure DevOps任务中运行az管道命令

4

在YAML Pipeline中通过Azure DevOps任务动态检索变量组中的所有变量。最初尝试使用AzureCLI@2任务并使用以下代码检索variableGroupID,该ID将用于获取其中的变量:

$variableGroupId = $(az pipelines variable-group list --org $(System.CollectionUri) --project $(System.TeamProject) --query "[?name=='{{ parameters.variableGroupName }}'].id" -o tsv)

这个命令在本地运行正常,但在像这样的MS托管代理上执行时不起作用:

parameters:
  variableGroupName: ''

steps:
- task: AzureCLI@2
  displayName: Azure CLI
  inputs:
    azureSubscription: ${{ parameters.azureSubscriptionName }}
    scriptType: pscore
    scriptLocation: inlineScript
    inlineScript: |
      az upgrade
      $variableGroupId = $(az pipelines variable-group list --org $(System.CollectionUri) --project $(System.TeamProject) --query "[?name=='{{ parameters.variableGroupName }}'].id" -o tsv)
      write-Host $variableGroupId
      $variables = $(az pipelines variable-group variable list --group-id $variableGroupId  --org $(System.CollectionUri)  --project $(System.TeamProject) -o yaml)
      write-Host $variables

这会产生以下错误:

Before you can run Azure DevOps commands, you need to run the login command (az login if using AAD/MSA identity else az devops login if using PAT token) to setup credentials. Please see https://aka.ms/azure-devops-cli-auth for more information

我已经打开了一个问题

同时,我尝试运行命令通过脚本安装必要的组件

   strategy:
      runOnce:
        deploy:
          steps:
          - task: AzureRmWebAppDeployment@3
            inputs:
              azureSubscription: Example - Dev
              WebAppName: wapp-Example-dev-eus
              Package: $(Pipeline.Workspace)/drop/Web.Example.zip
              TakeAppOfflineFlag: True
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.x'
              architecture: 'x64'
          - task: CmdLine@2
            displayName: 'Upgrade pip'
            inputs:
              script: python -m pip install --upgrade pip
          - task: CmdLine@2
            displayName: 'upgrade azure cli'
            inputs:
              script: pip install --pre azure-cli --extra-index-url https://azurecliprod.blob.core.windows.net/edge
          - task: CmdLine@2
            displayName: 'Show Azure CLI version'
            inputs:
              script: az --version
          - task: CmdLine@2
            displayName: 'Install Azure DevOps Extension'
            inputs:
              script: az extension add -n azure-devops
          - task: CmdLine@2
            env:
              AZURE_DEVOPS_CLI_PAT: $(patCredential)
            displayName: 'Login Azure DevOps Extension'
            inputs:
              script: echo ${AZURE_DEVOPS_CLI_PAT} | az devops login
          - task: CmdLine@2
            displayName: 'Show List of Variables'
            inputs:
              script: |
                $variableGroupId = $(az pipelines variable-group list --org $(System.CollectionUri) --project $(System.TeamProject) --query "[?name=='{{ parameters.variableGroupName }}'].id" -o tsv)
                write-Host $variableGroupId
                $variables = $(az pipelines variable-group variable list --group-id $variableGroupId  --org $(System.CollectionUri)  --project $(System.TeamProject) -o yaml)
                write-Host $variables

然而,当使用最新的Ubuntu代理和文档中指定的代理时,会出现错误:
WARNING: Failed to store PAT using keyring; falling back to file storage.
WARNING: You can clear the stored credential by running az devops logout.
WARNING: Refer https://aka.ms/azure-devops-cli-auth to know more on sign in with PAT.

我已经向文档团队提出了问题,至少提供的步骤无法正常工作。非常感谢您的任何帮助!

同意@wallezzi的观点,我们建议您部署自托管代理,这样可以更好地控制安装构建和部署所需的依赖软件。在流水线中使用自托管代理将在您的本地构建环境上进行构建。 - Edward Han-MSFT
1
不确定这一点,我不应该运行自托管代理来运行本机的Azure CLI命令和扩展。此外,自托管代理不是一个可能性。 - DreadedFrost
看起来你已经在这里找到了一个解决方法:https://developercommunity.visualstudio.com/solutions/1337250/view.html,如果你在stackoverflow上分享你的解决方法并[标记它](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work/5235#5235),那会更好,这将帮助其他遇到相同问题的社区成员,非常感谢。 - Edward Han-MSFT
@EdwardHan-MSFT 请注意下面已经发布的评论。这个解决方法最初是在stackoverflow上被发现的,并且社区票据已经更新以反映这一点。 - DreadedFrost
2个回答

4
我遇到了同样的错误,通过添加以下代码,我成功地解决了这个问题:
echo $(System.AccessToken) | az devops login

将我的内联脚本移到顶部。这是它的样子:

  variables:
    variableGroupName: 'my-variable-group'
    ...

          - task: AzureCLI@2
            displayName: 'Set environment variables'
            inputs:
              azureSubscription: '$(azureSubscription)'
              scriptType: 'pscore'
              scriptLocation: 'inlineScript'
              inlineScript: |
                echo $(System.AccessToken) | az devops login

                $groupId = (az pipelines variable-group list `
                --organization $(System.CollectionUri) `
                --project $(System.TeamProject) `
                --group-name $(variableGroupName) | ConvertFrom-Json).id
                
                ...

3
您可以使用 REST API 而不是 Azure CLI 来获取信息。它可以与 Microsoft 托管代理上已有的标准工具一起使用。它仅需要普通的 PowerShell 或 PowerShell Core,这意味着它可以在 Windows 和 Linux 代理上运行。下面的示例已经在 windows-latest/windows-2019ubuntu-latest/ubuntu-20.04 上成功测试过。
方法与 Azure CLI 相同。
  1. 通过名称筛选列出所有可用的群组,以检索所需的变量组。
  2. 使用步骤中的变量组 ID 获取变量组中的所有变量

事实上,管道还具有一个开箱即用的 PAT 令牌,具有对变量组的读取访问权限。它存储在变量{{link3:System.AccessToken}}中。使用它而不是手动管理的令牌将进一步简化事情。

以下脚本在 pwsh 步骤中执行,这是 Powershell 核心模式下的 内置 Powershell 任务
- pwsh: |
    # Construct PAT authentication header
    $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "user",$env:SYSTEM_ACCESSTOKEN)))
    $headers = @{Authorization=("Basic {0}" -f $base64AuthInfo)}
    
    # Retrieve variable group id. Filter the result by setting the groupName query parameter
    $variableGroupId = $(Invoke-RestMethod -Headers $headers "$(System.CollectionUri)$(System.TeamProject)/_apis/distributedtask/variablegroups?groupName=${{ parameters.variableGroupName }}&api-version=6.0-preview.2").value[0].id
    
    # Retrieve variables in variable group with id $variableGroupId
    $variables = $(Invoke-RestMethod -Headers $headers "$(System.CollectionUri)$(System.TeamProject)/_apis/distributedtask/variablegroups/${variableGroupId}?api-version=6.0-preview.2").variables
    
    #Print variables as json (for demo purpose)
    $variables | ConvertTo-Json
  env:
    SYSTEM_ACCESSTOKEN: $(System.AccessToken)
  displayName: 'Retrieve variables'

在一个包含两个变量的变量组项目中测试上述管道将产生以下输出:
{
  "Variable 1": {
    "value":  "Value 1"
  },
  "Variable 2": {
    "value":  "Value 2"
  }
}

谢谢,我没有想到过这个!!我会尝试一下并回复你。我确实使用了系统提供的一个,但那也导致了钥匙串失败。 - DreadedFrost
我希望这可以在Ubuntu上运行。话虽如此,我确实让它工作了,但需要对提供的答案进行调整。{{ parameters.variableGroupName }}无法读取YAML值。最终,我能够将其从参数更改为任务模板中调用作业的变量,然后执行groupName=$env:variableGroupName - DreadedFrost
它也可以在Ubuntu上运行(如果您使用任务的PowerShell Core版本(pwsh而不是powershell))。我已经更新了我的答案。您甚至可以编写一个版本的bash,使用类似于“curl”和“jq”的东西来调用API并解析响应,如果您因某种原因更喜欢这样做而不是PowerShell。但是使用PowerShell Core的好处是它可以在Linux和Windows上无需修改即可工作。 - danielorn
参数问题可能是回复中的拼写错误,应该是${{ parameters.variableGroupName }}而不是{{ parameters.variableGroupName }}(现已更新)。然而,由于您没有发布完整的yaml文件,很难就variableGroupName提供建议。但正如您所说,您可以使用参数或变量,但它们具有略微不同的语法:https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#understand-variable-syntax - danielorn
是的,在Linux上它确实起作用了,谢谢。我也更新了社区工单,以引用这个解决方法。感谢您的帮助。 - DreadedFrost
显示剩余2条评论

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