如何正确为Azure Pipeline YAML中的阶段添加条件?
问题:Azure流水线第二阶段条件判断失效
- 现有基于代码仓库创建Chocolatey包的Azure流水线,第一阶段负责创建包、检查包生成状态并复制nupkg文件到目标目录,功能正常。
- 第二阶段需仅在文件成功生成时执行Vagrant测试,但添加条件后该阶段每次被跳过;移除条件则能正常启动并输出"test"。
原流水线YAML片段:
variables: solution: *****' buildConfiguration: 'Release' buildPlatform: 'Any CPU' chocoSource: ***** localChocoFolder: '.\chocolateypack' binaryInputFolder: ***** localFolder: '$(Build.SourcesDirectory)\Package' dropFolder: ***** vagrantDropFolder: ***** fileExists: true stages: - stage: BuildCommands displayName: Build Commands stage jobs: - job: BuildCommands timeoutInMinutes: 120 displayName: Build commands job pool: name: 'Bugzing' ***** ***** ***** ***** ***** - task: PowerShell@2 displayName: 'Check for existing files in target folder' inputs: targetType: 'inline' script: | # Access pipeline variables $localFolder = "${env:localFolder}" $dropFolder = "${env:dropFolder}" # Get the list of local files $localFiles = Get-ChildItem -Path $localFolder -Recurse -File foreach ($localFile in $localFiles) { $relativePath = $localFile.FullName.Substring($localFolder.Length) $targetFilePath = Join-Path $dropFolder $relativePath if (Test-Path $targetFilePath) { Write-Host "##vso[task.logissue type=warning]File already exists in target folder: $targetFilePath" Write-Host "##vso[task.complete result=SucceededWithIssues;]" exit 0 } } Write-Host "##vso[task.setvariable variable=fileExists]false" - task: CopyFiles@2 condition: and (succeeded(), eq(variables['fileExists'], 'false')) displayName: 'Copy installer' inputs: SourceFolder: '$(localFolder)' Contents: '**' TargetFolder: '$(dropFolder)' - stage: VagrantTest displayName: Test Package With Vagrant dependsOn: BuildCommands condition: and(succeeded(), eq(dependencies.BuildCommands.outputs['BuildCommands.fileExists'], 'false')) jobs: - job: BuildCommands timeoutInMinutes: 120 displayName: Build commands job pool: name: 'Bugzing' steps: - task: PowerShell@2 displayName: stage 2 echo test inputs: targetType: 'inline' script: | echo "test"
问题原因
第一阶段中通过##vso[task.setvariable]设置的fileExists变量默认是作业级私有变量,未标记为输出变量,导致第二阶段无法读取该变量的更新值,始终使用初始定义的true,因此条件判断不成立,阶段被跳过。
解决方案
1. 修改第一阶段的PowerShell任务,标记变量为输出变量
给PowerShell任务添加name属性,并在设置变量时加上isOutput=true:
- task: PowerShell@2 name: check_files # 添加任务名称,用于后续引用输出 displayName: 'Check for existing files in target folder' inputs: targetType: 'inline' script: | # Access pipeline variables $localFolder = "${env:localFolder}" $dropFolder = "${env:dropFolder}" # Get the list of local files $localFiles = Get-ChildItem -Path $localFolder -Recurse -File foreach ($localFile in $localFiles) { $relativePath = $localFile.FullName.Substring($localFolder.Length) $targetFilePath = Join-Path $dropFolder $relativePath if (Test-Path $targetFilePath) { Write-Host "##vso[task.logissue type=warning]File already exists in target folder: $targetFilePath" Write-Host "##vso[task.complete result=SucceededWithIssues;]" exit 0 } } # 设置为输出变量,允许跨阶段引用 Write-Host "##vso[task.setvariable variable=fileExistsOutput;isOutput=true]false"
2. 在第一阶段的作业中定义输出变量映射
给第一阶段的作业添加outputs,将步骤的输出变量映射为作业级输出:
- job: BuildCommands timeoutInMinutes: 120 displayName: Build commands job pool: name: 'Bugzing' outputs: # 将check_files步骤的fileExistsOutput输出映射为作业的fileExists输出 fileExists: $[steps.check_files.outputs.fileExistsOutput]
3. 保持第二阶段的条件判断不变
原第二阶段的条件引用格式正确,修改后即可读取到正确的变量值:
- stage: VagrantTest displayName: Test Package With Vagrant dependsOn: BuildCommands condition: and(succeeded(), eq(dependencies.BuildCommands.outputs['BuildCommands.fileExists'], 'false')) jobs: - job: BuildCommands timeoutInMinutes: 120 displayName: Build commands job pool: name: 'Bugzing' steps: - task: PowerShell@2 displayName: stage 2 echo test inputs: targetType: 'inline' script: | echo "test"
验证
修改后,当第一阶段的PowerShell任务成功设置fileExistsOutput为false时,第二阶段会读取到该值,满足条件后正常执行;如果目标目录已有文件,fileExists保持初始的true,第二阶段会被跳过。
内容的提问来源于stack exchange,提问作者M. Bence
相关产品推荐
相关产品推荐

