分享一段自动化编译部署的shell脚本,适用于Java多工程以及代码存储在Subversion仓库的项目,可根据参数指定是否合并增量代码、编译和部署指定的工程。
#!/bin/bash # Java多工程项目自动化编译部署脚本 # 自SVN仓库获取源码至编译机,编译打包后再发布至应用服务器 # 编译服务器:10.10.10.10 # 应用服务器:10.10.10.20 10.10.10.21 10.10.10.22 # 脚本参数说明 # -a 指定本次需要部署的工程列表(用于多个工程的项目) # -v 增量代码在仓库中的版本目录(有增量代码时先合并) # ./autoDeployJava.sh -a 'project1 project2 project3' -v 'JAVA_PROJ_NAME_versionPath_20230215/code' # 项目名称 projName="101010_PROJECT_NAME" # 代码仓库信息 svnPath="svn://10.10.10.100/${projName}/code" svnUser="admin" svnPass="admin123456" # 增量代码仓库 verPath="svn://10.10.10.100/${projName}/vers" # 本地工作空间 workDir="${PWD}/CODES/${projName}" # 编译环境信息 jdkPath="/usr/local/jdk1.8.0_271" mvnPath="/usr/local/apache-maven-3.0.4" #antPath="/usr/local/apache-ant-1.8.2" # 编译配置信息 setFile="${mvnPath}/conf/settings_${projName}.xml" repPath="/data/.m2/${projName}" # 应用工程列表 appList=("project1" "project2" "project3" "project4" "project5") # 应用主机列表 hstList=("10.10.10.20" "10.10.10.21" "10.10.10.22") # 应用部署信息 deployUsr="weblogic" deployDir="/home/${deployUsr}/apps" # 部署日志文件 deployLog="${PWD}/deploy_${projName}.log" # 获取输入参数 while getopts 'a:v:' OPT do case ${OPT} in a) deployLst="$OPTARG";; v) deployVer="$OPTARG";; esac done # 未输入版本号时确认是否继续 # 无版本号时将不执行版本合并 while [ -z "${deployVer}" ] do read -p "未输入版本号,确定不用合并代码吗?输入'Y'继续部署,输入'E'退出脚本..." toNEXT [ "${toNEXT^^}" = "Y" ] && break [ "${toNEXT^^}" = "E" ] && exit 2 done # 重置待部署的应用列表 [ -n "${deployLst}" ] && appList=(${deployLst}) while [ -z "${deployLst}" ] && [ "${#appList[*]}" -ge 2 ] do read -p "未指定应用列表,确定部署全部应用吗?输入'Y'继续部署,输入'E'退出脚本..." toNEXT [ "${toNEXT^^}" = "Y" ] && break [ "${toNEXT^^}" = "E" ] && exit 2 done # 获取当前时间 getTime (){ nowTime=`date +'%Y-%m-%d %H:%M:%S'` } # 处理执行结果 getResult () { [ ${getStatus} -ne 0 ] && getTime && echo -e "${nowTime}\t上一条命令执行失败\n" >> ${deployLog} && exit 1 } getTime echo ">>>>>>>>>> ${projName} - ${nowTime:0:8} <<<<<<<<<<" >> ${deployLog} # 检查基本环境 [ ! -d "${workDir}" ] && getTime && mkdir -p ${workDir} && echo -e "${nowTime}\t创建工作空间基本目录" >> ${deployLog} # 合并(将增量代码合并至全量代码库) mergeCode (){ getTime echo -e "${nowTime}\t合并版本${deployVer}" >> ${deployLog} ./mergeCode.sh -a ${projName} -c ${svnPath} -v ${verPath}/${deployVer} -u ${svnUser} -p ${svnPass} getStatus=$? [ ${getStatus} -eq 8 ] && getTime && echo -e "${nowTime}\t代码末端目录没有匹配时主动退出\n" >> ${deployLog} && exit 1 [ ${getStatus} -eq 9 ] && getTime && echo -e "${nowTime}\t核对DIFF差异遇到问题时主动退出\n" >> ${deployLog} && exit 1 getResult } # 检出 checkoutCode (){ cd ${workDir} for appName in ${appList[@]} do getTime [ -d "${appName}" ] && verInfo=`svn info ${appName} | grep -Ew "Revision|版本" | awk '{print $2}'` || verInfo=0 [ -z "${verInfo}" ] && verInfo=0 if [ ${verInfo} -ge 1 ] then echo -e "${nowTime}\t更新代码${svnPath}/${appName}" >> ${deployLog} svn update ${appName} --username ${svnUser} --password ${svnPass} getStatus=$? else [ -d "${appName}" ] && rm -rf ${appName} echo -e "${nowTime}\t检出代码${svnPath}/${appName}" >> ${deployLog} svn checkout ${svnPath}/${appName} ${appName} --username ${svnUser} --password ${svnPass} getStatus=$? fi getResult done } # 编译 compileApp (){ [ ! -d "${repPath}" ] && echo -e "${nowTime}\t依赖仓库${repPath}不存在\n" >> ${deployLog} && exit 1 [ ! -e "${setFile}" ] && echo -e "${nowTime}\t配置文件${setFile}不存在\n" >> ${deployLog} && exit 1 getTime for appName in ${appList[@]} do cd ${workDir}/${appName} getTime echo -e "${nowTime}\t编译工程${appName}" >> ${deployLog} # Maven编译(视实际情况调整编译命令) mvn clean install package -s ${setFile} -Dmaven.test.skip=true -Dmaven.repo.local=${repPath} # Ant编译(视实际情况调整编译命令) #ant -f build.xml getStatus=$? getResult sleep 3 done } # 部署 deployApp (){ cd ${workDir} for hstIP in ${hstList[@]} do for appName in ${appList[@]} do # 备份应用 getTime echo -e "${nowTime}\t备份${hstIP}上的应用${appName}" >> ${deployLog} # 复制备份脚本至应用服务器 #scp scripts/common/backup.sh ${deployUsr}@${hstIP}:~/scripts/common/ # 视实际需求调整备份的文件(-s参数值) ssh ${deployUsr}@${hstIP} "sh scripts/common/backup.sh -s ${deployDir}/${appName}*.jar -b ${deployDir}/${appName}/backup" getStatus=$? # 没有待备份的文件时确认是否继续 while [ ${getStatus} -eq 9 ] do read -p "没有待备份的文件,确定要跳过备份直接部署吗?输入'Y'继续部署,输入'E'退出脚本..." toNEXT [ "${toNEXT^^}" = "Y" ] && break [ "${toNEXT^^}" = "E" ] && exit 2 done getResult # 停止应用(视实际情况调整停止命令) echo -e "${nowTime}\t停止${hstIP}上的应用${appName}" >> ${deployLog} ssh ${deployUsr}@${hstIP} "sh scripts/common/${appName}.sh stop" getStatus=$? getResult # 拷贝制品 echo -e "${nowTime}\t拷贝制品至${hstIP}:${deployDir}" >> ${deployLog} scp -r ${appName}/target/${appName}*.jar ${deployUsr}@${hstIP}:${deployDir}/ getStatus=$? getResult # 启动应用(视实际情况调整启动命令) echo -e "${nowTime}\t启动${hstIP}上的应用${appName}" >> ${deployLog} ssh ${deployUsr}@${hstIP} "sh scripts/common/${appName}.sh start" getStatus=$? getResult sleep 3 done sleep 1 done } # 导出环境参数 [ ! -d "${jdkPath}" ] && echo "环境目录${jdkPath}不存在" && exit 1 || export JAVA_HOME="${jdkPath}" [ ! -d "${mvnPath}" ] && echo "环境目录${mvnPath}不存在" && exit 1 || export JAVA_HOME="${mvnPath}" #[ ! -d "${antPath}" ] && echo "环境目录${antPath}不存在" && exit 1 || export JAVA_HOME="${antPath}" export PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH #export PATH=$JAVA_HOME/bin:$ANT_HOME/bin:$PATH [ -n "${deployVer}" ] && mergeCode checkoutCode compileApp deployApp getTime echo -e ">>>>>>>>>> ${nowTime} <<<<<<<<<<\n" >> ${deployLog}
原创文章禁止转载:技术学堂 » Java多工程项目自动化编译部署Shell脚本