需求背景
项目已有基于Jekins的代码检查流程,但当前流程未启用状态检查,只是单纯触发Jenkins工作流,起不到门禁的效果。
因此期望结合gitea的状态检查,由Jenkins将测试状态上报到PR后才允许合并,以此实现门禁的效果。
很奇怪,这个需求应该是很普遍的需求,但网上能找到的信息很少,因此在调通后将具体实现在此分享。
其他托管软件如gitlab、github等也都有状态检查这个功能,可以参考。
状态检查
状态检查这个功能虽然有,但是在gitea文档里描述很简单,没有提到具体怎样上报状态,又有哪些状态可以上报,这里简单说明下。
首先状态检查,可以理解为每个commit都有一个"状态"字段,这个字段是一个数组,每次通过接口上报状态时,都向这个数组里写入一条状态信息。
可以通过以下接口查询:

上报接口如下:

状态字段中,context可以理解为状态信息的标签,state是这条消息的状态,如图示的消息就可以理解为单元测试通过,而如果state为error,则表示不通过,在gitea中可以配置要求指定的所有标签都通过才允许合并。
方案实现
gitea
首先到目标仓库,点击仓库右上角的"设置",进入仓库设置页面。
然后点击"分支",点击分支保护,如果没有启用分支保护就在此新建一个。

随后在编辑分支保护配置时,勾选"启用状态检查",并在状态检查模式中填入期望检查的内容即可。

这里的状态检查模式可以自己随便写,写了啥在Jenkins工作流中上报对应的状态即可。
另外,为了在Jenkins中调用Gitea接口,这里还需要先拿到授权Token,按如下步骤跳转执行即可:

执行后,就会生成当前账号赋予权限的Token

Jenkins
由于这里每次提交应当触发代码检查的分支和commit都不一样,因此这里需要从gitea触发webhook时附带的信息中动态获取。
具体而言,就是在Jenkins配置中,在Webhook配置下,配置Post变量,也就是从Post请求的body中取值作为此次构建的变量,如下所示:

这里通过JsonPath,从pr触发附带的信息中取得此次PR的信息。
这些信息用于在Jenkins流程中拉取指定分支、上报状态信息时动态填入等。
具体用到的信息及JsonPath如下:
-
PR分支:$.pull_request.head.ref
-
PR仓库:$.pull_request.head.repo.name
-
PR状态(用于判断,如果为closePR就不触发):$.pull_request.state
-
仓库所有者:$.pull_request.head.repo.owner.username
-
PR最新commit:$.pull_request.head.sha
这些变量取得后,即可在pipeline中上报状态:
text-plain
stage('Git StatusCommit') {
agent {
label '${node}' //对应添加节点时的标签,可选择多个
}
steps {
script {
if ( PR_STATE == "open") {
sh """curl -X 'POST' \
'http://10.0.0.1/api/v1/repos/${仓库所有者}/${PR仓库}/statuses/${PR最新commit}?access_token=${这里是前面获取的gitea token}' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"context": "单元测试",
"description": "单元测试不通过",
"state": "error"
}'
}
}
}
}
以上是一个示例,注意将描述的字段替换为你设置的变量。
随后,将Webhook及此工作流对应token配置到gitea的Webhook中即可,注意触发条件,这里我勾选的是"合并请求被打开、被关闭、被重新打开或被编辑。"
实现效果
完成上述配置后,当创建一个合并请求时,就会出现如下检查提示:

遇到问题
Webhook触发失败:如果提交PR后发现Jenkins没有被触发,先检查gitea的Webhook是否有触发记录,如果没有触发记录,则为触发条件设置不正确,如果有触发记录,但发送请求失败,则根据失败的提示去分析,如Jenkins端口能否被gitea访问、Jenkins所在地址是否处于gitea配置app.ini 中 webhook允许列表中,等等。
转载声明:此博文未经本人允许,不得转载,请勿爬取