如果发布了新的标签,Jenkins会触发构建。

69
我想配置Jenkins,以便在任何git仓库的任何分支发布新标签时开始构建。我该如何配置这个行为?

git jenkins config

触发:

build trigger

9个回答

41

将refspec设置为:+refs/tags/*:refs/remotes/origin/tags/*

分支指定符:**

在构建触发器下,勾选“当有变更推送到GitHub时构建”。


1
你忘记了 refspec 的星号:+refs/tags/*:refs/remotes/origin/tags/*。另外,分支指示符(**)没有起作用,但是“refs/tags/*”可以。现在它只会触发标记提交。 - Antebios
2
我改正了:分支指定器需要是**。让我解释一下原因:如果你提交了一个提交,然后Jenkins作业轮询了仓库,然后你打了标签...Jenkins不会检测到更改。如果你将分支指定器留为空,然后执行相同的过程,即使没有引入新的提交,你的新标签也将被检测到。所以,用户"albertski"几乎给出了正确的答案,只需在"tags/"之后添加星号。 - Antebios
2
这不是一个可靠的答案,它会在每次推送任何分支或创建标签时触发构建。但它只会检出存储库中最近的提交,无论是否打了标签。例如:如果你先将一个提交推到main分支,然后将另一个提交推到release/0.1分支,然后将第一个提交打上v1.0.1的标签并推送;这个任务会触发并检出release/0.1分支上的提交。据我所知,期望的行为是不可能实现的。 - Bracken

31

“新标签”是什么意思?它有一些模板名吗?

你肯定可以在 高级 --> Refspec --> refs/tags/{标签名称} 中定义它。

你甚至可以使用 refs/tags/* 来查找任何新标签。

输入图像描述


1
是的,我想让 Jenkins 在 /tags 文件夹中发布新标签时开始构建。我尝试通过将 /tags/* 添加到分支指定器来实现,但这对我没有起作用。 - Kingalione
1
是的,我尝试过了,它只能半成功。如果我给最新版本打标签,它可以工作,但如果我给旧版本打标签,它就不能工作。我希望当任何修订版被打上新标签时,Jenkins都会开始构建。我使用了类似于您在refspec中的示例+refs/tags/*:refs/remotes/uw/tags/*。我是否漏掉了什么? - Kingalione
因此,总结一下。我的refspec类似于+refs/tags/*:refs/remotes/origin/tags/*,我的分支是*/tags/*,当然你会每隔N分钟(我设为5)添加SCM轮询。之后你会得到什么? - Stan E
2
我发现如果在源代码中没有进行任何更改,Jenkins将不会开始构建标签,即使它是最新的修订版。但在我们的情况下,即使源代码没有更改,触发构建也是必要的。如果创建了一个新的标签,Jenkins应该无论如何都要构建它。 - Kingalione
6
明白了。只有在有新代码时,Git才会在轮询后触发。这是该插件的主要规则,因此只使用Git插件无法绕过该规则。我能给你的建议是创建2个任务。第一个任务每隔N分钟运行一次,并且只需使用控制台即可。您需要执行 git describe --tags 作为 shell 命令,并从 Git 中获取最新的标签。然后,您将标签写入某个属性文件中(用于保存已经运行了该标签的任务),并轮询另一个流,在其中传递标签名称并进行构建。 - Stan E
显示剩余5条评论

10
请注意,stanjer在回答中提供的方法不能使Jenkins在新标签指向之前构建的提交时触发构建。例如,您标记发布v1.0.0(以使Jenkins部署此版本),然后在将来必须回滚到v1.0.0,重新标记其提交,但使用v1.0.0-rollback,Jenkins将不会部署您的回滚,因为它将检查标签所指向的哈希值,而不是标签本身的哈希值。
总之,Jenkins仅会构建指向尚未标记的提交的新标签,这目前无法调整。
如果能够使用Jenkins作为CD工具,使用标签进行部署和回滚将非常棒。
更多信息请参见 https://groups.google.com/forum/#!msg/jenkinsci-users/mYxtDNMz1ZI/xbX9-xM9BQAJ

2
这方面已经有了进展:https://github.com/jenkinsci/github-branch-source-plugin/pull/158/ 看起来非常接近合并。 - Andrew
2
@Andrew 嗯,为什么是 GitHub 插件,而不是通用的 Git 插件? - Dan M.

4

Previous方法对我不起作用,我的情况下需要在单引号中使用refspec:

Refspec:'+refs/tags/*':'refs/remotes/origin/tags/*' Branch Specifier:**/tags/**

我使用的是Jenkins 2.120. 要使由标签触发的作业正常工作,需要执行以下步骤:

  1. 创建作业:

    Refspec:'+refs/tags/*':'refs/remotes/origin/tags/*'

    Branch Specifier:**/tags/**

  2. 运行构建

  3. 重新配置相同的作业参数为:

    Refspec:'+refs/tags/*':'refs/remotes/origin/tags/*'

    Branch Specifier:**

  4. 运行构建

  5. 重新配置相同的作业参数为:

    Refspec:'+refs/tags/*':'refs/remotes/origin/tags/*' Branch Specifier:**/tags/**

  6. 运行构建

只有完成这些神奇的步骤后,当我给分支打上标签时它才会自动触发Jenkins。


这对我也不起作用。我在Github上添加了钩子,并且可以看到钩子在Github(企业版)上被正确触发,但仍然无法触发Jenkins上的作业运行。Git插件已安装,构建触发器“GitHub hook trigger for GITScm polling”也已选中。不知道为什么它不起作用。但是当我在Github上将事件更改为“Pushes”时,触发器将起作用!因此问题是如何在创建标签时触发Jenkins作业? - TangHongWan

2
Combined @albertski and @Sergey的答案对我有用。
路径: Jenkins > {YourJob} > Configure > Pipeline > Definition(Pipeline script from SCM) > SCM(Git)
选项: Repositories > Advanced... > Refspec +refs/tags/v*:refs/remotes/origin/tags/v* Branches to build > Branch Specifier (blank for 'any') **/tags/v* 如果您想构建以v开头的标签,例如v0.1.0、v1.0.5等,请设置v*。

