是否可以基于 System.PullRequest.TargetBranch 为管道模板中的阶段设置条件?

时间:2021-03-22 14:24:06

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

我有一个解决方案,其中 git 分支与环境直接相关(必须这样,所以请不要讨论这是好是坏,我知道这不是最佳实践)。

我们可以选择对环境运行验证部署(包括自动测试),而无需将解决方案实际部署到环境中。正因为如此,我想建立一个管道来运行这个环境的验证,每当向该环境的分支打开拉取请求时。此外,我为大部分管道使用了模板。主存储库中的实际管道只是一个指向另一个存储库中模板管道的小解决方案。反过来,这个模板又为每个相应的环境提供了阶段。

我在主管道中成功添加了一个标识当前分支的解决方案,对于拉取请求应该是目标分支:

variables:
  - name: currentBranch
    ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
      value: $(System.PullRequest.TargetBranch)
    ${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
      value: $(Build.SourceBranch)

我想通过参数将此变量 currentBranch 发送到模板,因为我的模板管道根据分支具有不同的阶段。我的解决方案是使用这样的管道:

extends:
  template: <template-reference>
  parameters:
    branch: $(currentBranch)

...然后在我的管道中的一个阶段执行以下操作:

- stage: TestAndDeployBranchName
    condition: eq('${{ parameters.branch }}', 'refs/heads/branchName')
    jobs:
      - job1... etc.

基本上,如果当前分支是“branchName”,或者(对于拉取请求)当目标分支是“branchName”时,阶段应该运行,它来自发送到模板的“branch”参数。< /p>

但是,我看到 here 表明 System.PullRequest.TargetBranch 不可用于模板,并且进一步 here 当模板展开时参数不可用于模板(变量为空)。因此我的管道没有按预期工作(条件不会在它应该触发时触发,即当分支名称匹配时)。

有什么方法可以在模板中的条件中使用 System.PullRequest.TargetBranch,还是应该寻找其他解决方案?

2 个答案:

答案 0 :(得分:0)

检查你的脚本后,我们发现我们不能使用

  variables:
  - name: currentBranch
    ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
      value: $(System.PullRequest.TargetBranch)
    ${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
      value: $(Build.SourceBranch)

在变量中。 变量会将第二个值复制到第一个值。 这会导致您的问题。 因此,就我而言,我创建了一个变通方法,希望这对您有所帮助。这是我的主要 yaml:

parameters:
  - name: custom_agent
    displayName: Use Custom Agent
    type: boolean
    default: true
  - name: image
    type: string
    default: default

resources:
  repositories:
    - repository: templates
      type: git
      name: Tech-Talk/template

trigger: none

    
pool:
  vmImage: windows-latest
  # vmImage: ubuntu-20.04

stages:
- stage: A
  jobs:
  - job: A1
    steps:
     - task: PowerShell@2
       name: printvar 
       inputs:
         targetType: 'inline'
         script: |
            If("$(Build.Reason)" -eq "PullRequest"){
                Write-Host "##vso[task.setvariable variable=currentBranch;isOutput=true]$(System.PullRequest.TargetBranch)"
            }
            else{
                Write-Host "##vso[task.setvariable variable=currentBranch;isOutput=true]$(Build.SourceBranch)"
            }    
    
- stage: B
  condition: eq(dependencies.A.outputs['A1.printvar.currentBranch'], 'refs/heads/master')
  dependsOn: A
  jobs:
  - job: B1
    variables:
      varFromA: $[ stageDependencies.A.A1.outputs['printvar.currentBranch'] ]
    steps:
    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: |
          # Write your PowerShell commands here.
          
          Write-Host "$(varFromA)"
    - template:  temp.yaml@templates
      parameters:
        branchName: $(varFromA)
        agent_pool_name: ''
        db_resource_path: $(System.DefaultWorkingDirectory)

请注意: 如果我们使用它,我们需要修改您的临时 yaml。 我们需要将条件移动到主 yaml 并使临时 yaml 只剩下步骤。

答案 1 :(得分:0)

在进一步调查之后,我得出结论,我试图做的事情是不可能的。

简而言之,System.PullRequest.TargetBranch(我假设至少 System.PullRequest 中的一些其他变量在模板的编译时不可用,即评估条件时。因此,在条件中使用这些变量在模板中是不可能的。

由于我的目标是仅针对拉取请求运行某些步骤,因此基于拉取请求的目标分支,我通过创建重复管道解决了这个问题。除了模板的输入参数不同之外,每个管道都是相同的并且引用相同的模板。然后我添加了每个“PR 管道”作为分支策略的一部分运行,每个分支都适用。

这很好用,但是如果我对另一个分支有相同的要求,它需要我创建一个新管道。此外,我必须单独维护每个 PR 管道(这可能有好有坏)。

不是一个理想的解决方案,但它有效。

参考 PR 管道:

trigger: none # no trigger as PR triggers are set by branch policies

#This references the template repository to reuse the basic pipeline
resources:
  repositories:
  - repository: <template repo>
    type: git # "git" means azure devops repository
    name: <template name> # Syntax: <project>/<repo>
    ref: refs/heads/master # Grab latest pipeline template from the master branch

stages:
  - stage: VerifyPullRequest
    condition: |
      and(
        not(failed()), 
        not(canceled()), 
        eq(variables['Build.Reason'], 'PullRequest')
      )
    displayName: 'Verify Pull Request'
    jobs:
      - template: <template reference> # Template reference
        parameters:
          image: <image>
          targetBranch: <targetBranch> # Adjust this to match each respective relevant branch

targetBranch 参数用于模板中相关的地方,用于运行 PR 验证。

分支策略示例: (为每个相关分支设置此项) Picture of branch policy set up