Java多工程项目自动化编译部署Shell脚本

分享一段自动化编译部署的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脚本

精彩评论

1+2=

感谢您的支持与鼓励

支付宝扫一扫打赏

微信扫一扫打赏