Azure Pipeline中基于目录更新条件运行模板的问题排查
问题
我想在Azure Pipeline中根据提交记录是否更新特定目录,条件运行Terraform模板,但两种配置都失败了:
配置1:同一Job内使用${{ if }}表达式,变量始终判定为false
- stage: Provision_Central_Techops dependsOn: [] displayName: Provision Central Techops jobs: - job: Provision_TechOps_Central_Stack displayName: Provision TechOps Central Stack variables: workingDirectory: terraform/stacks/techops steps: - bash: | echo workingDirectory $(workingDirectory) if git diff-tree --no-commit-id --name-only -r HEAD | grep -q $(workingDirectory); then echo "##vso[task.setvariable variable=techopsUpdated]true" else echo "##vso[task.setvariable variable=techopsUpdated]false" fi name: Check_For_Update - ${{ if eq(variables.techopsUpdated, true) }}: - template: steps/terraform.yml parameters: environment: prod workingDirectory: $(workingDirectory) stackName: techops terraformVersion: $(terraformVersion) - ${{ else }}: - script: echo "techopsUpdated $(techopsUpdated)"
配置2:拆分Job后,条件判断时输出变量为null
- stage: Provision_Central_Techops dependsOn: [] displayName: Provision Central Techops jobs: - job: Provision_TechOps_Central_Stack1 displayName: Provision TechOps Central Stack variables: workingDirectory: terraform/stacks/techops steps: - bash: | echo workingDirectory $(workingDirectory) if git diff-tree --no-commit-id --name-only -r HEAD | grep -q $(workingDirectory); then echo "##vso[task.setvariable variable=techopsUpdated; isOutput=true]true" else echo "##vso[task.setvariable variable=techopsUpdated; isOutput=true]false" fi name: Check_For_Update - job: Provision_TechOps_Central_Stack condition: eq(variables.techopsUpdated , true) displayName: Provision TechOps Central Stack variables: workingDirectory: terraform/stacks/techops steps: - template: steps/terraform.yml parameters: environment: prod workingDirectory: $(workingDirectory) stackName: techops terraformVersion: $(terraformVersion)
原因分析与修复方案
针对配置1的问题
${{ if }}是编译时表达式,Azure Pipeline会在运行前就解析这个表达式,但你通过bash任务设置的techopsUpdated是运行时变量,编译阶段这个变量还未生成,所以表达式会默认判定为false。
修复方法:把编译时的${{ if }}替换为运行时的condition参数,给步骤添加动态条件判断:
- stage: Provision_Central_Techops dependsOn: [] displayName: Provision Central Techops jobs: - job: Provision_TechOps_Central_Stack displayName: Provision TechOps Central Stack variables: workingDirectory: terraform/stacks/techops steps: - bash: | echo workingDirectory $(workingDirectory) if git diff-tree --no-commit-id --name-only -r HEAD | grep -q $(workingDirectory); then echo "##vso[task.setvariable variable=techopsUpdated]true" else echo "##vso[task.setvariable variable=techopsUpdated]false" fi name: Check_For_Update - template: steps/terraform.yml condition: eq(variables.techopsUpdated, 'true') parameters: environment: prod workingDirectory: $(workingDirectory) stackName: techops terraformVersion: $(terraformVersion) - script: echo "techopsUpdated $(techopsUpdated)" condition: ne(variables.techopsUpdated, 'true')
针对配置2的问题
你缺少两个关键配置:第二个Job未依赖第一个Job,且未正确引用前一个Job的输出变量。
修复后的配置:
- stage: Provision_Central_Techops dependsOn: [] displayName: Provision Central Techops jobs: - job: Check_TechOps_Update displayName: Check if TechOps directory is updated variables: workingDirectory: terraform/stacks/techops steps: - bash: | echo workingDirectory $(workingDirectory) if git diff-tree --no-commit-id --name-only -r HEAD | grep -q $(workingDirectory); then echo "##vso[task.setvariable variable=techopsUpdated; isOutput=true]true" else echo "##vso[task.setvariable variable=techopsUpdated; isOutput=true]false" fi name: Check_For_Update - job: Provision_TechOps_Central_Stack dependsOn: Check_TechOps_Update condition: eq(variables.techopsUpdated, 'true') displayName: Provision TechOps Central Stack variables: workingDirectory: terraform/stacks/techops techopsUpdated: $[ dependencies.Check_TechOps_Update.outputs['Check_For_Update.techopsUpdated'] ] steps: - template: steps/terraform.yml parameters: environment: prod workingDirectory: $(workingDirectory) stackName: techops terraformVersion: $(terraformVersion)
注意:输出变量的值为字符串类型,所以条件判断中要使用'true'而非布尔值true。
内容的提问来源于stack exchange,提问作者Nicholas Namacha
相关产品推荐
相关产品推荐