1
他们发布了一个新的“buildingTag”,可以在when块中使用。
buildingTag - A simple condition that just checks if the Pipeline is running against a tag in SCM, rather than a branch or a specific commit reference.

https://jenkins.io/blog/2018/04/09/whats-in-declarative/


0

@albertski的答案是正确的,但不要忘记以下额外设置: 1. 从Bitbucket设置钩子到Jenkins 2. 需要检查轮询SCM

您可以通过从bitbucket存储库中的提交添加新的git标签来测试触发器。


0

我之前遇到了一个问题,因为我勾选了“删除工作区”,但是构建需要一个现有的工作区来进行比较。所以我按照以下步骤操作:

  1. 将refspec设置为'+refs/tags/*':'refs/remotes/origin/tags/*'
  2. 将分支规范设置为refs/tags/{A SPECIFIC TAG}
  3. 确保在构建开始前未勾选“删除工作区”
  4. 运行构建以创建初始工作区
  5. 将分支规范设置为refs/tags/**
  6. 确保轮询您的Git服务已被勾选
  7. 在Git服务(例如Github)上设置Webhook
  8. 创建一个新的标签在Git服务中触发Webhook

现在应该可以正常工作了。 您需要注意日志中的消息是Multiple candidate revisions,这意味着当Git从远程获取并应用分支规范时,存在多个匹配项,因此它只选择列表中的第一个。


0
如果有人正在使用多分支流水线项目,那么答案就简单一些。一旦在您的版本控制服务上设置了Webhook,您可以通过在项目配置中添加一个分支行为来启用标记分支构建:
BranchSources > Behaviors > Add > Discover Tags
当推送标记时,标记分支现在应该会构建。正如其他人提到的,您可以在Jenkinsfile中使用buildingTag()函数和TAG_NAME环境变量来创建特定于标记的逻辑。
stage('Deploy') {
  when { buildingTag() } // only execute this stage on tags
  steps {
    // pass tag name to my fancy deployment script
    pwsh '.deploy.ps1 -release_name $env:TAG_NAME'
  }
}

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