Jenkins 自动生成二维码到构建历史

发表时间 ·

我们希望将构建好的文件自动生成下载链接,然后自动生成下载链接对应的二维码,再将二维码图片显示在 Jenkins 的构建历史(Build History)区块中。有几种不同的方法可以实现,本文介绍其中一种。

本文目的

希望能将构建好的文件传到 Jenkins 中,自动在构建历史中显示文件下载链接的二维码。如下图:

构建的文件可能来自上一个构建 Job,也可能有人工上传,本文假设需要人工上传,下面介绍详细的实现步骤:

显示二维码的原理

构建历史中的每一个 build,都由两部分组成: build name 和 build description,我们只要自动生成二维码图片(第一步),再将图片的 html 链接放入 build description (第二步)即可实现。

设置 Jenkins 允许显示 HTML

首先要让 Jenkins 允许在 build description 中显示 html 内容,这牵涉到安全性。所以在Jenkins 管理界面的全局安全配置(Configure Global Security)栏目下,寻找 “标记格式器”,如下图:

选择 Safe HTML,这样无论是 build 还是 job 的 description 都支持 html.

设置文件上传控件

在 Jenkins 里新建一个 Job,首先我们需要将待测的文件上传到 Job的 workspace 里。然后在 Job 的配置页面,新增 File Parameter :

由于控件自带的描述含混不清,这里需要解释下“文件路径”的含义。首先这个名称是误导的,这里面填入的内容,和路径毫无关系。举例来说,如果按上图中填入 testfile, 那么文件上传到 workspace 后,将发生两件事情:

  • 上传后,位于 workspace 中的文件名改为 testfile
  • 文件上传前的名称(在用户的文件系统中的名称),保存在 ${testfile}

文件预处理

接下来可以将上传的 testfile 进行一番预处理。首先在构建步骤中增加 Execute Shell,然后利用 本文上节 中的“文件路径” 变量操作,恢复原来文件的名字,并且加上时间戳。填入下面脚本:

# 假设原始文件 abc.zip

BASENAME=${testfile%.*}
# abc

EXTNAME=${testfile##*.}
# zip

TIMESTAMP=`date "+%y%m%d-%H%M%S"`
# 20191010-121101

NEWNAME=${BASENAME}-${TIMESTAMP}
# abc-20191010-121101

SHA=$(md5sum testfile)
SHA=${SHA:0:8}
# 1234abcd

mv testfile ${NEWNAME}.${EXTNAME}
# abc-20191010-121101.zip

比如说你上传了 abc.zip 文件,经过 上面这一系列 操作后,就得到 abc-20191010-121101.zip 的文件名。另外,还计算了文件的 md5,作为文件的附属信息,在后面一起呈现出来。

自动成生二维码图片

多种语言都有 生成二维码的方案 ,但是由于 上面预处理一节 使用了 shell ,所以继续使用 shell 生成二维码将更方便。

使用 fukuchi 提供的 libqrencode 库本站下载链接 )可以实现在 bash 命令行下输出 png 格式的图片。

libqrencode 库 需要安装一些组件,如果要生成 PNG 图片,则必须安装 libpng 库,它在不同的Linux发行版下,有不同的名字:

Ubuntu
# apt-get install libpng12-dev   

CentOs
# yum install libpng12-devel    

其他需要安装的组件可能有:

autoconf
automake
autotools-dev
libtool
pkg-config

组件安装好后,将压缩包(qrencode-4.0.2.tar.gz)上传到 jenkins 主机的 /usr/local/src中,执行 tar 命令解压:

# tar zxvf qrencode-4.0.2.tar.gz

在解压后的文件夹里执行下列命令:

# cd qrencode-4.0.2
# ./configure
# make
# sudo make install
# sudo ldconfig

编译后,会在 /usr/local/bin 中得到可执行文件 qrencode ,这时候在任意位置下即可直接运行:

# qrencode
qrencode version 4.0.2
Copyright (C) 2006-2017 Kentaro Fukuchi
Usage: qrencode [OPTION]... [STRING]
Encode input data in a QR Code and save as a PNG or EPS image.

  -h           display this message.
  ...

