Azure YAML中PowerShell输出变量无法跨阶段传递问题排查
问题:Azure Pipelines跨阶段变量传递失败
问题现象
从与azure-pipelines.yml同目录的.version文件提取major和minor版本号时,GetVersion阶段可正常输出变量值,但后续阶段出现异常:
BuildMasterVersion阶段构建号被更新为..8(major和minor变量为空)TagRelease阶段触发PowerShell错误:major : The term 'major' is not recognized as the name of a cmdlet...
错误信息
BuildMasterVersion阶段错误
The value is Async Command Start: Update Build Number Update build number to ..8 for build 14074 Async Command End: Update Build Number Finishing: PowerShell
TagRelease阶段错误
major : The term 'major' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At C:\grmn\prj\mrn\vsts-agent\_work\_temp\97b95723-b57c-451c-9e65-17cbecac17cf.ps1:3 char:20 + if ($(git tag -l $(major).$(minor).20)) { + ~~~~~ + CategoryInfo : ObjectNotFound: (major:String) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : CommandNotFoundException ##[error]PowerShell exited with code '1'. Finishing: PowerShell
原azure-pipelines.yml配置
pool: name: Marine-Server stages: - stage: GetVersion displayName: Get Major and Minor Version from .Version File jobs: - job: Get_Major_Minor_From_Version_File steps: - checkout: self - task: PowerShell@2 inputs: targetType: 'inline' script: | $version = Get-Content -Path .version -TotalCount 1 $versionSplit = $version.Split(".") $major = $versionSplit[0] $minor = $versionSplit[1] Write-Host ##vso[task.setvariable variable=major;isOutput=true]$major Write-Host "The value of major is $($major)" Write-Host ##vso[task.setvariable variable=minor;isOutput=true]$minor Write-Host "The value of minor is $($minor)" name: 'GetMajorMinorVersion' # # Versioning master branch builds - stage: BuildMasterVersion displayName: Build_Master_Version_Number #change to 'refs/head/master' or master when done testing condition: and(eq(variables['Build.SourceBranchName'], 'convert-to-commonjs-module-with-tags-implementation'), eq(variables['Build.Reason'], 'IndividualCI')) jobs: - job: Build_Master_Version_Number # variables: #patch: $[counter(variables['minor'], 0)] variables: major: $[stageDependencies.GetVersion.Get_Major_Minor_From_Version_File.outputs['GetMajorMinorVersion.major']] minor: $[stageDependencies.GetVersion.Get_Major_Minor_From_Version_File.outputs['GetMajorMinorVersion.minor']] semantic: $(major).$(minor) buildNum: $[counter(variables['semantic'], 0)] steps: - checkout: self - task: PowerShell@2 inputs: targetType: 'inline' script: | Write-Host "The value is $(major)" Write-Host "##vso[build.updatebuildnumber]$(major).$(minor).$(buildNum)" name: 'SetMasterBuildName' - stage: TagRelease # when done testing update branch to master condition: and(eq(variables['Build.SourceBranchName'], 'convert-to-commonjs-module-with-tags-implementation'), eq(variables['Build.Reason'], 'IndividualCI')) jobs: - job: Tag variables: semantic: $major.$minor buildNum: $[counter(variables['semantic'], 0)] workspace: clean: all # variables: # patch: $[counter(variables['minor'], 0)] steps: - checkout: self persistCredentials: true - task: PowerShell@2 inputs: targetType: 'inline' script: | if ($(git tag -l $(major).$(minor).$(buildNum))) { Write-Output "$(major).$(minor).$(buildNum) already released" } else { git tag $(major).$(minor).$(buildNum) git push origin $(major).$(minor).$(buildNum) } workingDirectory: $(Build.SourcesDirectory) displayName: 'Conditionally Tag'
修复方案
1. 补全TagRelease阶段的跨阶段变量引用
TagRelease阶段的Tag作业未定义从GetVersion阶段传递的major和minor变量,导致脚本无法解析这两个值,将其当作PowerShell命令执行报错。
修复: 在Tag作业的variables块中添加变量定义:
variables: major: $[stageDependencies.GetVersion.Get_Major_Minor_From_Version_File.outputs['GetMajorMinorVersion.major']] minor: $[stageDependencies.GetVersion.Get_Major_Minor_From_Version_File.outputs['GetMajorMinorVersion.minor']]
2. 修正变量引用语法错误
原TagRelease阶段中semantic: $major.$minor使用了错误的变量引用格式,Azure Pipelines中需用$(变量名)格式引用变量,而非$变量名。
修复: 将semantic定义改为:
semantic: $(major).$(minor)
3. 修复后的完整TagRelease阶段配置
- stage: TagRelease condition: and(eq(variables['Build.SourceBranchName'], 'convert-to-commonjs-module-with-tags-implementation'), eq(variables['Build.Reason'], 'IndividualCI')) jobs: - job: Tag variables: major: $[stageDependencies.GetVersion.Get_Major_Minor_From_Version_File.outputs['GetMajorMinorVersion.major']] minor: $[stageDependencies.GetVersion.Get_Major_Minor_From_Version_File.outputs['GetMajorMinorVersion.minor']] semantic: $(major).$(minor) buildNum: $[counter(variables['semantic'], 0)] workspace: clean: all steps: - checkout: self persistCredentials: true - task: PowerShell@2 inputs: targetType: 'inline' script: | $tagName = "$(major).$(minor).$(buildNum)" if (git tag -l $tagName) { Write-Output "$tagName already released" } else { git tag $tagName git push origin $tagName } workingDirectory: $(Build.SourcesDirectory) displayName: 'Conditionally Tag'
额外优化建议
在PowerShell脚本中,建议将流水线变量赋值给本地变量后再使用,避免多次解析可能出现的问题,同时提升代码可读性(如上述修复中使用$tagName变量)。
内容的提问来源于stack exchange,提问作者Sagufa Khanam
相关产品推荐
相关产品推荐

