简体   繁体   English

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

[英]Azure Devops - passing variables between job templates

Normal (non-template) jobs in Azure DevOps yaml support inter-job variable passing as follows: 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

How do I do something similar in the following, given that templates don't support the dependsOn syntax?鉴于模板不支持dependsOn语法,我如何在下面做类似的事情? I need to get an output from the first template and pass it as 'environmentSlice' to the second template.我需要从第一个模板获取输出并将其作为“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'])'

The reason I want the separation between the two templates is the second one is a deployment template and I would like input from the first template in naming the environment in the second template.我希望将两个模板分开的原因是第二个模板是部署模板,我希望在命名第二个模板中的环境时从第一个模板输入。 Ie initial part of node-app-deploy.yml (2nd template) is:即 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 }}

Update:更新:

The accepted solution does allow you to pass variables between separate templates, but won't work for my particular use case.接受的解决方案确实允许您在单独的模板之间传递变量,但不适用于我的特定用例。 I wanted to be able to name the 'environment' section of the 2nd template dynamically, ie environment: ${{ parameters.environmentPrefix }}${{ parameters.environmentSlice }} , but this can only be named statically since templates are compiled on pipeline startup.我希望能够动态命名第二个模板的“环境”部分,即environment: ${{ parameters.environmentPrefix }}${{ parameters.environmentSlice }} ,但这只能静态命名,因为模板是在管道启动。

The downside of the solution is that it introduces a hidden coupling between the templates.该解决方案的缺点是它在模板之间引入了隐藏的耦合。 I would have preferred the calling pipeline to orchestrate the parameter passing between templates.我更喜欢调用管道来协调模板之间的参数传递。

You can apply the depend on and dependency variable into templates.您可以将depend ondependency variable到模板中。

See below sample:请参阅以下示例:

To make sample more clear, here has 2 template files, one is azure-pipelines-1.yml , and another is azure-pipeline-1-copy.yml .为了让示例更清楚,这里有 2 个模板文件,一个是azure-pipelines-1.yml ,另一个是azure-pipeline-1-copy.yml

In azure-pipelines-1.yml , specify the environment value as output variable: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

And then, in azure-pipeline-1-copy.yml use dependency to get this output variable:然后,在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

At last, in YAML pipeline , just need to pass the environment value最后,在YAML 管道中,只需要传递环境值

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

Now, you can see the value get successfully in the second template job:现在,您可以在第二个模板作业中看到该值成功获取:

在此处输入图片说明

It is possible to avoid the dependency in the called template.可以避免在所谓的模板的依赖。 However, as the OP says, the environment name cannot be created dynamically.但是,正如 OP 所说,不能动态创建环境名称。

Here is an example of the "calling" template, which firstly calls another template (devops-variables.yml) that sets some environment variables that we wish to consume in a later template (devops-callee.yml):这是“调用”模板的示例,它首先调用另一个模板(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']]

In the devops-variables.yml file, I have this:在 devops-variables.yml 文件中,我有这个:

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

Then, in the "devops-callee.yml", I just consume it something like this:然后,在“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"

Output:输出:

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

This way, the callee doesn't reference the caller.这样,被调用者就不会引用调用者。 Unfortunately, setting the environment in the callee thus:不幸的是,因此在被调用者中设置环境:

environment: "$(SomeParameter)"

doesn't work - you'll just get an environment with the literal characters '$(SomeParameter)'.不起作用 - 你只会得到一个带有文字字符“$(SomeParameter)”的环境。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM