AzureDevops管道任务的条件未正确评估。

huangapple go评论87阅读模式
英文:

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:
      - &quot;*&quot;

pool:
  vmImage: windows-latest

variables:
  hasTags: $[contains(variables[&#39;Build.SourceBranch&#39;], &#39;refs/tags/&#39;)]
  isVersionTag: &#39;False&#39;
  versionTag: &#39;&#39;

steps:

- task: PowerShell@2
  condition: eq(variables.hasTags, &#39;True&#39;)
  inputs:
    targetType: &#39;inline&#39;
    script: |
      # get the tag the from the SourcheBranch
      $dummy = $Env:Build_SourceBranch
      $regex = &quot;(refs)\/(tags)\/(?&lt;version_tag&gt;.+)$&quot;
      $result = [regex]::Matches($dummy, $regex)
      $Env:versionTag = $result[0].Groups[&quot;version_tag&quot;].Value

      # check if the tag is actually a version (e.g. &#39;v1.0.1&#39;)
      $regex = &quot;v[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$&quot;
      $Env:isVersionTag = [regex]::IsMatch($Env:versionTag, $regex)

      if($Env:isVersionTag -eq &#39;True&#39;)
      {
        Write-Host &#39;It is a version tag&#39;
      }

      Write-Host &quot;Variable Build.SourceBranch = $Env:Build_SourceBranch&quot;
      Write-Host &quot;Variable isVersionTag = $Env:isVerionTag&quot;
      Write-Host &quot;Variable hasTags = $Env:hasTags&quot;
      Write-Host &quot;Variable versionTag = $Env:versionTag&quot;      

# This will not run because the condition is evaluated as the following:
# Evaluating: and(eq(variables[&#39;hasTags&#39;], &#39;True&#39;), eq(variables[&#39;isVersionTag&#39;], &#39;True&#39;))
# Expanded: and(eq(&#39;True&#39;, &#39;True&#39;), eq(&#39;False&#39;, &#39;True&#39;))
# Result: False
- task: PowerShell@2
  condition: and(eq(variables.hasTags, &#39;True&#39;), eq(variables.isVersionTag, &#39;True&#39;))
  inputs:
    targetType: &#39;inline&#39;
    script: |
      # Write your PowerShell commands here.
      
      Write-Host &quot;The tag is a version tag&quot;      

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 &quot;True&quot;) 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 &quot;##vso[task.setvariable variable=isVersionTag]True&quot;
}else{
   Write-Host &quot;##vso[task.setvariable variable=isVersionTag]True&quot;
}

and then it worked as expected.

huangapple
  • 本文由 发表于 2023年8月9日 14:15:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76865031-2.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定