持续集成 Jenkins 获取上游触发 Job 的相关信息

rihkddd · 2020年01月21日 · 2786 次阅读

问题

最近测试的一个系统模块较多,因此想每个模块的 Jenkins 成功构建之后,就自动把测试环境的改模块进行更新。各个模块的构建 Job 已经编写完了,由于我们的上线系统依赖于 Jenkins 的构建 Job,因此在能不修改各个模块的构建 Job 的前提下尽量不修改。

Jenkins 在构建触发器中提供了一种触发方式:指定一个或者多个上游 Job 构建后触发自身 Job 构建,在关注的项目添加希望触发的上游 Job 即可。

这里的问题在于,Job 编写的过程中往往希望可以获取一些上游 Job 的信息,以便做相应的流程处理,例如:根据上游的 Job 名字获取上游 Job 最新构建的产物,根据上游 Job 触发的参数做不同的动作。

但是目前 Jenkins 没有直接提供这个功能。该类需求通常的做法是,在上游 Job 中使用构建后操作添加Trigger parameterized build on other projects步骤来实现,此步骤可以配置相关的参数传递给下游 Job。

但是如前文所说,是否能在不修改上游 Job 的前提下完成我们的目标呢?

解决思路

对于我们的目标 Job A,首先按照构建触发器中添加上游 Job 的思路完成配置,尝试触发上游 Job,成功构建后,可以看到 Job A 的控制台输出信息中有这样的输出:

日志中我们可以看到,上游触发 Job 的名字,build number 都包含在了输出中,甚至还包含了上游 Job 的触发人。
有了这些信息,剩下的事情就好办了,我们只需要根据日志输出使用正则批评获取相关信息即可。

下面 shell 为例展示获取上游 Job name 和 build number,里面 grep 的正则部分使用了零宽断言技巧,BUILD_URL 是 Jenkins 的环境变量,表示当前构建的 url。

log=$(curl -s ${BUILD_URL}consoleText | head -n 1)
p_job=$(echo $log | grep -oP '(?<=Started by upstream project ").*(?=")')
p_build_number=$(echo $log | grep -oP '(?<=build number ).*')

扩展

有同学会有疑惑,仅仅获取了上游 Job name 和 build number 有什么用呢?其实,到这一步,熟悉 Jenkins 的同学应该就想到了,利用 Jenkins 提供的 API,我们基本上可以获取上游 Job 的一切信息。

举几个例子:

  1. 获取上游 Job 的构建参数,我们根据 Jenkins 的 url 规则拼出 Json API 的接口地址,请求后解析 Json 抽取相关字段。

    param=$(curl -s -X GET ${JENKINS_URL}/job/${p_job}/${p_build_number}/api/json | jq .actions[0].parameters[1].value)
    

    其中 jq 是解析 json 的命令行工具。

  2. 获取上游 Job 的构建产物。

    wget -q ${JENKINS_URL}/job/${p_job}/${p_build_number}/artifact/archive/deploy.tar.gz
    
  3. 获取上游 Job 的构建是否成功。

param=$(curl -s -X GET ${JENKINS_URL}/job/${p_job}/${p_build_number}/api/json | jq .result)

基于/api/json 这个接口,可以获取本次构建的大部分信息,而 config.xml 接口,可以获取 Job 本身的大部分配置信息。熟悉这两个接口,并灵活应用,基本上可以覆盖我们的绝大部分需求了。

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册