在 Github 中合并拉取请求时触发 Jenkins 构建

Posted

技术标签:

【中文标题】在 Github 中合并拉取请求时触发 Jenkins 构建【英文标题】:Trigger Jenkins build when pull request is merged in Github 【发布时间】:2021-01-10 23:40:09 【问题描述】:

这在 Jenkins 中应该是一个简单的、开箱即用的配置,但我在互联网上没有找到任何简单的东西。我要做的就是仅在我将拉取请求合并到我们的 Github 存储库时触发构建。

首先,Github 将围绕拉取请求的几乎所有活动聚合到一个 webhook 中(而 bitbucket 允许您区分操作)。

在 Jenkins 方面,我看到帖子指向 Generic Webhook Plugin,它允许您摄取 webhook 的 json 并创建变量,但是从这里看起来需要在脚本中使用这些才能触发/不触发构建。

Github Pull Request Build 是另一个流行的插件,但同样没有明确声明“仅在 PR 合并时触发此构建”,甚至似乎提供了在 webhook json 中查找特定值的选项。

除非有其他插件,否则我没有找到最好的选择(即最少的配置才能开始构建)是在 Jenkins 中为 GITSCM 轮询配置 GitHub 挂钩触发器,在 Github 端仅发送 webhook在推送事件中......但这不是我们正在寻找的确切行为。

现在这一切都是通过 UI 完成的,而且自从我使用 Jenkins 以来已经有一段时间了,所以也许声明性管道基础设施已经通过了 UI,但看起来这应该更直观。有人可以解释他们发现的最简单的实现,使用 Jenkins 和 Github,仅在拉取请求合并到特定分支时触发构建?

【问题讨论】:

【参考方案1】:

不再需要 webhook,因为您现在可以使用GitHub Actions(假设您使用的是github.com,尽管Actions are coming with GHE, GitHub Enterprise, in Beta, starting Sept. 2020)。

正如 on this thread 所解释的,当拉取请求在 master 上合并时,您可以在 GitHub 端触发作业:

on:
  pull_request:
    branches:
      - master
    types: [closed]

jobs:
  <job id>:
    if: github.event.pull_request.merged == true
    steps: // the rest of the code

然后该作业可以使用像 Trigger Jenkins Job for GitHub Actions 这样的 GitHub Action,它将调用您的 Jenkins 并触发一个或多个 Jenkins 作业。

jobs:

  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
    - name: trigger single Job
      uses: appleboy/jenkins-action@master
      with:
        url: "http://example.com"
        user: "example"
        token: $ secrets.TOKEN 
        job: "foobar"

在discussion with the OP 和GitHub Actions tutorial 之后,我确认:

Jenkins 不必从 Docker 启动,只需通过其公共 URL 从 GitHub 进行寻址即可; 需要在 Jenkins 上激活“触发远程构建”; 需要为有权启动 Jenkins 作业的 Jenkins 用户生成令牌; 必须在您的 GitHub 存储库的文件夹 .github/workflows 中创建一个文件 triggerJenkinsBuild.yml(或您想要的任何其他名称),其中包含上述两个 YAML 部分; “url:”字段只是 Jenkins 实例的基本 URL,没有额外的路径。

【讨论】:

在 Jenkins 端是否需要启用“触发远程构建”? 另外,这似乎只适用于 Jenkins 的 Docker 安装,对吗? @NealR 是的,您需要启用“触发远程构建”。这个 GitHub 操作使用 URL 来联系您的 Jenkins,所以无论是否使用 Docker,只要您的 Jenkins 可以从 GitHub 访问,GitHub 就会在 master 上的 Pull Request 上调用它。 对不起 - 这方面的教程令人难以置信......稀疏。如果没有安装 Docker,这会工作吗?如果是这样,您能否提供有关如何将其配置为在 Jenkins 端工作的说明? @NealR 不涉及 docker,(jenkins2.caceis.group.gca 使用 docker Jenkins 作为本地 Jekins 的示例,以显示需要生成令牌的屏幕截图,其中将由 GitHub Action 在其 Jenkins "url:" 参数中使用【参考方案2】:

尝试到处寻找,然后自己想出了这个解决方案

我假设您已经为 jenkins 配置了 webhook,因此跳过了。这个想法是捕获合并状态,并且仅在其为 true 时触发构建。

我在 jenkins 上使用通用 webhook 触发器和可选过滤器来实现这一点。

如果构建被合并,此变量返回 true。

只有当这个变量为真时才会触发构建

【讨论】:

谢谢,这很有帮助,现在似乎对我有用 很高兴我能帮上忙!【参考方案3】:

您可以配置通用 webhook 触发器插件来解析来自 github 的有效负载 json。 首先确保你在 github webhook 配置中勾选了 Pull requests

现在您可以在 webhook json 中查找合并的密钥,更多详细信息请参见此网址:https://developer.github.com/webhooks/event-payloads/#pull_request 首先,您需要检查操作键是否已关闭,然后检查合并键。根据官方文档 如果操作已关闭且合并的键为 false,则拉取请求已通过未合并的提交关闭。如果操作关闭并且合并的键为真,则拉取请求已合并。 现在配置通用 webhook 以从您的 jenkins 管道中的有效负载中读取它们的操作和合并密钥,您可以按照以下示例进行操作:https://github.com/jenkinsci/generic-webhook-trigger-plugin/blob/master/sandbox/multibranch.jenkinsfile 在您的管道中,您可以使用这些键来检查您是否要触发构建。 要在特定分支上触发合并构建,您可以在 jenkins 管道中使用环境变量,env.BRANCH_NAME 将告诉您从哪个分支获得提交

【讨论】:

我将 generic-webhook-trigger 配置为在负载中查找这些值,但我应该如何使用它们?【参考方案4】:

要回答这个“仅当拉取请求合并到特定分支时才触发构建?”问题,最简单的方法是在 Jenkins 中使用 Generic Webhook Trigger Plugin。此 Webhook 允许您将 JSON 有效负载对象用作环境变量。搜索 "How to setup Generic Webhook Trigger Plugin" ,完成 webhook 配置后,查看有效负载,您会发现许多不同的对象用作管道中的变量。使用这些变量,您可以触发构建。使用此https://jsonpath.curiousconcept.com/ 查找 JSONPath。

【讨论】:

【参考方案5】:

您可以使用 github 操作来触发 jenkins 管道

https://github.com/features/actions https://github.com/marketplace/actions/trigger-jenkins-job

【讨论】:

以上是关于在 Github 中合并拉取请求时触发 Jenkins 构建的主要内容,如果未能解决你的问题,请参考以下文章

Circle ci 触发构建拉取请求创建或更新

为 GitHub 拉取请求添加验证检查

取消操作运行,当拉取请求更改时

VSTS GitHub拉取请求触发器未触发

如何避免使用 API 延迟 github 拉取请求合并

使用 github api 从拉取请求编号获取拉取请求合并提交 sha