在Azure DevOps构建管道完成后设置Git标签

44

我正在尝试使用GitVersion在成功构建后将当前版本号作为标签设置到GIT提交上。感觉好像不是第一个这样做的人,但我很难找到可行的方法。

Azure Devops Pipeline在"获取源代码"选项中提供了"标记源"功能。我已经设置了这个功能,并设置了一个变量,该变量由我其中一个代理任务(GitVersion)设置。

Tag Sources

我可以在调试日志中看到,我添加到管道中的GitVersion组件正在设置此变量。

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

然而,如果我只是这样离开它,我会得到一个被创建为"v$(GitVersion.MajorMinorPatch)"的标签,这意味着在创建标签的时候,该变量已不存在。
标签格式帮助工具提示说:“标签格式可以是用户定义或预定义变量的组合,其范围为“全部”。例如:'$ (Build.DefinitionName)$(Build.DefinitionVersion)$(Build.BuildId)$(Build.BuildNumber)$(My.Variable) '”。
所以我想问题在于在管道期间创建的此变量没有全局作用域。
然后我尝试向"GitVersion.MajorMinorPatch"的管道添加一个管道变量,希望这是正确的范围,并希望当运行"task.setvariable"命令时,它将设置更高范围变量的变量值。

enter image description here

然而,在这种情况下,我只是创建了一个标签“v”。
所以我有点困惑。不知何故,我需要能够动态地创建或设置一个变量,其作用域为ALL,并具有我想要标记的值。
如果您有任何想法,我将非常感激。

你尝试过将 $(Build.BuildNumber) 设置为所需的值吗?然后将其设置为标记值?这需要使用不同的日志命令来设置构建号:build.updatebuildnumber 而不是 task.setvariable。请参见:https://dev59.com/d1oU5IYBdhLWcg3w15ay#37048559 - jessehouwing
是的,那可能是一个绕过它的技巧。 - 4c74356b41
2
在这里使用Build.BuildNumber并不是我想要做的解决方案。我需要BuildNumber是全局唯一的(例如v2.19.1-b23),而且这个标签需要更简单 - 只是v2.19.1。 - Brett
5个回答

72
如果您正在进行yaml管道,您可以添加以下步骤。
- checkout: self
  persistCredentials: true

## Rest of pipeline ##

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

persistCredentials允许令牌自动传递给其他git命令。请注意workingDirectory的赋值,否则我会收到错误提示,指出该位置不是git仓库。

对于带注释标签而非轻量级标签,语法如下所示...

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

为了对其进行用户/日期匹配,您需要设置用户名/电子邮件,例如:
- 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>

为了使其正常工作,需要将{{项目集生成服务器}}的账户(而不是{{项目生成服务帐户}})分配给库的Contribute权限。

enter image description here


8
如果您想知道如何配置项目集合构建服务器账户,可以在“项目设置”>“仓库”>“存储库”中找到。当您单击一个存储库时,您应该会在列出的用户中找到此账户。请注意不要改变原文意思,使翻译更易懂。 - akokskis
1
您还可以单击“仓库”将其设置为项目中所有存储库的选项。 - Paul Hatcher
2
如果您查看https://dev59.com/lG865IYBdhLWcg3wkfgW,它提到-follow-tags仅推送带注释的标签而不是轻量级标签,因此由于所述答案适用于两者,我认为它不需要更改。 - Paul Hatcher
@Dbloom 管道的第一步 - Paul Hatcher
2
由于我处于无头状态,所以我不得不使用 git push origin <tagname> HEAD:origin/$(Build.SourceBranchName) - Klepto
显示剩余3条评论

3
- pwsh: |
    # Construct PAT authentication header
    $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "user",$env:SYSTEM_ACCESSTOKEN)))
    $headers = @{Authorization=("Basic {0}" -f $base64AuthInfo)}
    $url="$(System.CollectionUri)/$(System.TeamProject)/_apis/git/repositories/$(Build.Repository.ID)/annotatedtags?api-version=5.0-preview.1"
    $body = @{name = "$(GitVersion.MajorMinorPatch)"
              message = "automatically added"
              taggedObject = @{
                objectId = "$(Build.SourceVersion)"
              }
            } | ConvertTo-Json


    Invoke-RestMethod -Uri $url -Headers $headers -Method Post -ContentType "application/json" -Body ($body)
  env:
    SYSTEM_ACCESSTOKEN: $(System.AccessToken)
  displayName: 'Add tag'

