You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure DevOps YAML扩展模板Unrecognized value 'else'报错解决

YAML扩展阶段模板else表达式报错问题

在job.steps的foreach循环内添加else条件时,会触发报错:Unrecognized value: 'else'. Located at position 1 within expression: else

测试用构建YAML

resources:
  repositories:
    - repository: self
      type: git
      ref: refs/heads/Development
      
    - repository: AdoRestrictions
      type: git
      name: utl-yaml-templates
      ref: refs/heads/main

trigger: none

pool:
    name: PROD    

extends:
  template: ADO_Stage_Restrictions_Dev.yml@AdoRestrictions
  parameters:
    stageObjs:
      - stage: 'BuildStage'
        displayName: 'Build Test'
        jobs:
          - job: 'BuildJob'
            displayName: 'Build'
            steps:
            - task: PowerShell@2
              displayName: 'PS Hello World'
              inputs:
                targetType: inline
                script: |
                  Write-Host "Hello World"

可正常运行的基础扩展模板

未添加else分支时,模板可正常解析运行:

parameters:
  - name: stageObjs
    type: stageList
    default: []

stages:
- ${{ each stage in parameters.stageObjs }}:
  - stage: ${{ stage.stage }}
    displayName: ${{ stage.displayName }}
    jobs: 
    - ${{ each job in stage.jobs }}:          
      - job: ${{ job.job }}
        displayName: ${{ job.displayName }}
        steps:          
        - ${{ each step in job.steps }}:
          - ${{ if or(startsWith(step.task, 'PowerShell'),startsWith(step.task, 'CmdLine'),startsWith(step.task, 'Bash'),startsWith(step.task, 'ShellScript'),containsValue(step.task, 'Script'),containsValue(step.task, 'CLI'),containsValue(step.task, 'PowerShell')) }}:         
            - task: PowerShell@2
              displayName: 'Unapproved - ${{ step.displayName }}'
              inputs:
                targetType: inline                        
                script: Write-Output "Unapproved Task - Scripting and CLI tasks are not approved for use in yaml pipelines"

添加else分支后的异常模板

添加else分支后模板解析失败:

parameters:
  - name: stageObjs
    type: stageList
    default: []

stages:
- ${{ each stage in parameters.stageObjs }}:
  - stage: ${{ stage.stage }}
    displayName: ${{ stage.displayName }}
    jobs: 
    - ${{ each job in stage.jobs }}:          
      - job: ${{ job.job }}
        displayName: ${{ job.displayName }}
        steps:          
        - ${{ each step in job.steps }}:
          - ${{ if or(startsWith(step.task, 'PowerShell'),startsWith(step.task, 'CmdLine'),startsWith(step.task, 'Bash'),startsWith(step.task, 'ShellScript'),containsValue(step.task, 'Script'),containsValue(step.task, 'CLI'),containsValue(step.task, 'PowerShell')) }}:         
            - task: PowerShell@2
              displayName: 'Unapproved - ${{ step.displayName }}'
              inputs:
                targetType: inline                        
                script: Write-Output "Unapproved Task - Scripting and CLI tasks are not approved for use in yaml pipelines"                  
          - ${{ else }}:
            - ${{ step }}

完整报错信息

(Line: 22, Col: 13): Unrecognized value: 'else'. Located at position 1 within expression: else. (Line: 22, Col: 13): Expected at least one key-value pair in the mapping 

报错原因

Azure DevOps YAML模板解析器在each循环生成序列的上下文中,无法正确绑定独立作为序列项的${{ else }}表达式和前置的if条件,导致解析失败。

可用解决方案

放弃直接使用${{ else }}语法,改为对条件取反后写独立的if分支实现相同逻辑,同时可扩展更多校验规则,验证可用的模板代码如下:

parameters:
  - name: stageObjs
    type: stageList
    default: []

stages:
- ${{ each stage in parameters.stageObjs }}:
  - stage: ${{ stage.stage }}
    displayName: ${{ stage.displayName }}
    jobs: 
    - ${{ each job in stage.jobs }}:          
      - job: ${{ job.job }}
        displayName: ${{ job.displayName }}
        steps:          
        - ${{ each step in job.steps }}:

            # 拦截所有未获批的脚本类任务
            - ${{ if or(startsWith(step.task, 'PowerShell'),startsWith(step.task, 'CmdLine'),startsWith(step.task, 'Bash'),startsWith(step.task, 'ShellScript'),contains(step.task, 'Script'),contains(step.task, 'CLI'),contains(step.task, 'PowerShell')) }}:                   
              - task: PowerShell@2
                displayName: 'Unapproved Task - ${{ step.displayName }}'
                inputs:
                  targetType: inline                        
                  script: throw "Unapproved Task - Scripting and CLI tasks are not approved for use in yaml pipelines" 

            # 非脚本类任务执行额外校验
            - ${{ if and(not(startsWith(step.task, 'PowerShell')),not(startsWith(step.task, 'CmdLine')),not(startsWith(step.task, 'Bash')),not(startsWith(step.task, 'ShellScript')),not(contains(step.task, 'Script')),not(contains(step.task, 'CLI')),not(contains(step.task, 'PowerShell')) ) }}:         
              
              # 校验Azure相关任务的订阅是否在允许列表内
              - ${{ if contains(step.task, 'Azure') }}:                                                      
                - ${{ each pair in step }}:                                                       
                    ${{ if eq(pair.key, 'inputs') }}:
                      inputs:
                        ${{ each attribute in pair.value }}:
                          ${{ if contains(attribute.key, 'Subscription') }}:
                            ${{ if and(ne(attribute.value, 'sub-name1'), ne(attribute.value, 'sub-name2'), ne(attribute.value, 'sub-name3')) }}:
                              ${{ attribute.value }}: ''
                            ${{ if or(eq(attribute.value, 'sub-name1'), eq(attribute.value, 'sub-name2'), eq(attribute.value, 'sub-anme3')) }}:
                              ${{ pair.key }}: ${{ pair.value }}
                    ${{ if ne(pair.key, 'inputs') }}:
                      ${{ if eq(pair.key, 'displayName') }}:
                        ${{ pair.key }}: 'Invalid Azure Subscription - ${{ pair.value }}'
                      ${{ if ne(pair.key, 'displayName') }}:
                        ${{ pair.key }}: ${{ pair.value }}

              # 其余非Azure类任务直接放行
              - ${{ if not(contains(step.task, 'Azure')) }}:
                - ${{ step }}

该方案实现的校验逻辑:

  • 第一层拦截所有未获批的脚本/CLI类任务,替换为抛出错误的PowerShell任务
  • 第二层对非脚本类任务做额外校验,针对Azure相关任务校验订阅是否在允许列表内,非Azure类任务直接放行

内容的提问来源于stack exchange,提问作者Bri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 00:45:36