基于 Jenkins 实现 Gogs 的 Pull Request 自动构建
0x00 这玩意儿是啥首先我们要弄清楚 Pull Request 自动构建是啥,就需要分别说清楚 Pull Request 的意义以及 Pull Request 自动构建的意义:Pull Request 的意义:开发人员通过发出 Pull Requests 请求他人将自己贡献的代码拉下来进行代码审查,从而让自己贡献的代码可以顺利合并到代码仓库的指定分支。Pull Request 自动构...
0x00 这玩意儿是啥
首先我们要弄清楚 Pull Request 自动构建是啥,就需要分别说清楚 Pull Request 的意义以及 Pull Request 自动构建的意义:
-
Pull Request 的意义:开发人员通过发出 Pull Requests 请求他人将自己贡献的代码拉下来进行代码审查,从而让自己贡献的代码可以顺利合并到代码仓库的指定分支。
-
Pull Request 自动构建的意义:在 Pull Requests 中,自动地检测待审核的代码能否可以编译完成、通过所有测试、满足编码规范等工作,协助代码审核人员快速审核。
如下图所示,在 Github 中,Travis-CI 等工具可以很方便地协助我们完成 Pull Request 自动构建。
但是对于公司内部项目而已,可能没办法选择 Github + Travis-CI 的方案,那就需要我们自己来搭建了。
就我司而已,目前源码仓库选择在 Gogs 中进行管理,持续集成选择 Jenkins,因此本文主要也就是在探索如何基于 Jenkins 实现 Gogs 的 Pull Request 自动构建。
0x01 Step 1:监听 Pull Request 事件
通常,我们在 Jenkins 上搭建的自动化构建大多都是监听源码仓库中某些分支的 PUSH 事件。有两种方法可以实现这一目的:
- 基于 Jenkins 中构建触发器的 Build periodically 定期去检测源码仓库是否有更新;
- 在特定事件(如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”,即可完成相关配置。
在 Gogs 中的配置
由于 Gogs 默认支持 Webhook,因此,我们仅需如下图所示,在项目的仓库设置中添加一个新的 Gogs 的 Webhook 即可。
而 Webhook 中的具体内容填写方式如下:
- 推送地址(必填):设置为 Generic Webhook Trigger 提供的地址:
- 推送给所有 Jenkins 任务:http://JENKINS_URL/generic-webhook-trigger/invoke
- 推送给名为 task 的 Jenkins 任务:http://JENKINS_URL/generic-webhook-trigger/invoke?token=[task]
- 数据格式:设置为application/json
- 密钥文本:为空
- 请设置您希望触发Web钩子的事件:我们仅关注Pull Request,因此选择指定事件中的合并请求
- 是否激活:勾选
完成配置后,我们在 Gogs 中创建一个 Pull Request,即可出发 Jenkins 中 GogsPullRequestTest 的自动构建。
0x02 Step 2:获取 Webhook 中具体的事件信息
第一步完成之后,虽然我们已经可以实现 Gogs 的 Pull Request 自动构建,但是还有两个关键问题还没解决:
- 如何获取 Pull Request 中基准分支/对比分支具体是什么?
- 如何仅针对 Pull Request 的 开启事件进行自动构建?
如果这两个问题不解决, 自动构建触发时 Jenkins 就没法知道需要去哪个分支拉代码,而且更严重的是 Pull Request 的关闭,编辑,指派,标签设置,里程碑设置,评论等等都会触发自动构建任务!
问题虽复杂,但 Generic Webhook Trigger 插件已经帮我们把上述问题的解决思路抽象为两个功能:
- 如何从 Webhook 中获取变量
- 如何对 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:带过滤的文本内容,可以使用系统变量(上一部中获取了很多系统变量就可以在这里使用)
具体的配置项
了解了具体的方法之后,回到我们最初的目的:
- 如何获取 Pull Request 中基准分支/对比分支具体是什么?
- 如何仅针对 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
需要说明的是:
- head_branch 变量(Pull Request 的对比分支)将用于获取真正待测试的源码分支。
- number 变量(Pull Request 的具体 ID)将在第三步中用于确定具体的URL地址。
0x03 Step 3:将构建结果回传到 Gogs 的 Pull Request 中
注意:目前 Gogs 的 Pull Request API 尚未确定最终版本,目前是与 Issue API 共用一套接口,后续可能会变更。
通过 Gogs Wiki in Github ,可以拿到当前 Pull Request 的接口:
我们可以通过 Jenkins 的 HTTP Request Plugin 插件(当然也可以使用其他方法)在构建步骤中来完成构建结果的回传。这里,我们会用的之前获取的 number 变量(Pull Request 的具体 ID),用于确定具体的URL地址。
到这里,我们就基本完成了Gogs 的 Pull Request 自动构建主要工作。当然,构建的内容还需要根据项目的具体要求进行设置,这里就不具体展开了。
更多推荐
所有评论(0)