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 }}
,但这只能静态命名,因为模板是在管道启动时编译的。
该解决方案的缺点是它在模板之间引入了隐藏的耦合。我更希望使用调用管道来协调模板之间传递的参数。
答案 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 on
和dependency 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
现在,您可以在第二个模板作业中看到成功获取值: