【效率提升】一键切换项目maven版本号的工具

1,486 阅读5分钟

背景

目前公司采用微服务架构的方式,拆分十几个甚至更多的服务,当项目版本升级时,需要项目负责人手动去切换切maven项目的版本号和所依赖项目的版本号,并执行deploy操作,相当的费时间,经常一早上的时间就过去了(摸鱼),为了提高开发效率,空闲之余研究了个小工具(shell脚本),希望对大家有所帮助。

知识准备

image.png

上面的是项目的版本号,下面的是该项目依赖的其他项目的版本号

问题原因

目前公司使用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、如果不进行以上操作(开发基础),那么第一个进行开发的人(大冤种)将是非常痛苦的,因为他无法正常打包(就是我了)。

    image.png

    呜呜呜呜呜

解决方案

话不多说直接上代码

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包怎么来怎么去一窍不通,正好通过这次编写这个脚本,熟悉了许多,也加快了日常的开发效率。

共勉: 不管做什么事情,不要觉得难就不去做,想放弃。坚持一下,就会发现也不怎么难,自己也会成就感满满。