我的CD
作為一個(gè)獨(dú)立的工程師,時(shí)間是最寶貴的狡孔,搭建一個(gè)高效的產(chǎn)品發(fā)布環(huán)境能節(jié)省很多重復(fù)的時(shí)間懂诗。
現(xiàn)在有很多這樣的CD工具,可以管理較大的產(chǎn)品苗膝,對(duì)我來(lái)說(shuō)殃恒,學(xué)習(xí)成本太大,經(jīng)過仔細(xì)的考慮辱揭,我選擇使用shell腳本來(lái)實(shí)現(xiàn)簡(jiǎn)單的CD!
基本配置
基本配置
- 接下來(lái)就是安裝各種程序:lnmp离唐,java,tomcat问窃,maven亥鬓,git;
- 配置環(huán)境變量域庇;
還有一些每次發(fā)布版本都需要重復(fù)的工作嵌戈,比如:
- 部署java的war包;
- 重新啟動(dòng)tomcat的服務(wù)听皿;
這些操作都比較簡(jiǎn)單熟呛,但是很耗時(shí)間,對(duì)于快節(jié)奏的版本更新產(chǎn)品來(lái)說(shuō)尉姨,是很大的資源浪費(fèi)庵朝。
經(jīng)過以上的思考,通過2天的時(shí)間編寫了一個(gè)shell如下腳本;實(shí)現(xiàn)了:
- 自動(dòng)安裝java和git環(huán)境
- 自動(dòng)拉取git上的最新代碼偿短,通過maven進(jìn)行遠(yuǎn)程的源碼編譯
- 自動(dòng)發(fā)布和備份產(chǎn)品工程包
- 自動(dòng)安裝nodejs環(huán)境 v4.5的版本
- 自動(dòng)安裝cnpm來(lái)使用淘寶的源下載node模塊
- 啟動(dòng)web控制臺(tái)來(lái)執(zhí)行指令(通過nodejs實(shí)現(xiàn))
先創(chuàng)建一個(gè)目錄
$ mkdir -p /home/setups
#! /bin/sh
#定義顏色的變量
RED_COLOR='\E[1;31m' #紅
GREEN_COLOR='\E[1;32m' #綠
YELOW_COLOR='\E[1;33m' #黃
BLUE_COLOR='\E[1;34m' #藍(lán)
PINK='\E[1;35m' #粉紅
RES='\E[0m'
# >>>>>>>>>>>>>>>>>>>>設(shè)置全局變量
# >>>>>>>>>>>>>>>>>> api代碼的目錄
# >>>>>>>>>>>>>>>>>> ci代碼庫(kù)目錄
# >>>>>>>>>>>>>>>>>> tomcat目錄
#清屏
clear
# 安裝文件的目錄
# 優(yōu)先從安裝文件目錄中下載
SETUP_DIR="/home/setups"
# ci 的工作目錄
CI_HOME_DIR="/home/ci/java"
CI_LIB_DIR="$CI_HOME_DIR/lib"
CI_TARGET_DIR="$CI_HOME_DIR/target"
CI_LOG_DIR="$CI_HOME_DIR/log"
CI_CONF_FILE="$CI_HOME_DIR/ci.conf"
# maven 的相關(guān)變量定義
MAVEN_VERSION="apache-maven-3.3.9"
MAVEN_TAR="$MAVEN_VERSION-bin.tar.gz"
MAVEN_DOWNLOAD_URI="http://mirrors.cnnic.cn/apache/maven/maven-3/3.3.9/binaries/$MAVEN_TAR"
MAVEN_DIR="$CI_LIB_DIR/$MAVEN_VERSION"
# tomcat的相關(guān)變量的定義
TOMCAT_VERSION="apache-tomcat-8.5.4"
TOMCAT_TAR="$TOMCAT_VERSION.tar.gz"
TOMCAT_DOWNLOAD_URI="http://mirrors.cnnic.cn/apache/tomcat/tomcat-8/v8.5.4/bin/$TOMCAT_TAR"
TOMCAT_HOME_DIR="$CI_LIB_DIR/$TOMCAT_VERSION"
TOMCAT_DEPLOY_DIR="$TOMCAT_HOME_DIR/webapps"
TOMCAT_PORT="8080"
# jdk的相關(guān)變量的定義
JAVA_VERSION="jdk1.8.0_102"
JAVA_TAR="jdk-8u102-linux-x64.tar.gz"
JAVA_DOWNLOAD_URI="http://download.oracle.com/otn-pub/java/jdk/8u102-b14/$JAVA_TAR"
JAVA_HOME_DIR="$CI_LIB_DIR/$JAVA_VERSION"
# 需要讀取相關(guān)的配置文件
if [ -f $CI_CONF_FILE ]; then
TOMCAT_HOME_DIR=`grep 'TOMCAT_HOME=' $CI_CONF_FILE`
TOMCAT_HOME_DIR=${TOMCAT_HOME_DIR#*=}
TOMCAT_PORT=`grep 'TOMCAT_PORT=' $CI_CONF_FILE`
TOMCAT_PORT=${TOMCAT_PORT#*=}
TOMCAT_DEPLOY_DIR="$TOMCAT_HOME_DIR/webapps"
fi
# 項(xiàng)目名稱
PROJECT_NAME="yfoa"
# 項(xiàng)目的變量定義
PROJECT_GIT="https://git.oschina.net/***.git"
PROJECT_DIR="$CI_HOME_DIR/$PROJECT_NAME"
PROJECT_SOURCE_DIR=$PROJECT_DIR
PROJECT_TARGET_DIR="$PROJECT_SOURCE_DIR/target"
PROJECT_TARGET_VERSION_CODE=`date '+%m%d%H%M'`
# 定義相關(guān)的函數(shù)
# 返回 0 表示操作成功欣孤,小于 0 的所有返回值,均為執(zhí)行錯(cuò)誤
# 安裝操作
function ciInstall {
### 創(chuàng)建CI工作區(qū)
echo -e "${BLUE_COLOR}[PO]>>>>>>>>>>>>>>>>> Create CI Dir >> >>>>>>>>>>>>>>>>${RES}"
#放心執(zhí)行昔逗,因?yàn)橐呀?jīng)存在的忽略掉的
mkdir -p $CI_HOME_DIR
mkdir -p $CI_LIB_DIR
mkdir -p $CI_TARGET_DIR
mkdir -p $CI_LOG_DIR
### 安裝 jdk 1.8
#判斷是否安裝過 jdk
if [ ! -d $JAVA_HOME_DIR ]; then
echo -e "${BLUE_COLOR}[PO]>>>>>>>>>>>>>>>>> Install JDK >> >>>>>>>>>>>>>>>>${RES}"
cd $CI_LIB_DIR
if [ -f $SETUP_DIR/$JAVA_TAR ]; then
cp $SETUP_DIR/$JAVA_TAR $CI_LIB_DIR/$JAVA_TAR
else
wget --no-check-certificate -c --header "Cookie: oraclelicense=accept-securebackup-cookie" -O $JAVA_TAR $JAVA_DOWNLOAD_URI
fi
tar -zxvf $JAVA_TAR
# TODO:修改環(huán)境變量
echo "JAVA_HOME=$JAVA_HOME_DIR" >> /etc/profile
echo 'PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile
echo 'CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar' >> /etc/profile
echo "export JAVA_HOME PATH CLASSPATH" >> /etc/profile
source /etc/profile
java -version
else
echo -e "${GREEN_COLOR}[OK]>>>>>>>>>>>>>>>>> JDK Installed >> >>>>>>>>>>>>>>>>${RES}"
fi
### 安裝 tomcat
#判斷是否安裝過 tomcat
if [ ! -d $TOMCAT_HOME_DIR ]; then
echo -e "${BLUE_COLOR}[PO]>>>>>>>>>>>>>>>>> Install Tomcat >> >>>>>>>>>>>>>>>>${RES}"
cd $CI_LIB_DIR
if [ -f $SETUP_DIR/$TOMCAT_TAR ]; then
cp $SETUP_DIR/$TOMCAT_TAR $CI_LIB_DIR/$TOMCAT_TAR
else
wget $TOMCAT_DOWNLOAD_URI
fi
tar -zxvf $TOMCAT_TAR
else
echo -e "${GREEN_COLOR}[OK]>>>>>>>>>>>>>>>>> Tomcat Installed >> >>>>>>>>>>>>>>>>${RES}"
fi
### 安裝 maven
#判斷是否安裝過maven
if [ ! -d $MAVEN_DIR ]; then
echo -e "${BLUE_COLOR}[PO]>>>>>>>>>>>>>>>>> Install Maven >> >>>>>>>>>>>>>>>>${RES}"
cd $CI_LIB_DIR
if [ -f $SETUP_DIR/$MAVEN_TAR ]; then
cp $SETUP_DIR/$MAVEN_TAR $CI_LIB_DIR/$MAVEN_TAR
else
wget $MAVEN_DOWNLOAD_URI
fi
tar -zxvf $MAVEN_TAR
else
echo -e "${GREEN_COLOR}[OK]>>>>>>>>>>>>>>>>> Maven Installed >> >>>>>>>>>>>>>>>>${RES}"
fi
### 安裝 git & lsof
echo -e "${BLUE_COLOR}[PO]>>>>>>>>>>>>>>>>> Install Git & LSOF >> >>>>>>>>>>>>>>>>${RES}"
yum install git
yum install lsof
echo -e "${GREEN_COLOR}[OK]>>>>>>>>>>>>>>>>> Git & LSOF Installed >> >>>>>>>>>>>>>>>>${RES}"
### 下載代碼
if [ ! -d $PROJECT_DIR ]; then
echo -e "${BLUE_COLOR}[PO]>>>>>>>>>>>>>>>>> Download Code From Git : >$PROJECT_GIT< ${RES}"
cd $CI_HOME_DIR
git clone $PROJECT_GIT $PROJECT_NAME
fi
echo -e "${GREEN_COLOR}[OK]>>>>>>>>>>>>>>>>> Code Downloaded ${RES}"
echo -e "${GREEN_COLOR}[OK]>>>>>>>>>>>>>>>>> Install Down ${RES}"
echo -e "${GREEN_COLOR}[OK]>>>>>>>>>>>>>>>>> New You Can Build The Project ${RES}"
echo -e "${GREEN_COLOR}[OK]>>>>>>>>>>>>>>>>> $ ci build ${RES}"
return 0
}
# 配置設(shè)置
function ciConfig {
echo -e "${PINK}請(qǐng)輸入tomcat的所在目錄(默認(rèn):$TOMCAT_HOME_DIR)? ${RES}"
read -p ":" _tomcatHome
if [ -z $_tomcatHome ]; then
echo -e "${PINK}確認(rèn)要使用默認(rèn)的安裝目錄: $TOMCAT_PORT?${RES}"
read -p "[y/n]:" isYN
if [ ! $isYN = "y" ]; then
echo -e "${PINK}[ERROR]您已放棄本次配置降传,請(qǐng)?jiān)谙乱淮尾渴鸸こ糖巴瓿膳渲茫駝t將無(wú)法部署 ${RES}"
return 11
else
TOMCAT_HOME_DIR="$TOMCAT_HOME_DIR"
fi
else
TOMCAT_HOME_DIR=$_tomcatHome
fi
echo -e "${PINK}請(qǐng)輸入tomcat所使用的端口(默認(rèn):$TOMCAT_PORT)?${RES}"
read -p ":" _tomcatPort
if [ -z $_tomcatPort ]; then
echo -e "${PINK}確認(rèn)要使用默認(rèn)的端口號(hào): $TOMCAT_PORT?${RES}"
read -p "[y/n]:" isYN
if [ ! $isYN = "y" ]; then
echo -e "${PINK}[ERROR]您已放棄本次配置勾怒,請(qǐng)?jiān)谙乱淮尾渴鸸こ糖巴瓿膳渲闷排牛駝t將無(wú)法部署 ${RES}"
return 12
else
TOMCAT_PORT="$TOMCAT_PORT"
fi
else
TOMCAT_PORT=$_tomcatPort
fi
# 寫入文件
rm -f $CI_CONF_FILE
echo "TOMCAT_HOME=$TOMCAT_HOME_DIR" > $CI_CONF_FILE
echo "TOMCAT_PORT=$TOMCAT_PORT" >> $CI_CONF_FILE
return 0
}
# 清空ci工作區(qū)的所有文件,慎用
function ciClean {
if [ ! -d $CI_HOME_DIR ]; then
#該目錄已經(jīng)不存在
echo -e "${PINK}目錄 : $CI_HOME_DIR 已不存在,無(wú)需刪除~ ${RES}"
return 22
fi
echo -e "${PINK}確認(rèn)要清除CI目錄[$CI_HOME_DIR]么?${RES}"
read -p "[y/n]:" isYN
if [ $isYN = "y" ]; then
rm -rf $CI_HOME_DIR
else
echo "Bye"
return 21
fi
return 0
}
# 清楚ci工作區(qū)的 target & log目錄
function ciClear {
echo -e "${PINK}確認(rèn)要清除CI目錄的日志和目標(biāo)文件么?${RES}"
read -p "[y/n]:" isYN
if [ $isYN = "y" ]; then
rm -rf $CI_HOME_DIR/log/*
rm -rf $CI_HOME_DIR/target/*
else
echo "Bye"
return 31
fi
return 0
}
# 構(gòu)建項(xiàng)目
function ciBuild {
echo -e "${BLUE_COLOR}[GO]>>>>>> Clean${RES}"
# 清空target目錄下的文件
rm -rf $PROJECT_TARGET_DIR/*
if [ -f $CI_TARGET_DIR/$PROJECT_NAME_deploy.war ]; then
rm -f $CI_TARGET_DIR/$PROJECT_NAME_deploy.war
fi
echo -e "${GREEN_COLOR}[OK]>>>>>> Clean done${RES}"
#下拉代碼
cd $PROJECT_DIR
echo -e "${BLUE_COLOR}[GO]>>>>>> Pull the master source code ${RES}"
git pull origin master
echo -e "${GREEN_COLOR}[OK]>>>>>> Pull done ${RES}"
echo -e "${BLUE_COLOR}[GO]>>>>>> Build start ${RES}"
#編譯代碼
cd $PROJECT_SOURCE_DIR
$MAVEN_DIR/bin/mvn package > $CI_LOG_DIR/MAVEN_PACKAGE_$PROJECT_TARGET_VERSION_CODE.log
echo -e "${GREEN_COLOR}[OK]>>>>>> Build done ${RES}"
#ls -l $API_TARGET_DIR
echo -e "${BLUE_COLOR}[GO]>>>>>> Copy to target dir ${RES}"
# 這里需要替換成相應(yīng)的tomcat的目錄
cp $PROJECT_TARGET_DIR/$PROJECT_NAME.war $CI_TARGET_DIR/$PROJECT_NAME_$PROJECT_TARGET_VERSION_CODE.war
cp $PROJECT_TARGET_DIR/$PROJECT_NAME.war $CI_TARGET_DIR/$PROJECT_NAME_deploy.war
echo -e "${GREEN_COLOR}[OK]>>>>>> Target Version : $PROJECT_TARGET_VERSION_CODE"
echo -e "${GREEN_COLOR}[OK]>>>>>> You Need TO Deploy ${RES}"
echo -e "${GREEN_COLOR}[OK]>>>>>> Like: $ ./ci.sh deploy ${RES}"
return 0
}
function ciStartServer {
echo -e "${BLUE_COLOR}[GO]>>>>>> Shutdown Server ${RES}"
$TOMCAT_HOME_DIR/bin/shutdown.sh
# 有時(shí)候會(huì)關(guān)閉掉笔链,導(dǎo)致重啟不了
# 使用lsof強(qiáng)制進(jìn)行關(guān)閉
pid=`lsof -t -i:$TOMCAT_PORT`
if [ ! -z $pid ]; then
kill -9 $pid
fi
$TOMCAT_HOME_DIR/bin/startup.sh
echo -e "${GREEN_COLOR}[OK]>>>>>> Startup ok ${RES}"
return 0
}
# 復(fù)制工程并重啟tomcat
function ciRestart {
if [ -z $1 ]; then
target_war="$CI_TARGET_DIR/$PROJECT_NAME.war"
fi
echo "target_war $target_war"
if [ ! -f $target_war ]; then
echo -e "${PINK}[ERROR]>>>>>> Cant Find The TargetWar File~ You Need Run The Next Command: ${RES}"
echo -e "${GREEN_COLOR}[OK]>>>>>> $ ./ci.sh build ${RES}"
return 52
fi
echo -e "${BLUE_COLOR}[GO]>>>>>> Shutdown tomcat ${RES}"
# 有時(shí)候會(huì)關(guān)閉掉段只,導(dǎo)致重啟不了
# 使用lsof強(qiáng)制進(jìn)行關(guān)閉
pid=`lsof -t -i:$TOMCAT_PORT`
if [ ! -z $pid ]; then
$TOMCAT_HOME_DIR/bin/shutdown.sh
kill -9 $pid
fi
echo -e "${GREEN_COLOR}[OK]>>>>>> Shutdown ok ${RES}"
cp $target_war $TOMCAT_DEPLOY_DIR/$PROJECT_NAME.war
$TOMCAT_HOME_DIR/bin/startup.sh
if [ ! -f $TOMCAT_DEPLOY_DIR/$PROJECT_NAME.war ]; then
echo -e "${PINK}[ERROR]>>>>>> Deploy failed~ plz run again ${RES}"
return 51
else
echo -e "${GREEN_COLOR}[OK]>>>>>> Success~ Deploy Finished~ ${RES}"
fi
return 0
}
# 手動(dòng)部署項(xiàng)目
function ciDeploy {
target_war="$CI_TARGET_DIR/$PROJECT_NAME.war"
if [ ! -z $1 ]; then
echo $1
target_war="$CI_TARGET_DIR/$1.war"
fi
echo $target_war
echo -e "${GREEN_COLOR}[GO]>>>>>> Deploy ${RES}"
echo -e "${GREEN_COLOR}[GO]>>>>>> The Tomcat Var Is: ${RES}"
echo -e "${GREEN_COLOR}[OK]>>>>>> TOMCAT_HOME_DIR At $TOMCAT_HOME_DIR ${RES}"
echo -e "${GREEN_COLOR}[OK]>>>>>> TOMCAT_PORT At $TOMCAT_PORT ${RES}"
echo -e "${GREEN_COLOR}[OK]>>>>>> TOMCAT_DEPLOY_DIR At $TOMCAT_DEPLOY_DIR ${RES}"
echo -e "${GREEN_COLOR}[OK]>>>>>> 是否使用當(dāng)前環(huán)境變量進(jìn)行發(fā)布?${RES}"
read -p "[y/n]:" isYN
if [ ! $isYN = "y" ]; then
echo -e "${GREEN_COLOR}[OK]>>>>>> 請(qǐng)輸入 $ ci.sh conf 重新配置tomcat的目錄${RES}"
return 41
fi
ciRestart $target_war
return $?
}
# 自動(dòng)部署項(xiàng)目
function ciPublish {
ciRestart
return $?
}
function ciRequireCommand {
echo -e "${GREEN_COLOR}[GO]>>>>>> 您輸入的參數(shù)錯(cuò)誤,可選的參數(shù)如下: ${RES}"
echo -e "${GREEN_COLOR}[GO]>>>>>> ci install : 安裝ci目錄鉴扫,maven赞枕,下載git代碼 ${RES}"
echo -e "${GREEN_COLOR}[GO]>>>>>> ci build :編譯git倉(cāng)庫(kù)中最新的代碼 ${RES}"
echo -e "${GREEN_COLOR}[GO]>>>>>> ci deploy :將代碼發(fā)布到servlet容器中并重啟該容器 ${RES}"
echo -e "${GREEN_COLOR}[GO]>>>>>> ci conf :設(shè)置servlet容器的目錄和端口 ${RES}"
}
echo -e "${BLUE_COLOR}[GO]>>>>>>>>>>>> Command:[$1]>>>>>>>>>>>>>>${RES}"
#沒有值
if [ -z $1 ]; then
ciRequireCommand
exit
## 安裝流程
elif [ $1 = "install" ]; then
ciInstall
elif [ $1 = "conf" ]; then
ciConfig
if [ $? > 0 ]; then
exit
fi
elif [ $1 = "startup" ]; then
ciStartServer
if [ $? > 0 ]; then
exit
fi
elif [ $1 = "clean" ]; then
ciClean
if [ $? > 0 ]; then
exit
fi
elif [ $1 = "clear" ]; then
ciClear
if [ $? > 0 ]; then
exit
fi
elif [ $1 = "build" ]; then
ciBuild
elif [ $1 = "deploy" ]; then
ciDeploy $2
elif [ $1 = "publish" ]; then
ciPublish
if [ $? > 0 ]; then
exit
fi
else
ciRequireCommand
exit
fi #end if