Azure Devops-在作业模板之间传递变量

时间:2019-11-25 19:09:22

标签: azure-devops azure-pipelines

Azure DevOps yaml中的常规(非模板)作业支持作业间变量传递,如下所示:

jobs:
- job: A
  steps:
  - script: "echo ##vso[task.setvariable variable=skipsubsequent;isOutput=true]false"
    name: printvar

- job: B
  condition: and(succeeded(), ne(dependencies.A.outputs['printvar.skipsubsequent'], 'true'))
  dependsOn: A
  steps:
  - script: echo hello from B

鉴于模板不支持dependsOn语法,我该如何执行以下类似操作?我需要从第一个模板获取输出,并将其作为“ environmentSlice”传递给第二个模板。

- stage: Deploy
  displayName: Deploy stage
  jobs:
  - template: build-templates/get-environment-slice.yml@templates
    parameters:
      configFileLocation: 'config/config.json'

  - template: build-templates/node-app-deploy.yml@templates
    parameters:
      # Build agent VM image name
      vmImageName: $(Common.BuildVmImage)
      environmentPrefix: 'Dev'
      environmentSlice: '-$(dependencies.GetEnvironmentSlice.outputs['getEnvironmentSlice.environmentSlice'])'

我希望将两个模板分开的原因是第二个模板是部署模板,因此我希望在第一个模板中命名环境时来自第一个模板的输入。即node-app-deploy.yml(第二个模板)的初始部分是:

  jobs:
  - deployment: Deploy
    displayName: Deploy
    # Because we use the environmentSlice to name the environment, we have to have it passed in rather than 
    # extracting it from the config file in steps below
    environment: ${{ parameters.environmentPrefix }}${{ parameters.environmentSlice }}

更新

公认的解决方案确实允许您在单独的模板之间传递变量,但不适用于我的特定用例。我希望能够动态命名第二个模板的“环境”部分,即environment: ${{ parameters.environmentPrefix }}${{ parameters.environmentSlice }},但这只能静态命名,因为模板是在管道启动时编译的。

该解决方案的缺点是它在模板之间引入了隐藏的耦合。我更希望使用调用管道来协调模板之间传递的参数。

2 个答案:

答案 0 :(得分:1)

可以避免被调用模板中的依赖。但是,正如 OP 所说,不能动态创建环境名称。

以下是“调用”模板的示例,它首先调用另一个模板(devops-variables.yml),该模板设置了一些我们希望在以后的模板(devops-callee.yml)中使用的环境变量:

stages:
- stage: 'Caller_Stage'
  displayName: 'Caller Stage'

  jobs:
  - template: 'devops-variables.yml'
    parameters:
      InitialEnvironment: "Development"

  - template: 'devops-callee.yml'
    parameters:
      SomeParameter: $[dependencies.Variables_Job.outputs['Variables_Job.Variables.SomeParameter']]

在 devops-variables.yml 文件中,我有这个:

"##vso[task.setvariable variable=SomeParameter;isOutput=true;]Wibble"

然后,在“devops-callee.yml”中,我只是像这样使用它:

  parameters:
  - name: SomeParameter
    default: ''

  jobs:
  - deployment: 'Called_Job'
    condition: succeeded()
    displayName: 'Called Job'
    environment: "Development"
    pool:
      vmImage: 'windows-2019'
    dependsOn:
    - Variables_Job
    variables:
      SomeParameter: ${{parameters.SomeParameter}}
    strategy:
      runOnce:
        deploy:
          steps:
          - download: none
          - task: AzureCLI@2
            condition: succeeded()
            displayName: 'An Echo Task'
            inputs:
              azureSubscription: "$(TheServiceConnection)"
              scriptType: pscore
              scriptLocation: inlineScript
              inlineScript: |
                echo "Before"
                echo "$(SomeParameter)"
                echo "After"

输出:

2021-04-10T09:22:29.6188535Z Before
2021-04-10T09:22:29.6196620Z Wibble
2021-04-10T09:22:29.6197124Z After

这样,被调用者就不会引用调用者。不幸的是,这样在被调用者中设置环境:

environment: "$(SomeParameter)"

不起作用 - 你只会得到一个带有文字字符“$(SomeParameter)”的环境。

答案 1 :(得分:0)

您可以将depend ondependency variable应用于模板。

请参见以下示例:

为了使示例更清晰,这里有2个模板文件,一个是azure-pipelines-1.yml,另一个是azure-pipeline-1-copy.yml

azure-pipelines-1.yml 中,将环境值指定为输出变量:

parameters:
  environment: ''
jobs:
- job: preDeploy
  variables:
    EnvironmentName: preDeploy-${{ parameters.environment }}
  steps:
  - checkout: none
  - pwsh: |
      echo "##vso[task.setvariable variable=EnvironmentName;isOutput=true]$($env:ENVIRONMENTNAME)"
    name: outputVars

然后,在 azure-pipeline-1-copy.yml 中,使用依赖关系获取此输出变量:

jobs:
- job: deployment
  dependsOn: preDeploy
  variables:
    EnvironmentNameCopy: $[dependencies.preDeploy.outputs['outputVars.EnvironmentName']]
  steps:
  - checkout: none
  - pwsh: |
      Write-Host "$(EnvironmentNameCopy)"
    name: outputVars

最后,在 YAML管道中,只需传递环境值

stages:
  - stage: deployQA
    jobs:
    - template: azure-pipelines-1.yml
      parameters:
        environment: FromTemplate1
    - template: azure-pipeline-1-copy.yml

现在,您可以在第二个模板作业中看到成功获取值:

enter image description here