【问题标题】:Condition OR with variables in Azure Devops Pipeline条件 OR 与 Azure Devops Pipeline 中的变量
【发布时间】:2024-01-22 06:56:01
【问题描述】:

我有三个条件作为变量(isMaster、isRelease、isHotfix):

variables:
  isMaster: $[startsWith(variables['Build.SourceBranch'], 'refs/heads/master')]
  isRelease: $[startsWith(variables['Build.SourceBranch'], 'refs/heads/release/')]
  isHotfix: $[startsWith(variables['Build.SourceBranch'], 'refs/heads/hotfix/')]
  checkCondition: $[or(variables.isMaster, variables.isRelease)]

问题是当我为 OR 条件(如 checkCondition)取两个“假”时。 我应该得到“假”,但由于某种原因我得到了“真”。

  - task: CmdLine@2
       inputs:
         script: |
           echo %BUILD_SOURCEBRANCH%
           echo %ISMASTER%
           echo %ISRELEASE%
           echo %ISHOTFIX%
           echo %CHECKCONDITION%
       condition: or(variables.isMaster ,variables.isRelease)
...
Result:
...
refs/heads/someBranch
False
False
False
True
Finishing: CmdLine

任何人都知道为什么条件给出错误的结果? 谢谢!

【问题讨论】:

  • 你能试试condition: or(variables.isRelease ,variables.isMaster)吗?它可以有所作为developercommunity.visualstudio.com/content/problem/1236160/…
  • @KrzysztofMadej 那会很有趣。我过去也遇到过类似的问题。您可以尝试将您的 or 条件包装在:and(succeeded(), <your or condition>).
  • 不幸的是它仍然不正确(我得到了“真实”)。
  • 但是如果我在 OR $[or(startsWith(variables['Build.SourceBranch'], 'refs/heads/master'), startsWith(variables['Build.SourceBranch'] , 'refs/heads/release/'))],我得到了正确的 'false' :/

标签: azure-devops yaml conditional-statements azure-pipelines


【解决方案1】:

当使用OR function时,你需要使用or(expression, expression),然后它将表达式转换为布尔值进行评估。如果您使用or(variables.isMaster ,variables.isRelease),则有两个字符,没有表达式可以转换为布尔值。您需要改用or(startsWith(variables['Build.SourceBranch'], 'refs/heads/master'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'))

【讨论】:

    【解决方案2】:

    看起来这是可能的,因为它写了here

    评估条件以决定是否开始阶段、作业或步骤。这意味着在该工作单元内运行时计算的任何内容都将不可用。例如,如果您的作业使用 $[ ] 语法使用运行时表达式设置变量,则不能在自定义条件中使用该变量。

    但它不能在任何地方使用。因此,如果您在根级别上有步骤,它将不起作用,但如果您以这种方式放置它应该会这样做

    variables:
      isMaster: $[startsWith(variables['Build.SourceBranch'], 'refs/heads/master')]
      isRelease: $[startsWith(variables['Build.SourceBranch'], 'refs/heads/release/')]
      isHotfix: $[startsWith(variables['Build.SourceBranch'], 'refs/heads/hotfix/')]
      checkCondition: $[or(variables.isMaster, variables.isRelease)]
    
    pool:
      vmImage: 'ubuntu-latest'
    
    stages:
    - stage: A
      jobs:
      - job: A1
        steps:
          - script: echo Hello Stage A!
    
    - stage: B
      condition:  or(variables.isMaster ,variables.isRelease)
      jobs:
      - job: B1
        steps:
        - task: CmdLine@2
          inputs:
            script: |
              echo %BUILD_SOURCEBRANCH%
              echo %ISMASTER%
              echo %ISRELEASE%
              echo %ISHOTFIX%
              echo %CHECKCONDITION%
          condition: or(variables.isMaster ,variables.isRelease)
        - task: CmdLine@2
          inputs:
            script: |
              echo %BUILD_SOURCEBRANCH%
              echo %ISMASTER%
              echo %ISRELEASE%
              echo %ISHOTFIX%
              echo %CHECKCONDITION%
    

    【讨论】:

      【解决方案3】:

      如前所述 or 需要它是一个表达式,但如果您希望它更具可读性并且只在变量部分中对表达式进行一次评估,您可以这样做:

      or(eq(variables['isMaster'], 'true'), eq(variables['isRelease'], 'true'))

      带有 and 的示例,其中包含 a or 带有 and 语句:

      - task: AzureCLI@2
        displayName: Download feed.xml
        inputs:
          azureSubscription: vanillaResourceConnection
          scriptType: ps
          scriptLocation: inlineScript
          inlineScript: |
            az storage blob download --account-name $(storageAccount) --container-name '$web' --name feed.xml --file .ado\downloadedFeed.xml
         condition: and(succeeded(), or(eq(variables['isMaster'], 'true'), and(eq(variables['isTag'], 'true'), eq(variables['releaseCheck.isRelease'], 'true'))))
      

      【讨论】: