如何在带有变量组的 azure DevOps yaml 管道的变量中使用 IF ELSE?

kev*_*ndo 31 azure-devops azure-pipelines azure-pipelines-yaml

除了变量组之外,我还尝试将 2 个值之一分配给变量,但找不到有关如何使用 IF ELSE 的参考。

基本上我需要将这个 jerkins 逻辑转换为 azure DevOps。

詹金斯

if (branch = 'master') { 
   env = 'a'
} else if (branch = 'dev'){
    env ='b'
}
Run Code Online (Sandbox Code Playgroud)

我从下一个中找到了 1 个参考,但是如果变量部分没有变量组,这个参考似乎有效。

/sf/answers/4027276851/

但是在我的管道中,我已经有一个用于秘密的变量组,所以我必须使用名称/值约定,并且该示例不适用于诸如expected a mappingorA mapping was not expected或 or 之类的错误Unexpected value 'env'

variables:
- group: my-global
- name: env
  value:
    ${{ if eq(variables['Build.SourceBranchName'], 'master') }}: 
      env: a
    ${{ if eq(variables['Build.SourceBranchName'], 'dev') }}: 
      env: b

Run Code Online (Sandbox Code Playgroud)

或者

variables:
- group: my-global
- name: env
  value:
    ${{ if eq(variables['Build.SourceBranchName'], 'master') }}: a
    ${{ if eq(variables['Build.SourceBranchName'], 'dev') }}: b

Run Code Online (Sandbox Code Playgroud)

小智 37

此代码有效。
我正在做类似的参数。

variables:
  - name: var1
    ${{ if eq(parameters.var1, 'custom') }}:
      value: $(var1.manual.custom)
    ${{ if ne(parameters.var1, 'custom') }}:
      value: ${{ parameters.var1 }}
Run Code Online (Sandbox Code Playgroud)

  • 你好!我正在努力实现与作者类似的目标。此语法在 Azure 的在线编辑器中为我提供了“意外属性 ${{ if .... }}”。当我保存文件并点击“验证”/“运行”按钮时,我会收到一个弹出窗口,指示“值”已定义。 (2认同)

Seb*_*tze 19

几周前,微软发布了 YAML pipeline 的一项新功能,可以让您做到这一点:IF ELSE符号。

https://learn.microsoft.com/en-us/azure/devops/release-notes/2021/sprint-192-update#new-yaml-conditional-expressions

使用 ${{ else }} 和 ${{ elseif }} 表达式在 YAML 文件中编写条件表达式变得更加容易。以下是如何在 YAML 管道文件中使用这些表达式的示例。

steps:
- script: tool
  env:
    ${{ if parameters.debug }}:
      TOOL_DEBUG: true
      TOOL_DEBUG_DIR: _dbg
    ${{ else }}:
      TOOL_DEBUG: false
      TOOL_DEBUG_DIR: _dbg
Run Code Online (Sandbox Code Playgroud)
variables:
  ${{ if eq(parameters.os, 'win') }}:
    testsFolder: windows
  ${{ elseif eq(parameters.os, 'linux' }}:
    testsFolder: linux
  ${{ else }}:
    testsFolder: mac
Run Code Online (Sandbox Code Playgroud)


Sim*_*ing 12

我想要运行时条件评估,类似于编译时:

\n
variables:\n   VERBOSE_FLAG:\n   ${{if variables[\'System.Debug\']}}:\n      value: \'--verbose\'\n   ${{else}}:\n      value: \'\'\n
Run Code Online (Sandbox Code Playgroud)\n

但不幸的是,Azure devops 不支持特殊类型的函数,例如if(condition, then case, else case)- 所以我尝试了一下,发现可以使用replace函数进行双字符串替换。当然,它看起来确实有点老套。

\n

例如,人们可能希望根据系统调试是否启用来调整任务输入。这不能使用“标准条件插入”( ) 来完成${{ if \xe2\x80\xa6 }}:,因为System.Debug不在模板表达式的范围内。因此,运行时表达式可以解决这个问题:

\n
variables:\n   VERBOSE_FLAG:\n   ${{if variables[\'System.Debug\']}}:\n      value: \'--verbose\'\n   ${{else}}:\n      value: \'\'\n
Run Code Online (Sandbox Code Playgroud)\n

请注意,在调用之前使用eq来检查 的值并不是多余的:由于总是返回或,因此我们可以安全地使用将这些值分别映射到和。System.DebugreplaceeqTrueFalsereplace\'--verbose\'\'\'

\n

一般来说,我强烈建议坚持使用布尔表达式(例如,布尔值函数的应用,如eq, gtor in)作为内部应用程序的第一个参数replace。如果我们不这样做而只是写例如

\n
- job:\n  variables:\n    VERBOSE_FLAG: $[\n        replace(\n          replace(\n            eq(lower(variables[\'System.Debug\']), \'true\'),\n            True,\n            \'--verbose\'\n          ),\n          False,\n          \'\'\n        )\n      ]\n  steps:\n    - task: cURLUploader@2\n      inputs:\n        # \xe2\x80\xa6\n        options: --fail --more-curl-flags $(VERBOSE_FLAG)\n
Run Code Online (Sandbox Code Playgroud)\n

那么,如果System.Debug设置为eg footruebar,则值VERBOSE_FLAG将变为foo--verbosebar

\n


Krz*_*tof 5

模板表达式的语法${{ if ...... }}不仅限于作业/阶段级别。下面的管道执行相同的操作并产生相同的输出:

stages:
- stage: One
  displayName: Build and restore
  variables:
  - group: PROD
  - name: env
    ${{ if eq(variables['Build.SourceBranchName'], 'master') }}:
      value: a
    ${{ if eq(variables['Build.SourceBranchName'], 'dev') }}:
      value: b
  jobs:
  - job: A
    steps:
    - script: | 
        echo '$(name)'
        echo '$(env)'
Run Code Online (Sandbox Code Playgroud)
variables:
- group: PROD
- name: env
  ${{ if eq(variables['Build.SourceBranchName'], 'master') }}:
    value: a
  ${{ if eq(variables['Build.SourceBranchName'], 'dev') }}:
    value: b

steps:
- script: | 
    echo '$(name)'
    echo '$(env)'
Run Code Online (Sandbox Code Playgroud)


Jos*_*ust 4

我认为现在您需要使用一个任务来自定义name/value语法变量和条件变量值。正如您所指出的,语法的对象结构似乎name/value破坏了表达式的解析。

对我来说,以下是一个相当干净的实现,如果您想将其从管道中抽象出来,那么供您的许多管道使用的简单模板似乎应该满足对中心“全局”位置的需求。

variables:
  - group: FakeVarGroup
  - name: env
    value: dev

steps:
  - powershell: |
      if ($env:Build_SourceBranchName -eq 'master') {
        Write-Host ##vso[task.setvariable variable=env;isOutput=true]a
        return
      } else {
        Write-Host ##vso[task.setvariable variable=env;isOutput=true]b
      }      
    displayName: "Set Env Value"
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的建议。我想我已经从这里看到了类似的解决方案,但没有尝试过,因为我希望有更简单的解决方案,而无需添加步骤。我也询问了微软的支持,所以如果他们没有解决方案,那么我会尝试这个。 (2认同)