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

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

AzureDevops pipeline task with condition not evaluated correctly

问题

我有一个流水线,用于检查提交是否有标签,并且该标签是否是版本标签(即类似于'v1.0.0'或'v01.00.00')。

我的问题是,当我将正则表达式操作的结果保存在变量中时,它似乎首先是True,但在第二个任务的condition中使用时突然变为False

以下是该流水线的代码:

# 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"      

上述流水线的Write-Host输出如下:

It is a version tag
Variable Build.SourceBranch = refs/tags/v02.01.07
Variable isVersionTag = 
Variable hasTags = True
Variable 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",这仍然被认为是真值。相反,你可以使用类似于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

我最终将以下代码替换为:

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.html
匿名

发表评论

匿名网友

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

确定