Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Skipping stage based on commit message

I am trying to set Azure DevOps to skip a stage on a multi-stage pipeline if a message does not start with a given text.

From the examples documentation, I think it is just

  - stage: t1
    condition: not(startsWith(variables['Build.SourceVersionMessage'], '[maven-release-plugin]'))
    jobs:
      - job: ReleasePrepare
        displayName: Prepare release
        pool:
          vmImage: 'ubuntu-16.04'
        steps:
          - script: |
              env | sort

However, this gets executed regardless. Here's an example of where I expect the t1 task to not be run based on the commit message https://dev.azure.com/trajano/experiments/_build/results?buildId=110&view=results

The output of env shows that the message was passed in correctly

enter image description here

Just in case it is a bug I reported it here as well https://developercommunity.visualstudio.com/content/problem/697290/startswith-buildsourceversionmessage-variable-not.html

like image 937
Archimedes Trajano Avatar asked Aug 16 '19 07:08

Archimedes Trajano


2 Answers

It appears that Build.SourceVersionMessage at the time of this post is only resolvable on the steps.

Here's a working example that stores the value in a variable in one step and use it in the next job (which can be a deployment)

trigger:
  batch: true
  branches:
    include:
      - master

stages:
  - stage: ci
    displayName: Continuous Integration
    jobs:
      - job: Build
        pool:
          vmImage: 'ubuntu-16.04'
        steps:
          - script: |
              env | sort
              echo "$(Build.SourceVersionMessage)"
  - stage: t1
    displayName: Release
    condition: eq(variables['Build.SourceBranch'],'refs/heads/master')
    jobs:
      - job: GetCommitMessage
        displayName: Get commit message
        steps:
          - bash: |
              echo "##vso[task.setvariable variable=commitMessage;isOutput=true]$(Build.SourceVersionMessage)"
              echo "Message is '$(Build.SourceVersionMessage)''"
            name: SetVarStep
            displayName: Store commit message in variable
      - job: ReleasePrepare
        displayName: Prepare release
        dependsOn: GetCommitMessage
        pool:
          vmImage: 'ubuntu-16.04'
        condition: not(startsWith(dependencies.GetCommitMessage.outputs['SetVarStep.commitMessage'], '[maven-release-plugin]'))
        steps:
          - script: |
              echo this would be a candidate for release
              env | sort
            displayName: Don't do it if maven release
      - job: NotReleasePrepare
        displayName: Don't Prepare Release
        dependsOn: GetCommitMessage
        pool:
          vmImage: 'ubuntu-16.04'
        condition: startsWith(dependencies.GetCommitMessage.outputs['SetVarStep.commitMessage'], '[maven-release-plugin]')
        steps:
          - script: |
              echo this not be a candidate for release because it was created by the plugin
              env | sort
            condition: startsWith(variables.commitMessage, '[maven-release-plugin]')
            displayName: Do it if maven release

The build can be found in https://dev.azure.com/trajano/experiments/_build/results?buildId=133&view=logs&s=6fc7e65a-555d-5fab-c78f-9502ae9436c4&j=b5187b8c-216e-5267-fcdb-c2c33d846e05

like image 171
Archimedes Trajano Avatar answered Nov 15 '22 01:11

Archimedes Trajano


I am trying to set Azure DevOps to skip a stage if a message does not start with a given text.

If I am not misunderstand, the condition you want is if the message match the start with maven-release-plugin, the current stage will be queued.

If this, the condition you write is not correct, I think you should specified it:

startsWith(variables['Build.SourceVersionMessage'], '[maven-release-plugin]')

As I tested on my pipeline:

enter image description here

And in fact, the value of this variable is Deleted 121321. Here is the result:

enter image description here

As you can see, that it is successful to skip the stage. My logic is, the value of Build.SourceVersionMessage should start with othermessage. But in fact, in my pipeline, it's value is Deleted 121321. Not match, so skip this stage.

(Delete 121321 is not only my PR name, I just set the commit message as the default PR name.)

Updated 2:

Though my test logic is not incorrect, but after I reproduced with YAML and many other method tested, such as use Build.SourceVersion which can only got after the source pulled.

Yes, you are right about that Build.SourceVersionMessage does not has value in Job level. As my tested, it indeed null in job level.

But, unfortunately, this is not a bug. This is as designed in fact.

We can think that the source repos be pulled locally only the stage job begin to execute, right? You can see the Checkout log, it record the process about pull source file down.

If the stage does not be executed, the source will not be pulled down. But also, if no source pulled, the server will also could not get the value of Build.SourceVersionMessage because of no source history. That's why I also tested with the variable Build.SourceVersion in the Job level.

enter image description here

We can not use these two variable at the agent job level because it hasn't pulled sources yet so Build.SourceVersionMessage is null. You'll need to copy it to each step in your pipeline. This is what confirmed by our Product Group team.

But, I still need to say sorry. Sorry about our doc is not too clear to announce that this could not used in agent job level.

like image 1
Mengdi Liang Avatar answered Nov 14 '22 23:11

Mengdi Liang