背景
目前公司采用微服务架构的方式,拆分十几个甚至更多的服务,当项目版本升级时,需要项目负责人手动去切换切maven项目的版本号和所依赖项目的版本号,并执行deploy操作,相当的费时间,经常一早上的时间就过去了(摸鱼),为了提高开发效率,空闲之余研究了个小工具(shell脚本),希望对大家有所帮助。
知识准备
上面的是项目的版本号,下面的是该项目依赖的其他项目的版本号
问题原因
目前公司使用nexus搭建maven私服,来管理maven仓库。在项目打包的时候会从nexus上获取对应的项目maven版本,那当公司的项目此时结束了一个版本的开发,此时需要切出新的分支,用于新版本的开发。此时整个的操作流程如下:
-
1、先将项目的旧版本号(41.2.0.0-premise)升级为新版本号(41.3.0.0-premise)后,依赖项目的版本号(41.2.0.0-primise)暂时不升,然后进行deploy操作,将上传该项目的maven至nexus仓库。所有项目的项目都需要这一步的操作。
-
2、将所有项目依赖的其他服务的旧版本号修改至新版本号(41.3.0.0-premise),再重新depoly,保证每个项目依赖的其他项目都是最新版本。所有项目的项目都需要这一步的操作。
误区解答
- 1、为什么不能在修改项目的maven版本号的同时修改依赖的项目的版本号,再进行depoly操作。
答:举例项目-用户中心,依赖着通知服务。若都修改了新的版本号(41.3.0.0-premise),进行depoly操作,会报找不到通知服务maven对应的版本41.3.0.0-premise,因为此时通知服务还未进行depoly操作,将包上传至nexus。 自然找不到这个版本的包,所以此时只能先使用旧版本的进行打包。
- 2、为什么要升级依赖项目的版本号。
答:1、避免引用之前项目的开发错误版本,导致项目出现问题。 2、保证项目过程的统一的版本号。
以上的操作流程暴露出的问题
-
1、每个项目均需要进行maven版本号的替换和对依赖服务的版本号升级的操作,并进行depoly操作,当项目很多的时候,时间成本很高,同时也很容易出现漏切、误切的情况。
-
2、如果不进行以上操作(开发基础),那么第一个进行开发的人(大冤种)将是非常痛苦的,因为他无法正常打包(就是我了)。
呜呜呜呜呜
解决方案
话不多说直接上代码
1、新建一个文件batch-change-version.sh。
#!/bin/bash
#!/bin/bash
source changeVersion.conf
# 使用maven语句 批量修改版本号
function change_version ()
{
git stash
git checkout -b changeVersion/$targetBranch origin/$originBranch
mvn versions:set -DnewVersion=$target_brick_box_version
mvn versions:commit
#修改依赖版本号
#sed -i 's/'$originVersion'/'$targetVersion'/g' "$1"
}
# 进行depoly时,对应的maven账号应具有depoly的权限,没有的话,应先在修改settings.xml中添加最高权限的用户账号。
function deploy_to_nexus ()
{
mvn clean deploy -Dmaven.test.skip=true
# 判断上一条语句的执行结果,并将失败的项目,输出至versionsError.log中,方便排查。
if [ $? -ne 0 ];then
echo '***[' $(date "+%Y-%m-%d %H:%M:%S") ']***deploy fail ----> ' $1 >> ../versionsError.log
echo -e "\033[31m *********deploy" $1 "项目失败**********! \033[0m"
else
echo '*********deploy' $1 '项目成功!*********'
fi
}
#第一次循环做修改mavne版本号的操作函数
function update_maven_version ()
{
LINE=$1
echo "================first:"$1
cd "$LINE"
tmp="uc-"
result=$(echo $LINE | grep "${tmp}")
#判断是否是代码(相对数据库脚本),由于本人公司的数据库脚本项目UC-开头,且脚本项目无需改变maven版本,故进行排除。
if [[ -z "$result" ]];then
git stash
git checkout -b changeVersion/$targetBranch origin/$originBranch
mvn versions:set -DnewVersion=$targetVersion
mvn versions:commit
deploy_to_nexus "$LINE"
fi
}
#第二次循环做修改其项目所依赖项目的版本号
function update_project_dependent_version (){
echo "================second:"$1
LINE=$1
cd "$LINE"
tmp="uc-"
result=$(echo $LINE | grep "${tmp}")
#判断是否是代码(相对数据库脚本)
#由于本人公司的数据库脚本项目UC-开头,且脚本项目无需改变maven版本,故进行排除。
if [[ -z "$result" ]];then
#修改依赖版本号
sed -i 's/'$originVersion'/'$targetVersion'/g' ./pom.xml
deploy_to_nexus "$LINE"
git add .
git commit -m "feat(*):"$release_target_branch"开发基础"
else
#切开发环境的分支
git checkout -b changeVersion/$targetBranch origin/$originBranch
fi
#push 开发环境的分支
git push origin changeVersion/$targetBranch:$targetBranch
#切正式版本的分支
git checkout -b changeVersion/$release_target_branch origin/$release_origin_branch
git push origin changeVersion/$release_target_branch:$release_target_branch
}
#多线程进程数量限制常量定义(为加快效率,采用多线程的方式,来并发执行)
starttime=`date +'%Y-%m-%d %H:%M:%S'`
tmp_fifofile="/tmp/$$.fifo"
mkfifo $tmp_fifofile # 新建一个fifo类型的文件
exec 6<>$tmp_fifofile # 将fd6指向fifo类型
rm $tmp_fifofile
thread_num=3 # 最大可同时执行线程数量,可根据电脑性能自行调整
#根据线程总数量设置令牌个数
for ((i=0;i<${thread_num};i++));do
echo
done >&6
find `pwd` -type d -name ".git" > git_dir.txt
sed -i "s/\/.git/\//g" git_dir.txt
# 第一遍循环只修改自身版本号并deploy
while read LINE
do
{
# 一个read -u6命令执行一次,就从fd6中减去一个回车符,然后向下执行,
# fd6中没有回车符的时候,就停在这了,从而实现了线程数量控制
read -u6
#可以把具体的需要执行的命令封装成一个函数
{
update_maven_version "$LINE"
} &
echo >&6 # 当进程结束以后,再向fd6中加上一个回车符,即补上了read -u6减去的那个
}
done < git_dir.txt
wait
# 第二遍修改依赖版本号并deploy
while read LINE
do
{
echo "进入第二遍循环"
# 一个read -u6命令执行一次,就从fd6中减去一个回车符,然后向下执行,
# fd6中没有回车符的时候,就停在这了,从而实现了线程数量控制
read -u6
#具体的操作函数
{
update_project_dependent_version "$LINE"
} &
echo >&6 # 当进程结束以后,再向fd6中加上一个回车符,即补上了read -u6减去的那个
}
done < git_dir.txt
wait
exec 6>&- # 关闭fd6
endtime=`date +'%Y-%m-%d %H:%M:%S'`
start_seconds=$(date --date="$starttime" +%s);
end_seconds=$(date --date="$endtime" +%s);
echo "本次最终运行的时间: "$((end_seconds-start_seconds))"s"
#如果公司有组件的项目,应先在循环前,先按这样的方式,处理组件项目。同时在循环中特殊处理对应的组件项目。
2、新建一个文件changeVersion.conf
############ 批量修改配置文件
################# 切dev分支,并在目标分支修改版本号 ###########
###源dev分支
originBranch=xxxx-sp3-dev
###目标分支
targetBranch=xxxx-sp4-dev
################ 修改依赖版本号 #################
#原版本号
originVersion="xx.3.0.0-premise"
#目标版本号
targetVersion="xx.4.0.0-premise"
############## 切release分支 ##################
#原分支
release_origin_branch=xxxx-sp3
#目标分支
release_target_branch=xxxx-sp4
3、在这2个文件目录下,准备好需要批量切换的项目,可配合之前的博客一起使用。git一键克隆、更新、切换分支
4、打开git bash Here执行./batch-change-version.sh,好处是即使异常中止了,可以看的到报错,方便排查。
5、执行完后,可上git仓库和nexus仓库看看结果是否正确。
总结
作为一个职场新人,一开始对nexus和maven这一块也不太熟悉,maven包怎么来怎么去一窍不通,正好通过这次编写这个脚本,熟悉了许多,也加快了日常的开发效率。
共勉: 不管做什么事情,不要觉得难就不去做,想放弃。坚持一下,就会发现也不怎么难,自己也会成就感满满。