基于 Jenkins 实现 Gogs 的 Pull Request 自动构建

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaosongluo/article/details/80151474

0x00 这玩意儿是啥

首先我们要弄清楚 Pull Request 自动构建是啥,就需要分别说清楚 Pull Request 的意义以及 Pull Request 自动构建的意义:

  • Pull Request 的意义:开发人员通过发出 Pull Requests 请求他人将自己贡献的代码拉下来进行代码审查,从而让自己贡献的代码可以顺利合并到代码仓库的指定分支。

  • Pull Request 自动构建的意义:在 Pull Requests 中,自动地检测待审核的代码能否可以编译完成、通过所有测试、满足编码规范等工作,协助代码审核人员快速审核。

如下图所示,在 Github 中,Travis-CI 等工具可以很方便地协助我们完成 Pull Request 自动构建。

Sample for PR  auto tool in Github

但是对于公司内部项目而已,可能没办法选择 Github + Travis-CI 的方案,那就需要我们自己来搭建了。

就我司而已,目前源码仓库选择在 Gogs 中进行管理,持续集成选择 Jenkins,因此本文主要也就是在探索如何基于 Jenkins 实现 Gogs 的 Pull Request 自动构建。

0x01 Step 1:监听 Pull Request 事件

通常,我们在 Jenkins 上搭建的自动化构建大多都是监听源码仓库中某些分支的 PUSH 事件。有两种方法可以实现这一目的:

  1. 基于 Jenkins 中构建触发器的 Build periodically 定期去检测源码仓库是否有更新;
  2. 在特定事件(如PUSH/Pull Request)发生时,使用源码仓库中 Webhook 主动触发 Jenkins 的指定任务;

显然,为了让Jenkins 可以自动响应 Pull Request 事件,我们只能采取 Webhook 的方案。

从 Webhook 的实现原理:在特定事件(如PUSH/Pull Request)发生时,使用源码仓库中 Webhook 主动触发 Jenkins 的指定任务,可以得知 Jenkins 是信息的消费者,而源码仓库是信息的生产者,他们需要分别配置:

在 Jenkins 中的配置

首先,我们需要明确一点:Jenkins 自身无法处理 Webhook 事件,因此,我们需要第三方插件的协助。综合考量我们的需求,目前仅有 Generic Webhook Trigger Plugin 满足要求。

如下图所示,安装 Generic Webhook Trigger Plugin 之后,我们在 Jenkins 中创建一个名为 GogsPullRequestTest 的自动构建任务,在其构建触发器中,勾选启用“ Generic Webhook Trigger”,即可完成相关配置。

Enable Generic Webhook Trigger in Jenkins

在 Gogs 中的配置

由于 Gogs 默认支持 Webhook,因此,我们仅需如下图所示,在项目的仓库设置中添加一个新的 Gogs 的 Webhook 即可。

Set Webhook in Gogs

而 Webhook 中的具体内容填写方式如下:
1. 推送地址(必填):设置为 Generic Webhook Trigger 提供的地址:
- 推送给所有 Jenkins 任务:http://JENKINS_URL/generic-webhook-trigger/invoke
- 推送给名为 task 的 Jenkins 任务:http://JENKINS_URL/generic-webhook-trigger/invoke?token=[task]
2. 数据格式:设置为application/json
3. 密钥文本:为空
4. 请设置您希望触发Web钩子的事件:我们仅关注Pull Request,因此选择指定事件中的合并请求
5. 是否激活:勾选

这里写图片描述

完成配置后,我们在 Gogs 中创建一个 Pull Request,即可出发 Jenkins 中 GogsPullRequestTest 的自动构建。

0x02 Step 2:获取 Webhook 中具体的事件信息

第一步完成之后,虽然我们已经可以实现 Gogs 的 Pull Request 自动构建,但是还有两个关键问题还没解决:

  1. 如何获取 Pull Request 中基准分支/对比分支具体是什么?
  2. 如何仅针对 Pull Request 的 开启事件进行自动构建?

