如何将变量传递给 YAML 管道中任务条件的模板

How to pass variables to templates for task conditions in YAML pipeline

我有一个处理多个 Azure 函数部署的 YAML 模板:

parameters:
  azureSubscription: ''
  services: []

steps:
- ${{ each service in parameters.services }}:
  - task: AzureRmWebAppDeployment@4
    displayName: Deploy Azure Function ${{ service.name }}
    inputs:
      ConnectionType: 'AzureRM'
      azureSubscription: '${{ parameters.azureSubscription }}'
      appType: 'functionApp'
      WebAppName: '${{ service.webAppName }}'
      packageForLinux: '${{ service.packagePath }}'

在主管道中,我非常简单地调用模板,传递一组函数和所需的参数:

# Deploy Azure Functions
- template: ../Deploy/deploy-azure-functions.yml
  parameters:
    azureSubscription: 'XXX'
    services:
    - service: 
      name: 'Func 1'
      webAppName: 'func1'
      packagePath: 'Func1.zip'
    - service: 
      name: 'Func 2'
      webAppName: 'func2'
      packagePath: 'Function2.zip'

现在一切正常,因为所有功能都需要部署。但是,当某个条件(我只在运行时理解)有效时,我需要排除功能 2。

我举个例子。假设在部署所有 Azure 函数之前,我有一个创建变量的 PowerShell 脚本:

- pwsh: | 
    # Do some calculation and determine whether to proceed with deployment
    Write-Host "##vso[task.setvariable variable=DEPLOY;]$deploymentEnabled"
  displayName: 'Set dynamic variable'

现在我在变量 $(DEPLOY) 中输入了一个值(true 或 false),指示我是否可以部署某个功能。然后我希望在模板中传递值,例如:

# Deploy Azure Functions
- template: ../Deploy/deploy-azure-functions.yml
  parameters:
    azureSubscription: 'XXX'
    services:
    - service: 
      name: 'Func 1'
      webAppName: 'func1'
      packagePath: 'Func1.zip'
    - service: 
      name: 'Func 2'
      webAppName: 'func2'
      packagePath: 'Function2.zip'
      deploy: $(DEPLOY)

请注意 deploy 参数只是为 Function 2 添加的,因为我需要始终部署 Function 1 并且我希望这是一个可选参数,这样当它被省略时,就会进行部署。

现在我必须将模板更改为:

- ${{ each service in parameters.services }}:
 - task: AzureRmWebAppDeployment@4
   displayName: Deploy Azure Function ${{ service.name }}
   condition: or(eq('${{ service.deploy }}', ''), eq('${{ service.deploy }}', 'true')) 
   inputs:
     ConnectionType: 'AzureRM'
     azureSubscription: '${{ parameters.azureSubscription }}'
     appType: 'functionApp'
     WebAppName: '${{ service.webAppName }}'
     packageForLinux: '${{ service.packagePath }}'

注意条件:如果参数 'deploy' 的值未设置或值为 'true',则应进行部署,否则应跳过。

虽然我想说的很直接,但事实并非如此,因为变量没有被求值,而是作为字符串传递(我想模板求值首先出现)。有没有办法让它工作?

作为解决方法,我们可以在现场部署中使用条件,然后将参数传递给模板。

示例脚本:

YAML 构建定义:

trigger: none

variables:
    test: "true"
steps:
  - pwsh: | 
      # Do some calculation and determine whether to proceed with deployment
      Write-Host "##vso[task.setvariable variable=DEPLOY;]true"
    displayName: 'Set dynamic variable'

  - template: Template.yml
    parameters:
      azureSubscription: 'XXX'
      services:
      - service: 
        name: 'Func 1'
        webAppName: 'func1'
        packagePath: 'Func1.zip'
      - service: 
        name: 'Func 2'
        webAppName: 'func2'
        packagePath: 'Function2.zip'
        deploy: eq(variables['DEPLOY'], true)

Template.yml

parameters:
  azureSubscription: ''
  services: []
steps:
- ${{ each service in parameters.services }}:
  - task: PowerShell@2
    displayName: ${{ service.name }}
    condition: ${{ service.deploy }}
    inputs:
      targetType: 'inline'
      script: |
        Write-Host "The value of DEPLOY is: " $($env:DEPLOY)
        #Write-Host "The value of DEPLOY is: " ${{ service.deploy }}

结果:

将 DEPLOY 值设置为 true:

将 DEPLOY 值设置为 false: