azureazure-devopsazure-repos

How to make a stage in Azure Pipelines only run when the pull request is merged and not created?


I have an Azure pipeline and I want it to run the first stage when the pull request is created and the second stage when the pull request is completed and merged.

I'm fine with it also running the first stage again when merged. I don't want to create two different triggers, one that runs the validation stage and one that runs the deployment, I'd prefer this to be stages if it's possible, but will if I have to.

My repo is in Azure and the branches I'm starting with are just a feature branch and a dev branch.

trigger:
  batch: true
  branches:
    include:
      - feature
      - dev

pool:
  vmImage: ubuntu-latest

stages:
  - stage: Validate
    {Rest of validate stage}
  - stage: Deploy
    dependsOn: Validate
    condition: {Condition that makes it where this deploy stage runs only when merge happens}
    {Rest of deploy stage}

So far I've tried using predefined variables such as Build.Reason, Build.SourceBranch, System.PullRequest, etc. and haven't been able to make it work. Any help would be much appreciated!


Solution

  • I want it to run the first stage when the pull request is created and the second stage when the pull request is completed and merged. I'm fine with it also running the first stage again when merged.

    In other words, you only want to run the second stage when the pull request is completed and merged. When a PR is merged, there will be a Commit message like Merged PR xx: The pull request title in the commit history.

    enter image description here

    Based on this message, we can create conditions to make the second stage run only when the Commit message $(Build.SourceVersionMessage) contains the key word Merged PR.

    However, in my test, the $(Build.SourceVersionMessage) variable might not be available at the time the condition is evaluated in the second stage.

    As a workaround, we can determine whether $(Build.SourceVersionMessage) contains the Merged PR keyword in stage 1. If contains, set an output variable for use in the second stage.

    Here is my sample yaml:

    trigger:
      batch: true
      branches:
        include:
          - feature
          - dev
    
    pool:
      vmImage: ubuntu-latest
    
    stages:
    - stage: Validate
      jobs:
      - job: A1
        steps:
        - powershell: |
            Write-Host $(Build.SourceVersionMessage)
            if ('$(Build.SourceVersionMessage)' -like '*Merged PR*') {
              Write-Host "##vso[task.setvariable variable=isMergedPR;isOutput=true]true"
            }
          name: SetIsMergedPR
    - stage: Deploy
      dependsOn: Validate
      jobs:
      - job: B1
        condition: eq(variables['MergedPR'], 'true')
        variables:
          MergedPR: $[stageDependencies.Validate.A1.outputs['SetIsMergedPR.isMergedPR']]
        steps:
        - powershell: Write-Host "$(MergedPR)"
    

    Test result:

    The job in the second stage will run when $(Build.SourceVersionMessage) contains the key word Merged PR and be skipped when there is no key word Merged PR.

    enter image description here