如果这两个问题不解决, 自动构建触发时 Jenkins 就没法知道需要去哪个分支拉代码,而且更严重的是 Pull Request 的关闭,编辑,指派,标签设置,里程碑设置,评论等等都会触发自动构建任务!

问题虽复杂,但 Generic Webhook Trigger 插件已经帮我们把上述问题的解决思路抽象为两个功能:

  1. 如何从 Webhook 中获取变量
  2. 如何对 Webhook 进行过滤

如何从 Webhook 中获取变量

Generic Webhook Trigger 可以获取的变量有三种类型,获取到的变量会自动注册为该 Jenkins 任务的系统变量,可以通过 $parameter_name 的方式进行使用。

Post content parameters

这类变量从 POST 的具体内容中获取,格式支持JSON/XPATH,具体为:

  • Variable:是变量名
  • Expression:是变量的获取方式
  • Value filter:需要过滤的变量内容,一般不填
  • Default value:变量默认值,一般不填

其中,如果将 Expression 中设置为 $.a.b.c,即可获取到出下面 JSON 中的“value”。

{
    "a":{
        "b":{
            "c":"value"
        }
    }
}

Header parameters

这类变量从 Header 中获取,具体为:

  • Request header:变量名即参数名
  • Value filter:需要过滤的变量内容,一般不填

需要注意的是,获取到的变量名是小写字母的形式,且将会用 ‘_’ 字符代替 ‘-’ 字符。

Request parameters

这类变量从 URL 的 Request 参数中获取,具体为:

  • Request parameter:变量名即参数名
  • Value filter:需要过滤的变量内容,一般不填

如何对 Webhook 进行过滤

Generic Webhook Trigger 中 Optional filter 部分即可配置过滤策略。其中:

  • Expression:设置过滤(通过)的条件,通过正则方式进行判断
  • Text:带过滤的文本内容,可以使用系统变量(上一部中获取了很多系统变量就可以在这里使用)

具体的配置项

了解了具体的方法之后,回到我们最初的目的:

  1. 如何获取 Pull Request 中基准分支/对比分支具体是什么?
  2. 如何仅针对 Pull Request 的 开启事件进行自动构建?

因此,我们在 Generic Webhook Trigger 中的具体配置如下:

  • Post content parameters

    参数 head_branch
    Variable:head_branch (Pull Request 的对比分支)
    Expression:$.pull_request.head_branch

    参数 base_branch
    Variable:base_branch (Pull Request 的基准分支)
    Expression:$.pull_request.base_branch

    参数 action
    Variable:action (Webhook 的事件内容)
    Expression:$.action

    参数 number
    Variable:number(Pull Request 的具体 ID)
    Expression:$.pull_request.number

  • Header parameters

    参数 x_gogs_event(Webhook 的事件类别)
    Request header:X-Gogs-Event

  • Optional filter
    过滤策略:1.必须为 pull_request 事件类别下的 opened 事件;2.基准分支必须为 develop
    Expression: pull_request_opened_develop
    Text: $x_gogs_event_$action_$base_branch

需要说明的是:

  1. head_branch 变量(Pull Request 的对比分支)将用于获取真正待测试的源码分支。
  2. number 变量(Pull Request 的具体 ID)将在第三步中用于确定具体的URL地址。

0x03 Step 3:将构建结果回传到 Gogs 的 Pull Request 中

注意:目前 Gogs 的 Pull Request API 尚未确定最终版本,目前是与 Issue API 共用一套接口,后续可能会变更。

通过 Gogs Wiki in Github ,可以拿到当前 Pull Request 的接口:

Create A Comment API

我们可以通过 Jenkins 的 HTTP Request Plugin 插件(当然也可以使用其他方法)在构建步骤中来完成构建结果的回传。这里,我们会用的之前获取的 number 变量(Pull Request 的具体 ID),用于确定具体的URL地址。

Result

到这里,我们就基本完成了Gogs 的 Pull Request 自动构建主要工作。当然,构建的内容还需要根据项目的具体要求进行设置,这里就不具体展开了。

猜你喜欢

转载自blog.csdn.net/xiaosongluo/article/details/80151474