jenkins多分支版本备份
jenkins多分支版本备份
今天左腰有点酸痛,昨晚也睡得晚,写完早点洗洗睡。。。
上一篇文章说到多分支版本发布到远程机器上,用插件:Active Choices Parameter 进行多分支版本号显示到控制台,但定义的变量在配置“Send build artifacts over SSH” 上引用不了的。最后想到在jenkins机器上新建一个版本信息文件跟发布包一并发布到远程,远程机器再读这个文件,去取上一个版本号来备份即可。
这文章顺带结合之前版本号同步回gitlab上,所以做的工作如下:
(1)jenkins发布前,看到所发布分支的当前/上一个版本号(old_version),和将要发布的版本号(new_version);
(2)jenkins发布时:修改gitlab项目.env文件的版本号记录文件(每发布一次,版本号最后一个数字递增1),编译,并将该.env同步回gitlab;
自己额外新建一个版本信息文件version.txt,写入上一个版本号,和这次发布的版本号,跟编译发布好的包一起发到远程机器上;
编译发布好的包的命名格式:
{项目名关键字}-{分支号}_{将要发布的版本号}_{发布时间}
(3)jenkins发布后:远程机器旧包备份,命名格式:
{项目名关键字}-{分支号}_{旧版本号}_{发布时间}
解压发布过来的包:{项目名关键字}-{分支号}_{将要发布的版本号}_{发布时间} 到运行目录
下面先简单介绍测试环境,再放效果图让大家有个感性认识,最后附上具体配置。
一、测试环境准备
1、提前做好的分支版本号记录文件(跟项目里面的.env不是同一个)
该文件用jenkins运行用户写入的。
每个分支对应一个记录文件,在下面具体配置里的这个目录:/var/lib/jenkins/scripts/xxx/get_version/admin/{分支名字}
这里准备了两个测试分支:test、test1。也就有两个记录文件
(1)/var/lib/jenkins/scripts/xxx/get_version/admin/test/admin-test_version.txt
(1)/var/lib/jenkins/scripts/xxx/get_version/admin/test1/admin-test1_version.txt
记录格式:
项目名关键字 分支名 版本号 发布时间
两个文件的内容如下:

2、确保gitlab上的.env跟分支版本号记录文件对应上
二、测试效果图:
假设发布test分支,当前版本号(old_version)为 v1.0.6
远程机器确认
(1)发布包临时存放目录(wars目录):有版本号为v1.0.7.tar.gz 的压缩文件

(2)发布目录:版本号为 v1.0.7的文件
(3)备份目录(bak目录):有版本号为v1.0.6的备份文件
三、具体设置:
里面用到一个shell的子串处理,参考:https://blog.csdn.net/github_33736971/article/details/53980123
1、控制台选择分支显示上一个和将要发布的版本号
添加选项参数:branch,选项值为test、test1
old_version 和 new_version 参考之前的jenkins单分支版本备份【https://www.cnblogs.com/windysai/p/16195537.html】
2、构建设置
##### 1、jenkins工作区间版本号替换再编译 #### 1.1、版本号获取和递增 old_ver=`cat .env |awk -F'=' '{print $2}' | tr -d "'"` last_num=`echo $old_ver | awk -F'.' '{print $NF}'` ##版本号最后一个数字加1 this_num=$(($last_num+1)) #截取版本号最后一个数字前面 begin_num=`expr substr "$old_ver" 1 5` #拼接为将要发布的版本号 new_ver=$begin_num$this_num #### 写入版本号信息到文件,插件参数不生效,要重新计算 #old_ver=`echo $old_version | tr -d "[" | tr -d "]"` #new_ver=`echo $new_version | tr -d "[" | tr -d "]"` #### 该方法不生效,要重新计算 DATE=`date +%Y%m%d_%H:%M:%S` ## 分支、版本号记录 echo admin $branch ${new_ver} $DATE >> /var/lib/jenkins/scripts/xxx/get_version/admin/${branch}/admin-${branch}_version.txt #### 1.2、文件版本号替换 sed -i "s/${old_ver}/${new_ver}/" .env ##### 2、更新文件版本号,上传到gitlab ssh {jenkins机器某登录用户}@{jenkins机器ip} "sh -x /home/{jenkins机器某登录用户}/scripts/update_version/update_admin.sh $branch" ## 3、编译(编译后会生成dist目录) npm install npm run build:test ## 创建发布到远程机器的目录,包含编译号的包+版本信息文件(version.txt) mkdir admin-${branch}_${new_ver} ## 信息文件:分支号 旧版本号 新版本号 touch version.txt echo $branch ${old_ver} ${new_ver} > version.txt ## 信息文件+发布包 mv version.txt admin-${branch}_${new_ver} cp -rp dist admin-${branch}_${new_ver}/ tar -zcf admin-${branch}_${new_ver}.tar.gz admin-${branch}_${new_ver}
3、构建后操作
(1)归档成品:**/*.tar.gz
(2)Send build artifacts over SSH

最后附上:admin-ljy发布脚本

#!/bin/bash ## 版本号、分支号 branch=$1 echo "发布分支:" $branch ## jenkins拷贝过来的临时目录 DIST_DIR=/home/xxx/wars/xxx/admin cd ${DIST_DIR} Tar_FileName=`ls -lht *${branch}*.tar.gz | head -n1 | awk '{print $9}'` ## 解压目录名(字符串处理,去掉.tar.gz剩余的前面部分) FileName=`echo ${Tar_FileName/.tar.gz/}` tar -xvf ${Tar_FileName} cd ${FileName} ## 获取上一次和这次的版本号 old_version=`cat version.txt | awk '{print $2}'` new_version=`cat version.txt | awk '{print $3}'` DATE=`date +%Y%m%d_%H:%M:%S` ## 备份目录 BAK_DIR=/home/xxx/bak #备份目录,不存在就创建 [ ! -d $BAK_DIR ] && mkdir -p $BAK_DIR ## 发布目录 - 测试ljy DEPLOY_DIR=/home/xxx Admin_DIR=${DEPLOY_DIR}/admin ## 1、备份原目录 if [ -d ${Admin_DIR} ]; then if [ ! -d ${BAK_DIR}/admin ]; then mkdir -p ${BAK_DIR}/admin fi /bin/mv ${DEPLOY_DIR}/admin ${BAK_DIR}/admin/admin-${branch}_${old_version}_$DATE fi ## 2、发布目录,不存在就创建 [ ! -d ${Admin_DIR} ] && mkdir -p ${Admin_DIR} ## 3、发布代码 /bin/cp -rp ${DIST_DIR}/${FileName}/dist/* ${Admin_DIR}/ exit 0
总结:
其实实现这个需求的时候,有个痛点,但无奈技术水平有限,没找到合适的解决方法。。。
体现在插件上new_version和old_version的定义上,方法很蠢,不够灵活:用了if条件判断所发布分支是什么,然后跑对应的脚本。想想如果项目要切换很多分支,条件判断就会很冗长,本来想用变量传参的方式给groovy去读发布分支这个变量,类似这样:
def command='sh get_version.sh $branch'
这样写是报错的,所以没找到好的方法,只能用这种笨方法了