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

问题描述

尝试通过 YAML 管道中的 Azure DevOps 任务动态检索变量组中的所有变量。最初尝试通过以下代码利用 AzureCLI@2 任务来检索用于获取其中变量的 variableGroupID:

$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

我打开了一个issue

与此同时,我尝试运行 commands to install the necessary pieces via scripts

   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.

我已经打开了一个 issue with the documentation team,因为至少提供的步骤不起作用。任何帮助将不胜感激!

解决方法

您可以使用 REST API 而不是 Azure CLI 来获取信息。它可以与 Microsoft 托管代理上已有的标准工具一起使用。它只需要 vanilla powershell 或 powershell core,这意味着可以在 windows 和 linux 代理上运行。以下示例已在 windows-latest/windows-2019ubuntu-latest/ubuntu-20.04

上成功测试

该方法与 Azure CLI 相同。

  1. List all available groups 按名称过滤以检索相关变量组
  2. Get all variables in the variable group 使用步骤中的变量组 ID

事实上,管道还有一个开箱即用的 PAT 令牌,可用于读取变量组。它存储在变量 System.AccessToken 中。使用它而不是手动管理的将进一步简化事情。

下面的脚本在pwsh步骤中执行,也就是Powershell核心模式下的built in Powershell task

- 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"
  }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...