3

在Paul Hatcher的出色回答上进行拓展,我想要补充一点,在Azure DevOps Server 2019中,对我来说帐户被称为Project Collection Build Service。这似乎也符合当前的Microsoft文档

很抱歉我的声望还不足以评论。


3
我可以看到调试日志,这个变量是由我添加到管道中的GitVersion组件设置的。
您在日志中看到的变量GitVersion.MajorMinorPatch是一个步骤级别的变量,这意味着它的生命周期仅从当前的GitVersion任务开始。

enter image description here

根据您所引用的定义,它必须适用于所有情况。这意味着它必须是一个全局变量。例如,系统默认预定义的变量以及在“变量”选项卡中指定的自定义变量。
基于GitVersion任务的编译和工作逻辑,实际上,GitVersion.MajorMinorPatch值被生成并存储为当前构建的构建号。

enter image description here

因此,您将GitVersion.MajorMinorPatch值标记到存储库的最方便方法是使用$(Build.BuildNumber)

v$(Build.BuildNumber)

enter image description here

这是我的结果:

enter image description here


更新:

为了将由GitVersion任务生成的GitVersion.MajorMinorPatch添加到变量中,请将以下脚本应用于PowerShell任务:

$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)}

如我之前提到的,我仍然认为无法在“标签格式”中指定$(GitVersion.MajorMinorPatch)
强烈建议您通过调用$(Build.BuildNumber)来标记$(GitVersion.MajorMinorPatch)值。

“Major.Minor.Patch”不是全局唯一的,因此不适合用于构建号,有很多提交将具有相同的值。GitVersion.MajorMinorPatch可用于作业中的所有未来步骤,因为我可以创建一个PS任务并输出当前$(GitVersion.MajorMinorPatch)。它只是不可用。似乎标签格式的限制是不必要的,您不能使用任何用户定义的变量(这不是文档所暗示的内容)? - Brett
@Brett,(需要为我的回答中的观点道歉,已经做出了一些更改)。是的,“Major.Minor.Patch”在管道中不是唯一的,但对于使用GitVersion.MajorMinorPatch的管道,其值对于GitVersion.yml是唯一的。关于你所关注的难题:似乎标签格式的限制是不必要的,因为你根本不能使用任何用户定义的变量。不,我们没有在管道上设置这个限制,你可以在“变量”选项卡中自定义一个变量并将其设置值。然后在标签空白处应用此变量即可。 - Mengdi Liang
你可以看到变量值已经被标记到了代码库中。而你的第二次尝试为什么没有值,是因为你没有在“变量”选项卡中设置值。在这里,可以被标记到代码库中的变量必须是预定义变量,包括在“变量”选项卡中定义的自定义变量。当你使用 GitVersion 时,它的值将覆盖构建号。这是这个任务的逻辑。所以我建议你使用 $(Build.BuildNumber) 调用来标记代码库。 - Mengdi Liang
1
谢谢更新。我能否在运行时创建具有全局范围的变量或预先创建并在运行时更改此变量的值?如果我能做到这一点,那么我就可以解决这个问题,事实上,如果我不能这样做,那么使用用户定义的变量的能力是受限的,因为您需要一个人在执行之前设置该值,这意味着很难自动化。对于我想要做的事情,使用Build.BuildNumber并不是一个解决方案。我需要BuildNumber是全局唯一的(例如v2.19.1-b23),并且这个标记需要更简单 - 只是v2.19.1。 - Brett
@Brett,抱歉因为个人忙碌回复晚了。请查看我的更新脚本。但是,正如我所提到的,我仍然认为在标签中指定 $(GitVersion.MajorMinorPatch) 是不可用的。 - Mengdi Liang
显示剩余2条评论

0
我遇到了类似的问题,通过以下方法成功解决:
  1. 在YAML中添加并设置您的自定义变量
trigger:
- none

parameters: # parameters are shown up in ADO UI in a build queue time
- name: 'debug'
  displayName: 'Enable debug output'
  type: boolean
  default: false

variables:
  ROOT: $(Build.SourcesDirectory)
  REPOROOT: $(Build.SourcesDirectory)
  MyCustomVariable: 'Set required value here'


然后在构建触发器中设置相同的变量。

BuildTagCustom


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接