如何在Azure管道中获取Git标记

时间:2019-05-27 13:21:25

标签: git azure-devops azure-pipelines git-tag

在Azure管道中,我启用了git标签来触发管道,如下所示:

trigger:
  branches:
    include:
    - '*'
  tags:
    include:
    - '*'

现在,我想知道是否有一种方法可以通过编程确定:

  1. 管道是从git commit还是git标签开始的?
  2. 如果管道是从git标签启动的,标签名称是什么?

9 个答案:

答案 0 :(得分:3)

要检查提交是否来自标签,请使用:

startsWith(variables['Build.SourceBranch'], 'refs/tags/')

来自James Thurley:

  

通过以下方式获取标签名称:

$tags = git tag --sort=-creatordate
$tag = $tags[0]
  

这样可以正确地对带注释和未带注释的标签进行排序,   因此,第一个结果是最新的标记。

我已经删除了原始答案,并用James Thurley的正确答案替换了它。我会删除我的答案,但看来您无法删除接受的答案。

答案 1 :(得分:1)

这需要考虑不同的情况。如果您只是推送标签或使用UI创建它,则管道将从git标签开始。只要提交没有任何标签,它将从git commit开始。毫无疑问,构建将仅触发一次。

但是,如果您使用标签推送提交,构建将被触发两次。首先由提交触发,其次由标签触发。检查这张照片。 enter image description here

这意味着管道是从提交而不是标签开始的。

总之,无论是哪个先发,触发构建的标签都是您推送或创建的。

要获得更直观的视图,可以在内部版本号中添加变量' $(Build.SourceBranch)'。这是有关如何在YAML文件中配置内部版本号的代码:

name: $(Build.SourceBranch)-$(date:yyyyMMdd)$(rev:.r)
trigger:
  branches:
    include:
    - '*'
  tags:
    include:
    - '*'

这是触发构建的结果。如果为tag,它将显示refs_tags_{tagname},如果已提交,则将显示refs_heads_{branchname}

enter image description here

答案 2 :(得分:1)

使用map.getOrDefault(key, defaultValue)接受的答案对我不起作用,因为它没有正确排列标签,而是给出了git tag -l v*

我发现最好这样做:

1.1, 1.11, 1.12, 1.2, 1.3, etc

这样可以正确地对带注释和未带注释的标签进行排序,因此第一个结果是最新的标签。

答案 3 :(得分:1)

回答第二个问题。 如果您不介意使用单独的管道来通过标签触发,则可以启用持续集成并覆盖YAML触发,如下所示。此示例将触发带有模式为“ test-*”(与分支无关)的标签的构建。

enter image description here

这样做,您只需在管道中执行git describe,它将输出触发构建的标记的名称。

在这里您可以看到结果:

enter image description here

答案 4 :(得分:0)

将管道配置为带有标签的触发器时,意味着按下新标签时,管道开始运行。所以:

1)管道将从git标签开始。

2)我不明白这个问题,如果您按下标签test,则标签名称将为test

如果您想通过编程方式了解构建触发器是否是标签以及标签名称是什么,则可以检查环境变量Build.SourceBranch(如果构建来自标签),则值将为:refs/tags/tagName

因此只需添加一个PowerShell任务并打印值:

Write-Host $env:Build_SourceBranch

答案 5 :(得分:0)

根据this doc,开始构建的标记可以在BUILD_SOURCEBRANCH中找到。

  

如果此创建是由于创建标记而排队的,则这是该标记的名称。对于Azure Pipelines,将BUILD_SOURCEBRANCH设置为完整的Git参考名称,例如refs / tags / tag_name。

答案 6 :(得分:0)

git describe可以为您提供给定git哈希的(最接近)标记名称,Azure可以使用$(Build.SourceVersion)为您提供当前的哈希。

使用--exact-match限制git describe仅使用特定提交中的标记:

git describe --exact-match $(Build.SourceVersion)

如果有标签,它将在stdout上返回:

$ git describe --exact-match d9df242
v1.0.0

如果没有标签,git describe --exact-match退出,退出代码为128:

$ git describe --exact-match cc1f9d2
fatal: no tag exactly matches 'cc1f9d23854c37dec000485c6c4009634516a148'
$ echo $?
128

因此您可以在测试中使用它,也可以使管道中的任务失败,这些管道会触发不仅仅是标记的修订。

答案 7 :(得分:0)

这里的其他答案涵盖了问题的第一部分,因此正如Alex Kaszynski所指出的,您可以使用YAML条件:

startsWith(variables['Build.SourceBranch'], 'refs/tags/')

现在,获取标签名称比问问题时要容易一些:

Build.SourceBranchName

此变量包含最后一个git ref路径段,因此例如,如果标记为refs/tags/1.0.2,则此变量将包含1.0.2:标记名称。

Full docs are now here

答案 8 :(得分:0)

我意识到我的回答可能不适用于所有人。但是,我想将其作为替代方案,供那些使用尚未具备 replace 功能的 Azure DevOps 本地安装的用户使用(2019 年)。

steps:
- powershell: |
    $tag = "$(Build.SourceBranch)"
    $tag = $tag -replace "refs/tags/", ""
    echo "##vso[task.setvariable variable=tag;isOutput=true]$tag"
  name: createTagVariableStep

此步骤使用特殊语法调用 setvariable 日志记录命令来设置名称为 tag 的变量,以便在当前作业中使用。它可以作为 $(createTagVariableStep.tag) 访问。

如果您使用的是具有替换功能的 Azure DevOps 版本(2020 on prem 或 Azure DevOps Services),那么您可以使用以下内容:

variables:      
  tag: $[replace(variables['Build.SourceBranch'], 'refs/tags/', '')]

对于这些选项中的任何一个,我都会将它们与条件结合使用

job: SomeAwesomeJob
condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/') # only run when there is a tag