Search code examples
azureazure-devopscontinuous-integrationpipelineversioning

Azure DevOps automatic versioning when it comes to feature branches


This is the way I'm doing my versioning right now

variables:
  major: '1'
  minor: '1'
  revision: $[counter(variables['minor'], 1)] # This will get reset every time minor gets bumped.
  ${{ if eq( variables['Build.SourceBranchName'], 'master' ) }}: 
    nugetVersion: '$(major).$(minor).$(revision)'
  ${{ else }} : 
    nugetVersion: '$(major).$(minor).$(revision)-$(Build.SourceBranchName)'

major and minor are changed manually, and whenever minor is changed, the revision resets back to 0, and keeps increasing with every pipeline that is ran. Now this works well if we only worked in master, but it's not as good when working in separate branches. Because the revision will keep incrementing even if we're working in a different branch, and thus the master version will no longer be coherent, skipping versions.

What is a good way to do this sort of automatic versioning? I was thinking of having the branch version be based on the latest master revision, and then keep incrementing a fourth digit after the branch name. Example with master being on 1.0.9, branch foo would have versions such as 1.0.9-foo.1, 1.0.9-foo.2, and so on.

This is just an idea but I don't know what's the best practice here or standard. Any ideas are appreciated


Solution

  • The counter expression will increment the revision value between different branches in one pipeline, hence, when you are back to master branch, the version will no longer be coherent, skipping versions.

    I was thinking of having the branch version be based on the latest master revision, and then keep incrementing a fourth digit after the branch name. Example with master being on 1.0.9, branch foo would have versions such as 1.0.9-foo.1, 1.0.9-foo.2, and so on.

    To achieve your original idea, you cannot use same counter expression in all yamls between different branches.

    You can store the master version as variable in variable group. In foo branch, get this variable value so that it won't update the master version.

    enter image description here

    The master yaml, change the variable group id to yours.

    trigger: none
    
    pool:
      vmImage: ubuntu-latest
    
    variables:
      major: '1'
      minor: '1'
      revision: $[counter(variables['minor'], 1)] # This will get reset every time minor gets bumped.
      ${{ if eq( variables['Build.SourceBranchName'], 'master' ) }}: 
        nugetVersion: '$(major).$(minor).$(revision)'
    
    steps:
    - bash: |
        az pipelines variable-group variable update --group-id 38 --name nugetversion --value $(nugetVersion)
      env:
        AZURE_DEVOPS_EXT_PAT: $(System.AccessToken)
      condition: eq( variables['Build.SourceBranchName'], 'master' )
    

    Then in foo branch, use yaml below to update the nugetversion. it gets the nugetversion from variable group, and use format() to combine nugetversion and branchname to determine the last patch version. So patch version will also increment and reset when nugetversion update in master branch.

    trigger: none
    
    pool:
      vmImage: ubuntu-latest
    
    variables:
    - group: versionVG
    
    - name: patch
      value: $[counter(format('{0}-{1}', variables['nugetVersion'], variables['Build.SourceBranchName']), 1)]
    
    
    steps:
    - script: echo "##vso[task.setvariable variable=nugetVersion;]$(nugetversion)-$(Build.SourceBranchName).$(patch)"
      displayName: update nuvetVersion value
    
    - script: echo $(nugetVersion)
      displayName: 'test version'
    

    So it will have below version as expected: enter image description here

    Pipeline result sample on master branch and foo branch:

    enter image description here