英文:
AzureDevops pipeline task with condition not evaluated correctly
问题
以下是翻译好的内容:
我有一个管道,用来检查提交是否有标签,以及该标签是否是版本标签(意思是像'v1.0.0'或'v01.00.00'这样)。
我的问题是,当我将正则表达式操作的结果保存在变量中时,它似乎首先是“True”,但在第二个任务的“condition”中使用时突然变为“False”。
以下是管道:
# 启动管道
# 从一个最小的管道开始,您可以自定义以构建和部署您的代码。
# 添加构建、运行测试、部署等步骤:
# https://aka.ms/yaml
trigger:
branches:
include:
- master
tags:
include:
- "*"
pool:
vmImage: windows-latest
variables:
hasTags: $[contains(variables['Build.SourceBranch'], 'refs/tags/')]
isVersionTag: 'False'
versionTag: ''
steps:
- task: PowerShell@2
condition: eq(variables.hasTags, 'True')
inputs:
targetType: 'inline'
script: |
# 从SourcheBranch获取标签
$dummy = $Env:Build_SourceBranch
$regex = "(refs)/(tags)/(?<version_tag>.+)$"
$result = [regex]::Matches($dummy, $regex)
$Env:versionTag = $result[0].Groups["version_tag"].Value
# 检查标签是否实际上是一个版本(例如'v1.0.1')
$regex = "v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$"
$Env:isVersionTag = [regex]::IsMatch($Env:versionTag, $regex)
if($Env:isVersionTag -eq 'True')
{
Write-Host '它是一个版本标签'
}
Write-Host "变量 Build.SourceBranch = $Env:Build_SourceBranch"
Write-Host "变量 isVersionTag = $Env:isVerionTag"
Write-Host "变量 hasTags = $Env:hasTags"
Write-Host "变量 versionTag = $Env:versionTag"
# 这不会运行,因为条件被评估为以下内容:
# 评估:and(eq(variables['hasTags'], 'True'), eq(variables['isVersionTag'], 'True'))
# 扩展:and(eq('True', 'True'), eq('False', 'True'))
# 结果:False
- task: PowerShell@2
condition: and(eq(variables.hasTags, 'True'), eq(variables.isVersionTag, 'True'))
inputs:
targetType: 'inline'
script: |
# 在此处编写您的PowerShell命令。
Write-Host "该标签是一个版本标签"
上述管道的Write-Host
输出如下:
它是一个版本标签
变量 Build.SourceBranch = refs/tags/v02.01.07
变量 isVersionTag =
变量 hasTags = True
变量 versionTag = v02.01.07
英文:
I have a pipeline which checks whether a commit has a tag and if that tag is a Version tag (meaning it is like 'v1.0.0' or 'v01.00.00').
My problem is that when I save the result of the regex operation in a variable, it appears to first be True
but when using it in the condition
of the second task it is suddenly False
.
Here is the pipeline:
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
branches:
include:
- master
tags:
include:
- "*"
pool:
vmImage: windows-latest
variables:
hasTags: $[contains(variables['Build.SourceBranch'], 'refs/tags/')]
isVersionTag: 'False'
versionTag: ''
steps:
- task: PowerShell@2
condition: eq(variables.hasTags, 'True')
inputs:
targetType: 'inline'
script: |
# get the tag the from the SourcheBranch
$dummy = $Env:Build_SourceBranch
$regex = "(refs)\/(tags)\/(?<version_tag>.+)$"
$result = [regex]::Matches($dummy, $regex)
$Env:versionTag = $result[0].Groups["version_tag"].Value
# check if the tag is actually a version (e.g. 'v1.0.1')
$regex = "v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$"
$Env:isVersionTag = [regex]::IsMatch($Env:versionTag, $regex)
if($Env:isVersionTag -eq 'True')
{
Write-Host 'It is a version tag'
}
Write-Host "Variable Build.SourceBranch = $Env:Build_SourceBranch"
Write-Host "Variable isVersionTag = $Env:isVerionTag"
Write-Host "Variable hasTags = $Env:hasTags"
Write-Host "Variable versionTag = $Env:versionTag"
# This will not run because the condition is evaluated as the following:
# Evaluating: and(eq(variables['hasTags'], 'True'), eq(variables['isVersionTag'], 'True'))
# Expanded: and(eq('True', 'True'), eq('False', 'True'))
# Result: False
- task: PowerShell@2
condition: and(eq(variables.hasTags, 'True'), eq(variables.isVersionTag, 'True'))
inputs:
targetType: 'inline'
script: |
# Write your PowerShell commands here.
Write-Host "The tag is a version tag"
The output of the Write-Host
of the above pipeline is the following:
It is a version tag
Variable Build.SourceBranch = refs/tags/v02.01.07
Variable isVersionTag =
Variable hasTags = True
Variable versionTag = v02.01.07
答案1
得分: 1
在PowerShell中,环境变量只包含字符串,没有布尔值。在您的情况下,它们包含字符串“True”或字符串“False”。无论如何,它们都包含某些内容,并且第二个示例中的表达式$Env:isVersionTag
返回“False”,这仍然被视为类似于true的值。而应该使用类似于 if($Env:isVersionTag -eq "True")
这样的方式,这应该可以工作。
要在任何PowerShell窗口中验证这种行为,您可以执行以下操作:
$Env:testbool = $false
Write-Host $Env:testbool.GetType().FullName
英文:
The environment variables in PowerShell only contain strings, no booleans. In your case, they contain either the string "True" or the string "False". Either way, they contain something and the expression $Env:isVersionTag
in the second example returns "False" which still is considered trueish. Use something like if($Env:isVersionTag -eq "True")
instead, this should work.
To verify this behavior in any PowerShell window, you can do this:
$Env:testbool = $false
Write-Host $Env:testbool.GetType().FullName
答案2
得分: 1
我最终替换了
$Env:isVersionTag = [regex]::IsMatch($Env:versionTag, $regex)
为
if ([regex]::IsMatch($Env:versionTag, $regex)) {
Write-Host "##vso[task.setvariable variable=isVersionTag]True"
} else {
Write-Host "##vso[task.setvariable variable=isVersionTag]True"
}
然后它按预期工作了。
英文:
I ended up replacing
$Env:isVersionTag = [regex]::IsMatch($Env:versionTag, $regex)
with
if([regex]::IsMatch($Env:versionTag, $regex))
{
Write-Host "##vso[task.setvariable variable=isVersionTag]True"
}else{
Write-Host "##vso[task.setvariable variable=isVersionTag]True"
}
and then it worked as expected.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论