现在可以用这条命令方便的将字符串编译为一个带有其信息的 PNG 图片文件,最简单的用法:

$ qrencode -o show.png 'hello world!'

就能得到 这样一幅二维码的 PNG 文件。

接下来就可以续写 这一节 中的 shell 脚本,加入下面的命令:

DOWNLOAD=${JOB_URL}ws/${NEWNAME}.${EXTNAME}
# http://server/jenkins/job/foo/ws/abc-20191010-121101.zip

qrencode -o ${NEWNAME}.png ${DOWNLOAD}
# http://server/jenkins/job/foo/ws/abc-20191010-121101.png

上面第一行 DOWNLOAD 表示下载链接,指向 workspace 中上传的文件。第二行将下载链接转化为图片,图片的名称与文件相同。这个图片将在后面步骤里以 HTML 形式插入构建历史。

将二维码图片插入构建历史

现在生成了二维码的 PNG 文件,接着就可以显示在构建历史列表中。Jenkins 没有提供直接修改 build description 的功能,我们需要安装插件 Description Setter 。安装好后,这个插件的功能将出现在 “构建后操作步骤” 中:

这个插件的原理是,用正则表达式搜索出现在 build log 中的文字,匹配出来的第一个结果,作为 build description,

这样我们续写 上一节 中的 shell 脚本,加入下面一行:

echo "appDescription: <img src=\"${JOB_URL}ws/${NEWNAME}.png\">"

然后在 build description 设置框的 Regular expression 中填入 ^appDescription: (.*) ,Description填入 \1 ,这样就顺利的将 <img 开始的图片链接显示在构建列表内。

微调二维码图片的透明度

显示出的图片,可能有些白茫茫的。这是因为 Jenkins 的自带样式里设置了opacity,只要修改样式文件即可。样式文件在Jenkins主目录下,一般来说主目录名字叫 .jenkins (在Jenkins配置页面里显示了主目录的绝对路径),那么样式文件的路径是 .jenkins/war/css/style.css,搜索 build history,就能找到起作用的样式:

#buildHistory .desc {
  ...
  opacity: 0.6;
}

改为 1.0 即可。

在图片旁边同时显示其他信息

前面一节中 中,我们还生成了文件的MD5,为了和图片一起显示出来,我们修改 上节中 中的 shell 脚本为:

echo "appDescription: <img src=\"${JOB_URL}ws/${NEWNAME}.png\">\
<br><span><a href=\"${DOWNLOAD}\">${SHA}</a></span>"

就可以在图片下方显示文件的 MD5,同时也是下载文件的入口,一举两得。总之,有什么关键信息都可以用 HTML 片段显示在这里。

完整代码

上面介绍的 可能不是最简便的方案,但是至少是一个可行的方案。完整的 shell 脚本如下:

BASENAME=${testfile%.*}
EXTNAME=${testfile##*.}
TIMESTAMP=`date "+%y%m%d-%H%M%S"`
NEWNAME=${BASENAME}-${TIMESTAMP}
SHA=$(md5sum testfile)
SHA=${SHA:0:8}
mv testfile ${NEWNAME}.${EXTNAME}
DOWNLOAD=${JOB_URL}ws/${NEWNAME}.${EXTNAME}
qrencode -o ${NEWNAME}.png ${DOWNLOAD}
echo "appDescription: <img src=\"${JOB_URL}ws/${NEWNAME}.png\">\
<br><span><a href=\"${DOWNLOAD}\">${SHA}</a></span>"

下载认证问题

如果 Jenkins 系统需要登录,那么上传到 workspace 中的文件就不能匿名下载。不过这不是难事,可以参考 这篇文章 搭建一个匿名下载服务器。然后在 shell 脚本mv 一步直接转移到下载服务器内,即可匿名下载。


相关文章   欢迎到 留言板 写下你的看法。
  本页面内容采用 署名协议 CC-BY 授权。欢迎转载,请保留原文链接