Azure DevOps模板参数传递时变量未展开问题
问题现象
使用Azure DevOps Pipeline模板调用Azure CLI任务时,传递包含动态版本号的文件路径参数,模板执行时PowerShell报错:
VERSION : The term 'VERSION' is not recognized as a name of a cmdlet, function, script file, or executable program.
At
"the_path_to_version-$(VERSION).tar"
原因分析
Azure DevOps Pipeline的模板参数在编译阶段解析,而通过##vso[task.setvariable]生成的VERSION变量是运行阶段才会生成的值。编译阶段VERSION还未存在,因此参数中的$(VERSION)会被原封不动传入PowerShell脚本。PowerShell将$(...)识别为子表达式语法,尝试执行VERSION命令,最终触发错误。
解决方法
方法1:模板脚本直接引用管道变量
若路径仅版本号需动态替换,可修改模板,直接在脚本中引用VERSION变量,无需传递完整路径参数:
修改模板文件upload.yaml@templates:
parameters: - name: basePath type: string default: 'the_path_to_version-' steps: - task: AzureCLI@2 displayName: "Do The Thing" inputs: azureSubscription: MySubscription scriptType: pscore scriptLocation: inlineScript inlineScript: Write-Host "Do a thing with ${{ parameters.basePath }}$(VERSION).tar"
调用管道中传递基础路径:
- task: Bash@3 displayName: "Lookup version info" inputs: targetType: "inline" script: | VERSION=$(cat VERSION) echo "##[debug]Version is [$VERSION]." echo "##vso[task.setvariable variable=VERSION;isOutput=true]$VERSION" - template: upload.yaml@templates parameters: basePath: "the_path_to_version-"
方法2:转义参数中的$符号
通过转义$,让PowerShell在运行时解析变量:
修改调用管道的模板参数部分:
- template: upload.yaml@templates parameters: source: "the_path_to_version-`$(VERSION).tar"
编译阶段$会被转义为`$,传入PowerShell后恢复为$(VERSION),此时会被识别为Azure DevOps管道变量,正确替换为版本号。
方法3:使用运行时表达式传递参数
利用Azure DevOps的运行时表达式$[],直接在参数中引用运行时变量:
修改调用管道的模板参数部分:
- template: upload.yaml@templates parameters: source: "the_path_to_version-$([variables.VERSION]).tar"
该表达式会在运行阶段解析VERSION的值后传递给模板参数,避免编译阶段的占位符问题。
内容的提问来源于stack exchange,提问作者Cylindric

