Question

Setting Git Tag from Azure Devops Build Pipeline on Complete

I'm trying to set a tag with the current version number determined by GitVersion on the GIT commit at the end of a successful build. Feels like I can't be the first one to be doing this, but I'm struggling to find something that works.

Azure Devops Pipeline has a feature in Get Sources to "Tag sources" On Success. I've set this and set to a variable that is set by one of the Agent Tasks I have (GitVersion)

Tag Sources

I can see in the debug logs that this variable is getting set by the GitVersion component that I've added to the pipeline.

2019-12-06T20:54:20.2390794Z ##[debug]Processed: ##vso[task.setvariable variable=GitVersion.MajorMinorPatch;]2.98.0

However if I leave it just as this, I get a tag created as "v$(GitVersion.MajorMinorPatch)" which means that at the time that the tag is being created that that variable no longer exists.

The Tag Format help tooltip says

"Tag format could be a combination of user-defined or pre-defined variables that have a scope of "All". For example: '$(Build.DefinitionName)$(Build.DefinitionVersion)$(Build.BuildId)$(Build.BuildNumber)$(My.Variable)'"

So I guess the problem is that this variable created during the pipeline does not have a scope of All.

I then tried adding a pipeline variable to the pipeline of "GitVersion.MajorMinorPatch" with the hope that this was at the right scope and hoping that when the "task.setvariable" command is run, that this will set the variable value of this higher scoped variable.

enter image description here

However in this case I just got a tag "v" created.

So I am a bit stuck. Somehow I need to be able to dynamically create or set a variable at scope ALL with the value I want to tag here.

I'd be really grateful for any ideas on this.

 48  58882  48
1 Jan 1970

Solution

 80

If you are doing a yaml pipeline, you can add the following steps

- checkout: self
  persistCredentials: true

## Rest of pipeline ##

- script: |
     git tag $(GitVersion.NugetVersionV2)
     git push origin $(GitVersion.NugetVersionV2)
  workingDirectory: $(Build.SourcesDirectory)

The persistCredentials allows the token to be automatically passed to other git commands. Note the assignment of workingDirectory, otherwise I had an error that the location was not a git repository.

For an annotated tag rather than lightweight tag, the syntax would look like this...

- script: |
    git tag -a <tagname> -m <message>
    git push origin <tagname>

To get a user/date against it you need to set the user name/email as well e.g.

- script: |
    git config --global user.name "BuildService"
    git config --global user.email "autobuild@fabrikam.com"
    git tag -a <tagname> -m <message>
    git push origin <tagname>

For this to work, the Project Collection Build Service account (not the Project Build Service Accounts group) needs to be allocated the Contribute permission for the Repositories

enter image description here

2020-03-21

Solution

 3

I can see in the debug logs that this variable is getting set by the GitVersion component that I've added to the pipeline.

The variable GitVersion.MajorMinorPatch you saw from the log is a step-level variable, which means its life cycle is only start from the current GitVersion task.

enter image description here

As the definition you are referring, it scope must to all. This means is must be a global variable. For example, the predefined variables that the system default have, and the customized variables which specified in the Variables tab.


Based on the GitVersion task compile and work logic, in fact, the GitVersion.MajorMinorPatch value is generated and stored as current build's build number:

enter image description here

So, the most convenient method for you to tag the GitVersion.MajorMinorPatch value to repos is using $(Build.BuildNumber):

v$(Build.BuildNumber)

enter image description here

And this is my result:

enter image description here


Update:

To add the GitVersion.MajorMinorPatch which generated by the GitVersion task into Variables, please apply below scripts into PowerShell task:

$connectionToken="{PAT Token}"
$urlget = "https://dev.azure.com/{org}/{project}/_apis/build/definitions/$(System.DefinitionId)?api-version=5.1"
$base64AuthInfo = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$getdef = Invoke-RestMethod -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method GET -ContentType application/json -Uri $urlget 
Write-Host Pipeline = $($getdef | ConvertTo-Json -Depth 100)
$bvalue=@"
    {
      "value": "$(GitVersion.MajorMinorPatch)"
    }
"@
$getdef.variables | add-member -Name "GitVersion.MajorMinorPatch" -value (Convertfrom-Json $bvalue) -MemberType NoteProperty -Force -PassThru

$getdef = $getdef | ConvertTo-Json -Depth 100
$getdef | clip
$urlput = "https://dev.azure.com/{org}/{project}/_apis/build/definitions/$(System.DefinitionId)?api-version=5.1"
$putdef = Invoke-RestMethod -Uri $urlput -Method PUT -Body $getdef -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

As I mentioned previously, I still don't think it is available to specify $(GitVersion.MajorMinorPatch) in Tag format.

Still strongly suggest you by calling $(Build.BuildNumber) to tag the $(GitVersion.MajorMinorPatch) value

2019-12-08