Github webhook 是什么以及它的用途
关于webhook
当 GitHub 上发生某些事件时,Webhooks 可以提供一种方式将通知传递到外部 Web 服务器。
Webhook 允许您订阅软件系统中发生的事件,并在这些事件发生时自动接收发送到您服务器的数据。
Webhook 用于实时接收数据,而不是轮询 API(间歇性调用 API)来查看数据是否可用。使用 Webhook,您只需在创建 Webhook 时表达一次对事件的关注。
Webhook 的用途非常广泛,包括:
- 在外部 CI 服务器上触发 CI(持续集成)流水线。例如,在代码推送到分支时在 Jenkins 或 CircleCI 中触发 CI。
- 将 GitHub 上发生的事件通知发送到协作平台。例如,在拉取请求获得审核时向 Discord 或 Slack 发送通知。
- 更新外部问题跟踪器(例如 Jira)。
- 部署到生产服务器。
- 在 GitHub 上实时记录事件,以便进行审计。
关于 GitHub 上的 Webhook
创建 Webhook 时,您需要指定一个 URL 并订阅 GitHub 上发生的事件。当 Webhook 订阅的事件发生时,GitHub 会向您指定的 URL 发送一个包含事件相关数据的 HTTP 请求。如果您的服务器已设置为监听该 URL 上的 Webhook 传递,则可以在收到 Webhook 时采取行动。
例如,您可以将 Webhook 订阅到以下事件:代码推送到仓库、拉取请求发起、GitHub Pages 网站构建或新成员添加到团队。您的服务器可以通过将代码部署到生产环境、触发 CI 流水线、发送通知或为新团队成员创建 GitHub 项目来响应这些事件。
您必须在特定的仓库、组织、GitHub Marketplace 帐户、GitHub Sponsors 帐户或 GitHub App 中创建 Webhook。 Webhook 只能访问安装它的仓库、组织、GitHub Marketplace 帐户、GitHub Sponsors 帐户或 GitHub App 中可用的资源。
选择 Webhook 还是 REST API
与使用 API 相比,使用 Webhook 具有以下优势:
- 与轮询 API 相比,Webhook 所需的工作量和资源更少。
- Webhook 的扩展性比 API 调用更好。如果您需要监控大量资源,那么为每个资源调用 API 可能会导致您很快达到 API 速率限制配额。您可以订阅多个 Webhook 事件,并仅在事件发生时接收信息。
- Webhook 允许近乎实时的更新,因为 Webhook 会在事件发生时触发。
如果您只需要一次或间歇性地获取信息,或者只想从一小部分资源中获取信息且没有扩展计划,则可以在需要相关信息时调用 API。
案例一: 使用Github Webhook 来启动 Jenkins 流水线
我将讲解如何设置 Github Webhook 来启动 Jenkins 流水线,并使用 Github Status API 报告构建状态检查。然后,我们将配置 Github 分支保护规则,以防止拉取请求在未通过所有状态检查的情况下被合并。
要求
- 拥有 Github 代码库的管理员权限
- 拥有 Jenkins 实例的管理员权限
假设
您有一个正在运行的 Jenkins 流水线,该流水线正在使用流水线脚本构建您的 Github 代码库。
创建 Jenkins API 令牌
首先,我们将生成一个 Jenkins API 令牌,Webhook 将使用该令牌与 Jenkins 构建作业进行通信。
前往 Jenkins 主页 > 点击您的用户名 > 配置 > 添加新令牌
为新令牌命名,并记住复制并保存该 API 令牌。
更新您的 Jenkins 构建
为构建作业添加参数
添加一个名为“payload”的字符串参数。此参数将存储来自 Webhook 的“payload”,其中包含与拉取请求相关的所有信息。
转到构建作业>配置>常规>该项目已参数化
配置构建作业以远程触发
您需要配置 Jenkins 流水线,以便能够远程触发构建。
前往“构建作业”>“配置”>“构建触发器”>“远程触发构建(例如,通过脚本)”
设置 Github Webhook 以启动构建
设置 Github 个人访问令牌
接下来,您需要设置 Github 个人访问令牌。稍后,您将使用它从 Jenkins 发送 Github 状态事件。
前往您的个人资料 > 设置 > 开发者设置 > 个人访问令牌
它的URL是: https://github.com/settings/tokens
点击“生成新令牌”。为其指定一个描述性名称。选择个人访问令牌的范围,如下所示。
选择范围后,点击“生成令牌”。
复制并保存生成的令牌。
创建一个新的 Webhook
导航到代码库的“设置”页面。
注意:您需要管理员权限才能查看“设置”选项卡。
在代码库的“设置”选项卡上,点击“Webhook”。
然后点击“添加 Webhook”。
Payload URL:https://admin:@/buildWithParameters?token=
我们在 URL 中使用 buildWithParameters 是因为构建作业使用字符串参数 Payload 进行参数化。
Content type:application/x-www-form-urlencoded(将 JSON Payload 作为名为 Payload 的表单参数发送)
选中pull request 事件
点击添加webhook
验证你的 webhook 在 Jenkins 上是否正常工作
创建拉取请求后,前往构建作业并检查新的构建作业是否已启动。如果看不到,请查看“验证你的 webhook 在 Github 上是否正常工作”子部分。
验证你的 webhook 在 Github 上是否正常工作
要确保创建拉取请求后 webhook 已启动,你需要执行以下操作:
前往代码库设置选项卡 > Webhook > 点击你之前创建的 webhook 上的“编辑”>“最近交付”(编辑页面底部)。
所有 webhook 请求都显示在这里。你可以在这里查看你的 webhook 是否已成功触发。
在此阶段
这将在创建拉取请求时启动一个 webhook,但它不会签出或构建您的拉取请求分支。
再次更新构建作业
使用 GitHub sha(哈希值)签出并构建拉取请求
现在我们需要确保构建作业能够构建拉取请求。我们可以通过使用拉取请求的 git 哈希值来实现这一点,该哈希值可以在作业的字符串参数有效负载中找到。此参数包含来自 webhook 的有效负载。
在您的 Jenkins 构建流水线脚本中,您需要从有效负载参数中检索 git 哈希值。
这可以通过执行以下操作来完成:
String payload = "${payload}" def jsonObject = readJSON text: payload String gitHash = "${jsonObject.pull_request.head.sha}"
然后您可以使用哈希检查代码:
sh "git checkout ${gitHash}"
这将允许您的 Jenkins 作业签出并构建您的拉取请求。
完成后,从 Jenkins 作业发送 Github 状态检查。
将以下变量添加到您的管道脚本中
String buildUrl = "${BUILD_URL}" String gitStatusPostUrl = "https://:x-oauth-basic@api.github.com/repos///statuses/${g
BUILD_URL:这是 Jenkins 环境变量。
在流水线脚本末尾添加以下命令
sh """ curl -X POST -H "application/json" -d '{"state":"success", "target_url":"${buildUrl}", "description":"Build Success", "context":"build/job"}' "${gitStatusPostUrl}" """
这会将 Github 状态通知发送到 Github 代码库。
我们快完成了
在此阶段,您应该能够创建一个会发送 webhook 的拉取请求。
此 webhook 将触发 Jenkins 构建作业,该作业将使用 git hash 签出并构建拉取请求。
构建作业会将 Github 状态请求发送回您的 Github 代码库。
我们只需要配置一个分支保护规则,以防止拉取请求在必要的状态检查通过之前被合并。
添加 Github 分支保护规则
前往代码库设置选项卡 > 分支 > 添加规则
在这里,您将执行以下操作: