【问题标题】:Azure Devops - passing variables between job templatesAzure Devops - 在作业模板之间传递变量
【发布时间】:2019-11-25 19:09:22
【问题描述】:

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'])'

我希望将两个模板分开的原因是第二个模板是部署模板,我想从第一个模板输入第二个模板中的环境命名。 IE。 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 }},但这只能静态命名,因为模板是在管道启动时编译的。

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

【问题讨论】:

标签: azure-devops azure-pipelines


【解决方案1】:

您可以将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

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

【讨论】:

  • 嗨梅林,感谢您将这些放在一起。我没有意识到您可以在不同模板中表达作业之间的依赖关系。缺点是模板之间存在隐藏的耦合。对我来说不幸的是,这个解决方案不适用于我的用例。模板的环境部分只能使用模板参数命名,因为它是在作业启动而不是运行时编译的。很遗憾,因为我想动态命名我的环境,但看起来缺少该功能。我会将您的答案标记为已接受并添加警告。
  • 我有类似的要求,在我的情况下,第一个模板提供环境 - 天蓝色资源的名称是动态构建的。在稍后部署模板应用程序时,需要传递动态构造的资源名称的输出。 @Merlin 提供的解决方案确实解决了这个问题,但是,它创建了一个隐藏的依赖关系,最好避免这种依赖关系。谢谢。
【解决方案2】:

可以避免调用模板中的依赖。但是,正如 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)”的环境。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-29
    • 1970-01-01
    • 2017-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多