设为首页 收藏本站
查看: 1121|回复: 0

[经验分享] 这些年我们一起搞过的持续集成~Jenkins+Perl and Shell script

[复制链接]

尚未签到

发表于 2015-12-3 13:58:55 | 显示全部楼层 |阅读模式
这些年我们一起搞过的持续集成~Jenkins+Perl and Shell script
  ##转载注明出处:http://www.cnblogs.com/wade-xu/p/4378224.html
  
  部门用持续集成已经很久了,但其实使用起来还是很麻烦的,每当要给一个新项目set up持续集成的环境,虽然是Copy一些现有的jobs, 但是许多参数,变量需要去改,然后还有调试,少说3,4天搞一下,非常不方便。
  最近比较空,就把现有的持续集成系统升级改造下,job用一套模板,全部参数化,只要修改配置文件,就可以为新项目配置好环境。
  
  本文的重点是一些经验,想法的分享,并不是一篇手把手教你搭建持续集成环境的教程,而且阅读本文需要一定的Jenkins, perl, shell脚本的基础知识, 所用到的知识有:Jenkins+Maven+Git+Sonar+Perl+Shell script
  下图很好的说明了我们现有的Job流, 以往是每个项目都有一套这样的job流,现在我改成这个Template_service job流,供所有的项目使用,项目名也是作为参数传递进来的,每个job都是用Jenkins Execute shell这个组件来实现功能的,像check out code,Email Notification, Publish Junit test results, code coverage report 等Jenkins自带组件都没有使用。
  
  运行环境:  apache-maven-3.0.5, jdk1.7.0_15, git 1.8.2.1, SonarQube 4.0, perl v5.8.8
  
DSC0000.jpg
  ##转载注明出处:http://www.cnblogs.com/wade-xu/p/4378224.html
  
  接下来简单的说明一下各个Job的功能,以及贴出详细的脚本供大家参考。
  除了上图里面的job, 还有一个Config job, export一些环境变量
  0)Template_Service_Config (one time run)
  用来Export 环境变量的,比如Project list, project git 地址,


  export PROJECT_LIST=PROJECTA,PROJECTB
export PROJECTA_GIT_PROJECT_URL=ssh://git@stash.xxx.com:7999/Project/ProjectA.git
export PROJECTA_BRANCH=development
export PROJECTA_SERVICE_NAME=China_Template_Service
export PROJECTA_EMAIL_LIST=wadexu@xxx.com,xxx@xxx.com
export PROJECTA_EMAIL_CC_LIST=wadexu@xxx.com
  ......
  export PROJECTB_GIT_PROJECT_URL=ssh://git@stash.xxx.com:7999/abc/ProjectB.git
export PROJECTB_BRANCH=perf
export PROJECTB_SERVICE_NAME=China_ProjectB_DEV
export PROJECTB_EMAIL_LIST=wadexu@xxx.com,xxx@xxx.com
export PROJECTB_EMAIL_CC_LIST=wadexu@xxx.com
  ......
  
  Build 这个job 的时候需要Parameters
DSC0001.jpg
  
  代码如下:主要作用就是将输入的Parameters写入到一个文件,以便后续所有job 一上来source一下



TEST=${WORKSPACE}/test
CONFIG_FILE=Project_Config.txt
rm -rf ${TEST}
git clone ssh://git@stash.xxx.com:7999/project/test.git
cd ${TEST}
cd Config
if [ ! -f "${CONFIG_FILE}" ]; then  
touch "${CONFIG_FILE}"
fi
##########Rewrite the config file base on the project list###########
CURRENT_TIME=`date +"%m/%d/%Y/%T"`
echo -e "export CONFIG_TIME=${CURRENT_TIME}\n
export PROJECT_LIST=${PROJECT_LIST}\n
export SHARED_FOLDER=~/jenkins/common\n" > ${CONFIG_FILE}

###########List the project1 parameters###########
echo -e "${PROJECTA_PARAMETERS}" >> ${CONFIG_FILE}
###########List the project2 parameters###########
echo -e "${PROJECTB_PARAMETERS}" >> ${CONFIG_FILE}

git add ${CONFIG_FILE}
git commit -m "config file"
git push origin master
cp ${CONFIG_FILE} ~/jenkins/common/Config
cd ..
cp Scripts/* ~/jenkins/common/Scripts
chmod 755 ~/jenkins/common/Scripts/*
  还有就是将一些perl写的脚本从git clone下来放到某一个公共目录下,以便后续job使用, 有如下脚本,比如发送email, Unit test analyzer
  部分脚本像gridService, packageService是操作公司一个网格云计算平台,安装rpm包,重启service用的,不方便贴出来。



[wadexu@vm10226 common]$ cd Scripts/
[wadexu@vm10226 Scripts]$ ll
total 404
-rwxr-xr-x 1 wadexu wadexu  37853 Mar 27 09:12 gridService
-rwxr-xr-x 1 wadexu wadexu   4991 Mar 27 09:12 packageService
-rwxr-xr-x 1 wadexu wadexu   1628 Mar 27 09:12 queryDB.pl
-rwxr-xr-x 1 wadexu wadexu 317183 Mar 27 09:12 Reporter.jar
-rwxr-xr-x 1 wadexu wadexu   2190 Mar 27 09:12 report.pl
-rwxr-xr-x 1 wadexu wadexu   3415 Mar 27 09:12 sendEmail.pl
-rwxr-xr-x 1 wadexu wadexu   1210 Mar 27 09:12 ServiceInfoProvider.pl
-rwxr-xr-x 1 wadexu wadexu   3418 Mar 27 09:12 UnitTestAnalyzer.pl
  
  1)Template_Service_Initial
  遍历Project list 列出的项目, 使用curl 调用下一个job (Commit_Auto_Build) 的Rest API, Build job with parameter接口
  每个项目的Job流都是通过Project name + Initial job的Build number 来贯穿的, 这点很重要,多项目一起运行时各项目之间不会错乱,比如写Log文件,分析Log文件生成report



rm -rf ${WORKSPACE}/*
####### Import config file #######
cd ~/jenkins/common/Config
. Project_Config.txt
cd ~/jenkins/common/Temp
####### Get the Project list and traverse the list ######   
id=1
list_size=`echo $PROJECT_LIST | awk -F "," '{print NF;}'`
let list_size=list_size+1
while [ $id -lt $list_size ]
do
projectName=`echo "${PROJECT_LIST}"|awk -v id=$id -F "," '{print $id}'`      
if [ "$projectName " != ' ' ];  then            
curl -X POST --user "jadmin:71103407" -s http://vm10686.global.xxx.net:8080/view/Template/job/Template_Service_Commit_Auto_Build/build --data json='{"parameter": [{"name":"PROJECT_NAME","value":"'$projectName'"},{"name":"PIPELINE_NUM","value":"'$BUILD_NUMBER'"}]}'                        
id=`expr $id + 1`
else
break
fi
done     

  
  2)Template_Service_Commit_Auto_Build
  这个Job的作用是用来比较代码版本有没有更新,如果有更新(或者是第一次run这个job)就会调用后续的-- Build job
  还有就是列出这次Build和上次Build之间改动过代码的作者。
  如果将Initial job 设置成每几分钟run一下,其实这个job就起到了 每当有人提交代码,则自动Build的作用了。
DSC0002.jpg



### Import config file ###
cd ~/jenkins/common/Config
. Project_Config.txt
### Initial parameters ###
GIT_PROJECT_URL=${PROJECT_NAME}"_GIT_PROJECT_URL"
GIT_PROJECT_URL=$(eval echo \${$GIT_PROJECT_URL})
BRANCH=${PROJECT_NAME}"_BRANCH"
BRANCH=$(eval echo \${$BRANCH})
LOG_NAME=${PROJECT_NAME}"_BUILD_"${PIPELINE_NUM}".log"
BUILD_LOG_FOLDER=${SHARED_FOLDER}/Log/${PROJECT_NAME}"_"${PIPELINE_NUM}
BUILD_LOG=${SHARED_FOLDER}/Log/${PROJECT_NAME}"_"${PIPELINE_NUM}/$LOG_NAME
mkdir $BUILD_LOG_FOLDER
GIT_PROJECT_NAME=${PROJECT_NAME}"_GIT_PROJECT_NAME"
GIT_PROJECT_NAME=$(eval echo \${$GIT_PROJECT_NAME})
#### setup ####
export CURRENT_RESOURCE_DIR=${WORKSPACE}/${GIT_PROJECT_NAME}
export CURRENT_MD5_FILE=${WORKSPACE}/${PROJECT_NAME}"_Code_Current"
export BASE_MD5_FILE=${WORKSPACE}/${PROJECT_NAME}"_Code_Base"
export CURRENT_AUTHOR_LIST=${WORKSPACE}/${PROJECT_NAME}"_Author_Current"
export BASE_AUTHOR_LIST=${WORKSPACE}/${PROJECT_NAME}"_Author_Base"
#### cd resource,get log commit MD5 ####
cd ${WORKSPACE}
rm -rf ${CURRENT_RESOURCE_DIR}
git clone ${GIT_PROJECT_URL}
cd ${CURRENT_RESOURCE_DIR}
git checkout -b ci origin/${BRANCH}
if [ ! -f "${BASE_AUTHOR_LIST}" ]; then  
touch "${BASE_AUTHOR_LIST}"
fi
if [ ! -f "${BASE_MD5_FILE}" ]; then  
touch "${BASE_MD5_FILE}"
########call build job######  
curl -d --user "jadmin:71103407" -s http://vm10686.global.xxx.net:8080/view/Template/job/Template_Service_Build/build --data json='{"parameter":[{"name":"PROJECT_NAME","value":"'${PROJECT_NAME}'"},{"name":"PIPELINE_NUM","value":"'${PIPELINE_NUM}'"}]}'

git log --pretty=format:"Author: %an" > ${BASE_AUTHOR_LIST}
sort -u  ${BASE_AUTHOR_LIST}  >  ${BUILD_LOG}
git log --max-count=1 --pretty=format:"%H" > ${BASE_MD5_FILE}
exit 0
else
git log --max-count=1 --pretty=format:"%H" > ${CURRENT_MD5_FILE}
git log --pretty=format:"Author: %an" > ${CURRENT_AUTHOR_LIST}
fi
#### compare the md5 file, and run the job.####
## -a means && ##
if cmp -s ${CURRENT_MD5_FILE} ${BASE_MD5_FILE}
then
echo "same,no changes!"
else
mv ${CURRENT_MD5_FILE} ${BASE_MD5_FILE}
diff -b $CURRENT_AUTHOR_LIST $BASE_AUTHOR_LIST | grep "<" | sed 's/^< //g' > Update_Author.txt
mv ${CURRENT_AUTHOR_LIST} ${BASE_AUTHOR_LIST}
sort -u Update_Author.txt > ${BUILD_LOG}
########call build job######
curl -d --user "jadmin:71103407" -s http://vm10686.global.xxx.net:8080/view/Template/job/Template_service_Build/build --data json='{"parameter": [{"name":"PROJECT_NAME","value":"'${PROJECT_NAME}'"},{"name":"PIPELINE_NUM","value":"'${PIPELINE_NUM}'"}]}'
fi
  这里用到了--pretty=format 这个参数, %H就是打印出哈希字串, %an是打印出Author, --max-count=1 取最近的一条log 记录
  
  ##转载注明出处:http://www.cnblogs.com/wade-xu/p/4378224.html
  
  3) Template_Service_Build
  这个job是最核心的job, 执行rpm build, 将rpm包丢到公司内部网格云计算平台的Repository下, 分析单元测试结果, 运行Sonar, 从Sonar的首页上拿到这个项目的一些信息,比如Sonar上 blocker, critical, major 等issues, 还有code coverage,全部打印到log里, 以便后续的脚本生成report, 另外就是Sonar issue, code coverage 不达标,则发送相应的email 给相应的project email list



rm -rf ${WORKSPACE}/*
###### Import config file ######
cd ~/jenkins/common/Config
. Project_Config.txt
###### Initial parameters ######
GIT_PROJECT_NAME=${PROJECT_NAME}"_GIT_PROJECT_NAME"
GIT_PROJECT_NAME=$(eval echo \${$GIT_PROJECT_NAME})
LOG_NAME=${PROJECT_NAME}"_BUILD_"${PIPELINE_NUM}".log"
BUILD_LOG=${SHARED_FOLDER}/Log/${PROJECT_NAME}"_"${PIPELINE_NUM}/$LOG_NAME
BRANCH=${PROJECT_NAME}"_BRANCH"
BRANCH=$(eval echo \${$BRANCH})
GIT_PROJECT_URL=${PROJECT_NAME}"_GIT_PROJECT_URL"
GIT_PROJECT_URL=$(eval echo \${$GIT_PROJECT_URL})
REPOSITORY=${PROJECT_NAME}"_REPOSITORY"
REPOSITORY=$(eval echo \${$REPOSITORY})
INSTANCES=${PROJECT_NAME}"_INSTANCES"
INSTANCES=$(eval echo \${$INSTANCES})
COVERAGE_URL=${PROJECT_NAME}"_COVERAGE_URL"
COVERAGE_URL=$(eval echo \${$COVERAGE_URL})
SONAR_MIN_COVERAGE=${PROJECT_NAME}"_SONAR_MIN_COVERAGE"
SONAR_MIN_COVERAGE=$(eval echo \${$SONAR_MIN_COVERAGE})
MAX_MAJOR_ISSUE_NUM=${PROJECT_NAME}"_MAX_MAJOR_ISSUE_NUM"
MAX_MAJOR_ISSUE_NUM=$(eval echo \${$MAX_MAJOR_ISSUE_NUM})
MAX_CRITICAL_ISSUE_NUM=${PROJECT_NAME}"_MAX_CRITICAL_ISSUE_NUM"
MAX_CRITICAL_ISSUE_NUM=$(eval echo \${$MAX_CRITICAL_ISSUE_NUM})
SERVICE_NAME=${PROJECT_NAME}"_SERVICE_NAME"
SERVICE_NAME=$(eval echo \${$SERVICE_NAME})
EMAIL_LIST=${PROJECT_NAME}"_EMAIL_LIST"
EMAIL_LIST=$(eval echo \${$EMAIL_LIST})
author_list=`cat $BUILD_LOG | grep "Author"` || true
######### SET ENVIRONMENT VARIABLE ##############
export BASE_DIR=${WORKSPACE}/${GIT_PROJECT_NAME}
export SCRIPTS_HOME=${SHARED_FOLDER}/Scripts
cd ${SCRIPTS_HOME}
chmod 755 *
export PATH=$PATH:`pwd`
####### Build Job ######
cd ${WORKSPACE}
START_TIME=`date +"%m/%d/%Y %T"`
echo "overview->startTime: ${START_TIME}" >> ${BUILD_LOG}
echo "overview->logURL: ${BUILD_URL}" >> ${BUILD_LOG}
echo "overview->serviceType: ${PROJECT_NAME} Service" >> ${BUILD_LOG}
git clone ${GIT_PROJECT_URL}
BUILD_FILE=rpmbuild.sh
cd ${BASE_DIR}
git checkout origin/${BRANCH}
let BUILD_NUMBER=100+${BUILD_NUMBER}
sed -i -r "s/^RELEASE.+/RELEASE=${BUILD_NUMBER}_Dev/g" ${BUILD_FILE}
sh ${BUILD_FILE}
cd ${WORKSPACE}
rm -rf *.rpm
mv `find . -type f -name "*.rpm" | egrep -v '(\.src\.)' | egrep -v 'BUILD'` .
RPM=`ls *.rpm`
packageService --addPackages --repository ${REPOSITORY} --packages "${RPM}"
############# Unit test analyze  ###############
UnitTestAnalyzer.pl --path "${BASE_DIR}/.rpm/BUILD" --sufix xml >> ${BUILD_LOG}
################Run Sonar################
cd ${BASE_DIR}
mvn clean install -f ${BASE_DIR}/pom.xml -DPASSWORD=$ENV{PASSWORD} -DUSERNAME=$ENV{USERNAME} -e -B sonar:sonar
################Get project in Sonar ################
sonarProjectName=`sed -ne '/name/{s/.*<name>\(.*\)<\/name>.*/\1/p;q;}' pom.xml`
lowerProjectName=`echo $sonarProjectName | awk '{print tolower($0)}'`
sonarId=`queryDB.pl --query="select * from resource_index where kee = '$lowerProjectName' order by resource_id;"`
echo $sonarId
sonar_path=http://vm10686.global.xxx.net:9000/dashboard/index/${sonarId}
echo "SonarPath: ${sonar_path}" >> ${BUILD_LOG}
################Function for get Sonar home page info################
##Key for what you want to find
##column to print
function get_html_value() {
html=$1
key=$2
column=$3
echo `cat $html | sed -n '/'$key'/p' | awk -v column=$column -F "[><]" '{print $column}'`
}
##############Sonar issues analyze ###############
curl ${sonar_path} > html.txt
blocker_num=`get_html_value html.txt m_blocker_violations 3`
critical_num=`get_html_value html.txt m_critical_violations 3`
major_num=`get_html_value html.txt m_major_violations 3`
minor_num=`get_html_value html.txt m_minor_violations 3`
info_num=`get_html_value html.txt m_info_violations 3`
echo "SonarIssues->Blocker: ${blocker_num}" >> ${BUILD_LOG}
echo "SonarIssues->Critical: ${critical_num}" >> ${BUILD_LOG}
echo "SonarIssues->Major: ${major_num}" >> ${BUILD_LOG}
echo "SonarIssues->Minor: ${minor_num}" >> ${BUILD_LOG}
echo "SonarIssues->Info: ${info_num}" >> ${BUILD_LOG}
##############Sonar Code Coverage analyze ###############
code_coverage=`get_html_value html.txt m_coverage 7`
code_coverage_integer=`echo $code_coverage | sed -n 's/%//p'`
line_coverage=`get_html_value html.txt m_line_coverage 5`
branch_coverage=`get_html_value html.txt m_branch_coverage 5`
echo "CoverageInfo->UnitTestsCoverage: ${code_coverage}" >> ${BUILD_LOG}
echo "CoverageInfo->LineCoverage: ${line_coverage}" >> ${BUILD_LOG}
echo "CoverageInfo->BranchCoverage: ${branch_coverage}" >> ${BUILD_LOG}
echo "CoverageInfo->CoverageThreshold: ${SONAR_MIN_COVERAGE}%"  >> ${BUILD_LOG}
################Send Email Code Coverage < Threshold ################
if (( $(echo "$code_coverage_integer < $SONAR_MIN_COVERAGE" | bc -l) ))
then
mail_subject=${PROJECT_NAME}"_Service_Build Job - Build # "${BUILD_NUMBER}" Failure"'!'
mail_body="Hi, ${PROJECT_NAME}"" project member"$'\n'$'\n'"Alerts : Unit Tests Coverage: ${code_coverage} < CoverageThreshold: ${SONAR_MIN_COVERAGE}%, the latest build package cannot be allowed to install to service - ${SERVICE_NAME} [$INSTANCES]"'!'$'\n'$'\n'"For details please refer to SonarQube - ${sonar_path}"$'\n'$'\n'"The latest code author list as below:"$'\n'"${author_list}"
sendEmail.pl --subject "${mail_subject}" --emaillist "${EMAIL_LIST}" --mailbody "$mail_body" --msg_type "text"
exit 0
fi
################Send Email when Sonar has major above issue################
if [ ${blocker_num} -gt 0 ] || [ ${critical_num} -gt ${MAX_CRITICAL_ISSUE_NUM} ] || [ ${major_num} -gt ${MAX_MAJOR_ISSUE_NUM} ]
then
mail_subject=${PROJECT_NAME}"_Service_Build Job - Build # "${BUILD_NUMBER}" Failure"'!'
mail_body="Hi, ${PROJECT_NAME}"" project member"$'\n'$'\n'"Alerts : Sonar major above issues != 0, the latest build package cannot be allowed to install to service - ${SERVICE_NAME} [$INSTANCES]"'!'$'\n'$'\n'"Blocker issues: ${blocker_num}"$'\n'"Critical issues: ${critical_num}"$'\n'"Major issues: ${major_num}"$'\n'"Minor issues: ${minor_num}"$'\n'"Info issues: ${info_num}"$'\n'$'\n'"For details please refer to SonarQube - ${sonar_path}"$'\n'$'\n'"The latest code author list as below:"$'\n'"${author_list}"
sendEmail.pl --subject "${mail_subject}" --emaillist "${EMAIL_LIST}" --mailbody "$mail_body" --msg_type "text"
exit 0
fi
####### Call Deploy Job ######
curl -d --user "jadmin:71103407" -s http://vm10686.global.xxx.net:8080/view/Template/job/Template_Service_Deploy/build --data json='{"parameter": [{"name":"PROJECT_NAME","value":"'${PROJECT_NAME}'"},{"name":"PIPELINE_NUM","value":"'${PIPELINE_NUM}'"}]}'

mvn clean install -f ${BASE_DIR}/pom.xml -DPASSWORD=$ENV{PASSWORD} -DUSERNAME=$ENV{USERNAME} -e -B sonar:sonar
  运行Sonar 的一些数据库配置信息,是放在maven/conf/settings.xml文件里的。
  另外一点:每个项目在Sonar里的名称是 项目pom文件的<name></name>标签里的值,根据这个值去数据库里搜出id, 有了这个id就可以直接访问到Sonar上的这个项目 比如http://vm10686.global.xxx.net:9000/dashboard/index/1234
  
  4)Template_Service_Deploy
  Build完之后 就是要Deploy了, 将rpm包装到相应Service的instance上,然后重启service



rm -rf ${WORKSPACE}/*
###### Import config file ######
cd ~/jenkins/common/Config
. Project_Config.txt
###### Initial parameters ######
SERVICE_NAME=${PROJECT_NAME}"_SERVICE_NAME"
SERVICE_NAME=$(eval echo \${$SERVICE_NAME})
INSTANCES=${PROJECT_NAME}"_INSTANCES"
INSTANCES=$(eval echo \${$INSTANCES})
PATTERN=${PROJECT_NAME}"_RPM_GREP_PATTERN"
PATTERN=$(eval echo \${$PATTERN})
LOG_NAME=${PROJECT_NAME}"_BUILD_"${PIPELINE_NUM}".log"
BUILD_LOG=${SHARED_FOLDER}/Log/${PROJECT_NAME}"_"${PIPELINE_NUM}/$LOG_NAME
##########SET ENVIRONMENT VARIABLE##############
SCRIPTS_HOME=~/jenkins/common/Scripts
cd ${SCRIPTS_HOME}
chmod 755 *
export PATH=$PATH:`pwd`
InstallTime=`date +"%m/%d/%Y %T"`
echo "Installation->InstallTime: ${InstallTime}" >> ${BUILD_LOG}
############ Deploy ###############
gridService --add-service --service ${SERVICE_NAME}  --instance ${INSTANCES}
sleep 60
gridService --start-service --service ${SERVICE_NAME}
Endpoint="${INSTANCES}:8080"
echo "Installation->Endpoint: ${Endpoint}" >> ${BUILD_LOG}
echo "Installation->LogURL: ${BUILD_URL}" >> ${BUILD_LOG}
UpdateTime=`date +"%m/%d/%Y %T"`
echo "ServiceInfo->UpdateTime: ${UpdateTime}" >> ${BUILD_LOG}
ServiceInfoProvider.pl --service ${SERVICE_NAME} --pattern ${PATTERN} >> ${BUILD_LOG}
###### Call Polling Job ######
curl -d --user "jadmin:71103407" -s http://vm10686.global.xxx.net:8080/view/Template/job/Template_Service_Polling/build --data json='{"parameter": [{"name":"PROJECT_NAME","value":"'$PROJECT_NAME'"},{"name":"PIPELINE_NUM","value":"'$PIPELINE_NUM'"}]}'
  
  5)Template_Service_Polling
  接下来通过这个Polling job 轮询service有没有启动好, 每1分钟 判断一下,timeout时间10分钟, 脚本其实很简单,就是调一个接口,查看状态是否status=200



rm -rf ${WORKSPACE}/*
######## Import config file #########
cd ~/jenkins/common/Config
. Project_Config.txt
####### SET ENV #############
export SCRIPTS_HOME=${SHARED_FOLDER}/Scripts
cd ${SCRIPTS_HOME}
chmod 755 *
export PATH=$PATH:`pwd`
###### Initial parameters #############
SERVICE_NAME=${PROJECT_NAME}"_SERVICE_NAME"
SERVICE_NAME=$(eval echo \${$SERVICE_NAME})
LOG_NAME=${PROJECT_NAME}"_BUILD_"${PIPELINE_NUM}".log"
BUILD_LOG=${SHARED_FOLDER}/Log/${PROJECT_NAME}"_"${PIPELINE_NUM}/$LOG_NAME
echo "pollingjob->logURL: ${BUILD_URL}" >> ${BUILD_LOG}
###### Polling service whether start #############
sleep 30
gridService --ping --timeout 600 --interval 60 --service ${SERVICE_NAME}

###### Call API Testing Job ######
curl -d --user "jadmin:71103407" -s http://vm10686.global.xxx.net:8080/view/Template/job/Template_Service_APITesting/build --data json='{"parameter": [{"name":"PROJECT_NAME","value":"'${PROJECT_NAME}'"},{"name":"PIPELINE_NUM","value":"'${PIPELINE_NUM}'"}]}'
  
  6)Template_Service_APITesting
  Polling之后 就是调用借口测试的内部测试系统,如果export 的变量有 TestPlan 就会执行,否则直接调用最后一个job--Report



rm -rf ${WORKSPACE}/*
###### Import config file ######
cd ~/jenkins/common/Config
. Project_Config.txt
###### Initial parameters ######
LOG_NAME=${PROJECT_NAME}"_BUILD_"${PIPELINE_NUM}".log"
BUILD_LOG=${SHARED_FOLDER}/Log/${PROJECT_NAME}"_"${PIPELINE_NUM}/$LOG_NAME
TESTPLAN_ID=${PROJECT_NAME}"_TESTPLAN_ID"
TESTPLAN_ID=$(eval echo \${$TESTPLAN_ID})
SERVICE_NAME=${PROJECT_NAME}"_SERVICE_NAME"
SERVICE_NAME=$(eval echo \${$SERVICE_NAME})
EMAIL_LIST=${PROJECT_NAME}"_EMAIL_LIST"
EMAIL_LIST=$(eval echo \${$EMAIL_LIST})
EMAIL_CC_LIST=${PROJECT_NAME}"_EMAIL_CC_LIST"
EMAIL_CC_LIST=$(eval echo \${$EMAIL_CC_LIST})
###########Set Env #############
export SCRIPTS_HOME=${SHARED_FOLDER}/Scripts/
cd ${SCRIPTS_HOME}
chmod 755 *
export PATH=$PATH:`pwd`
################Function################
##Key for what you want to find
##num occurrence of value if it multiple time
function jsonValue() {
KEY=$1
num=$2
awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'$KEY'\042/){print $(i+1)}}}' | tr -d '"' | sed -n ${num}p
}
############### Main ######################
if [[ $TESTPLAN_ID == "" ]]; then
echo "TestPlan ID is blank"
###### Call Report Job ######
curl -d --user "jadmin:71103407" -s http://vm10686.global.xxx.net:8080/view/Template/job/Template_Service_Report/build --data json='{"parameter": [{"name":"PROJECT_NAME","value":"'$PROJECT_NAME'"},{"name":"PIPELINE_NUM","value":"'$PIPELINE_NUM'"}]}'
else
processID=$(curl -X GET http://vm10765.global.xxx.net:8080/tms/project/testPlan/run.spring?ids=$TESTPLAN_ID)
if [[ $processID != TestPlan-* ]]; then
mail_subject=${PROJECT_NAME}"_Service_TMS_APITesting Job - Build # "${BUILD_NUMBER}" Failure"'!'
mail_body="TMS Server is not available now, please contact adminstrator."
echo $mail_body
sendEmail.pl --subject "${mail_subject}" --emaillist "${EMAIL_LIST}" --emailcclist "${EMAIL_CC_LIST}" --mailbody "$mail_body" --msg_type "text"
else
while [ 1 ]
do
response=$(curl -X GET http://vm10765.global.xxx.net:8080/tms/project/getProcessResult.spring?processID=$processID)
totalCounts=`echo $response | jsonValue totalCounts`
notStartCounts=`echo $response | jsonValue notStartCounts`
processingCounts=`echo $response | jsonValue processingCounts`
faildCounts=`echo $response | jsonValue faildCounts`
comparedCounts=`echo $response | jsonValue comparedCounts`
comparedFaildCounts=`echo $response | jsonValue comparedFaildCounts`
unComparedCounts=`echo $response | jsonValue unComparedCounts`
if [ $notStartCounts == 0 ] && [ $processingCounts == 0 ]; then
echo "End of run."
break
else
echo "API Testing is still running, please wait..."
sleep 5
fi
done
############# Print Log ###################
echo "APITestingInfo->TotalCounts: $totalCounts" >> ${BUILD_LOG}
echo "APITestingInfo->ErrorCounts: $faildCounts" >> ${BUILD_LOG}
echo "APITestingInfo->ComparedPassedCounts: $comparedCounts" >> ${BUILD_LOG}
echo "APITestingInfo->ComparedFailedCounts: $comparedFaildCounts" >> ${BUILD_LOG}
echo "APITestingInfo->UnComparedCounts: $unComparedCounts" >> ${BUILD_LOG}
###### Call Report Job ######
curl -d --user "jadmin:71103407" -s http://vm10686.global.xxx.net:8080/view/Template/job/Template_Service_Report/build --data json='{"parameter": [{"name":"PROJECT_NAME","value":"'$PROJECT_NAME'"},{"name":"PIPELINE_NUM","value":"'$PIPELINE_NUM'"}]}'
fi
fi
  ##转载注明出处:http://www.cnblogs.com/wade-xu/p/4378224.html
  
  7)Template_Service_Report
  这里主要是生成Report并且发送Email,用Java写的一个jar放到linux上执行的,用html直接贴在邮件里发送email的,简单的其实可以用Perl写个excel,统计下测试情况,做个报表。



rm -rf ${WORKSPACE}/*
###### Import config file ######
cd ~/jenkins/common/Config
. Project_Config.txt
###### Initial parameters ######
LOG_NAME=${PROJECT_NAME}"_BUILD_"${PIPELINE_NUM}".log"
BUILD_LOG_FOLDER=${SHARED_FOLDER}/Log/${PROJECT_NAME}"_"${PIPELINE_NUM}
BUILD_LOG=${SHARED_FOLDER}/Log/${PROJECT_NAME}"_"${PIPELINE_NUM}/$LOG_NAME
SERVICE_NAME=${PROJECT_NAME}"_SERVICE_NAME"
SERVICE_NAME=$(eval echo \${$SERVICE_NAME})
INSTANCES=${PROJECT_NAME}"_INSTANCES"
INSTANCES=$(eval echo \${$INSTANCES})
EMAIL_LIST=${PROJECT_NAME}"_EMAIL_LIST"
EMAIL_LIST=$(eval echo \${$EMAIL_LIST})
EMAIL_CC_LIST=${PROJECT_NAME}"_EMAIL_CC_LIST"
EMAIL_CC_LIST=$(eval echo \${$EMAIL_CC_LIST})
TESTPLAN_ID=${PROJECT_NAME}"_TESTPLAN_ID"
TESTPLAN_ID=$(eval echo \${$TESTPLAN_ID})
export SCRIPTS_HOME=${SHARED_FOLDER}/Scripts/
cd ${SCRIPTS_HOME}
chmod 755 *
export PATH=$PATH:`pwd`
export XML_REPORT=${WORKSPACE}/interface.xml
report.pl  --log-path="$BUILD_LOG_FOLDER" --output ${XML_REPORT}
REPORT_PATH=${WORKSPACE}/Report.html
echo ${REPORT_PATH}
java -Dxmlpath="${XML_REPORT}" -Dreport="${REPORT_PATH}" -jar Reporter.jar
report_context=`cat $REPORT_PATH`
errorCounts=`cat $BUILD_LOG | grep "APITestingInfo->ErrorCounts" | awk -F ": " '{print $2}'`
comparedFailedCounts=`cat $BUILD_LOG | grep "APITestingInfo->ComparedFailedCounts" | awk -F ": " '{print $2}'`
sonarPath=`cat $BUILD_LOG | grep "SonarPath" | awk -F ": " '{print $2}'`
############## Send Email ##################
if [ ${errorCounts} -gt 0 ] || [ ${comparedFailedCounts} -gt 0 ]
then
mail_subject=${PROJECT_NAME}"_Service_Report Job - Build # "${BUILD_NUMBER}" Failure"'!'
mail_body="Hi, ${PROJECT_NAME} project member <BR><BR>The latest build package has been installed to service - ${SERVICE_NAME} [$INSTANCES], but the API testing has some test case failed.<BR><BR>Errored Test Case: ${errorCounts}<BR>Failed Test Case: ${comparedFailedCounts}<BR><BR>For details please refer to Test Management System - http://vm10765.global.xxx.net:8080/tms/login.spring<BR><BR>SonarQube - $sonarPath<BR><BR>Report as below:<BR><BR>""$report_context"
sendEmail.pl --subject "${mail_subject}" --emaillist "${EMAIL_LIST}" --emailcclist "${EMAIL_CC_LIST}" --mailbody "$mail_body" --attached ${REPORT_PATH}
else
if [[ $TESTPLAN_ID == "" ]]; then
mail_subject=${PROJECT_NAME}"_Service_Report Job - Build # "${BUILD_NUMBER}" Success"'!'" [No TestPlan for API testing]"
mail_body="Hi, ${PROJECT_NAME} project member <BR><BR>The latest build package has been installed to service - ${SERVICE_NAME} [$INSTANCES].<BR><BR>SonarQube - $sonarPath<BR><BR>Report as below:<BR><BR>""$report_context"
else
mail_subject=${PROJECT_NAME}"_Service_Report Job - Build # "${BUILD_NUMBER}" Success"'!'
mail_body="Hi, ${PROJECT_NAME} project member <BR><BR>The latest build package has been installed to service - ${SERVICE_NAME} [$INSTANCES] and API testing has passed.<BR><BR>For detailed test results, please refer to Test Management System - http://vm10765.global.xxx.net:8080/tms/login.spring<BR><BR>SonarQube - $sonarPath<BR><BR>Report as below:<BR><BR>""$report_context"
fi
sendEmail.pl --subject "${mail_subject}" --emaillist "${EMAIL_LIST}" --emailcclist "${EMAIL_CC_LIST}" --mailbody "$mail_body" --attached ${REPORT_PATH}
fi
########### Tear Down ###########
rm -rf ${BUILD_LOG_FOLDER}
  
  我设置的是每天运行一次所有的project的持续集成, 收到的Email如下图所示:
DSC0003.jpg
  
  
DSC0004.jpg
DSC0005.jpg
  Report中的很多信息都是来源于Sonar
  ##转载注明出处:http://www.cnblogs.com/wade-xu/p/4378224.html
  
  到这里就结束了吗,还没有, 如果Build job,单元测试不通过或者其他原因导致Build Failure, 那怎么办?
  再加一个Post Build job, 来监控Build job, 如果挂了,发email通知项目人员。
  下图为Build job 加一个Action, 当Job Failed时触发Template_Service_Post_Build job
DSC0006.jpg
  
  Template_Service_Post_Build 脚本如下:



rm -rf ${WORKSPACE}/*
######## Import config file #########
cd ~/jenkins/common/Config
. Project_Config.txt
####### SET ENV #############
export SCRIPTS_HOME=${SHARED_FOLDER}/Scripts
cd ${SCRIPTS_HOME}
chmod 755 *
export PATH=$PATH:`pwd`
###### Initial parameters #############
LOG_NAME=${PROJECT_NAME}"_BUILD_"${PIPELINE_NUM}".log"
BUILD_LOG=${SHARED_FOLDER}/Log/${PROJECT_NAME}"_"${PIPELINE_NUM}/$LOG_NAME
EMAIL_LIST=${PROJECT_NAME}"_EMAIL_LIST"
EMAIL_LIST=$(eval echo \${$EMAIL_LIST})
EMAIL_CC_LIST=${PROJECT_NAME}"_EMAIL_CC_LIST"
EMAIL_CC_LIST=$(eval echo \${$EMAIL_CC_LIST})
author_list=`cat $BUILD_LOG | grep "Author"` || true
###### Monitor Service Build Job ########
build_job_url=`cat $BUILD_LOG | sed -n '/overview->logURL/p' | awk -F ": " '{print $2}'`
build_job_build_number=`echo $build_job_url | awk -F "/" '{print $(NF-1)}'`
build_job_log_url=$build_job_url"logText/progressiveText?start=0"
build_job_console_output=$build_job_url"console"
mail_subject=${PROJECT_NAME}"_Service_Build Job - Build # "${build_job_build_number}" Failure"'!'
mail_body="Hi, ${PROJECT_NAME}"" project member"$'\n'$'\n'"Build Failure"'!'$'\n'$'\n'"For details please refer to Console Output - ${build_job_console_output}"$'\n'$'\n'"The latest code author list as below:"$'\n'"${author_list}"
sendEmail.pl --subject "${mail_subject}" --emaillist "${EMAIL_LIST}" --emailcclist "${EMAIL_CC_LIST}" --mailbody "$mail_body" --msg_type "text"
  
  同理还需要加一个Template_Service_Post_Polling job来监控Template_Service_Polling job, 如果轮询Service的结果是重启失败,则邮件通知项目组人员。
  脚本如下:



rm -rf ${WORKSPACE}/*
######## Import config file #########
cd ~/jenkins/common/Config
. Project_Config.txt
####### SET ENV #############
export SCRIPTS_HOME=${SHARED_FOLDER}/Scripts
cd ${SCRIPTS_HOME}
chmod 755 *
export PATH=$PATH:`pwd`
###### Initial parameters #############
LOG_NAME=${PROJECT_NAME}"_BUILD_"${PIPELINE_NUM}".log"
BUILD_LOG=${SHARED_FOLDER}/Log/${PROJECT_NAME}"_"${PIPELINE_NUM}/$LOG_NAME
EMAIL_LIST=${PROJECT_NAME}"_EMAIL_LIST"
EMAIL_LIST=$(eval echo \${$EMAIL_LIST})
EMAIL_CC_LIST=${PROJECT_NAME}"_EMAIL_CC_LIST"
EMAIL_CC_LIST=$(eval echo \${$EMAIL_CC_LIST})
author_list=`cat $BUILD_LOG | grep "Author"`
###### Monitor Service Polling Job ########
polling_job_url=`cat $BUILD_LOG | sed -n '/pollingjob->logURL/p' | awk -F ": " '{print $2}'`
polling_job_build_number=`echo $polling_job_url | awk -F "/" '{print $(NF-1)}'`
polling_job_log_url=$polling_job_url"logText/progressiveText?start=0"
polling_job_console_output=$polling_job_url"console"
mail_subject=${PROJECT_NAME}"_Service_Polling Job - Build # "${polling_job_build_number}" Failure"'!'
mail_body="Hi, ${PROJECT_NAME}"" project member"$'\n'$'\n'"Service Restart Failure"'!'$'\n'$'\n'"For details please refer to Console Output - ${polling_job_console_output}"$'\n'$'\n'"The latest code author list as below:"$'\n'"${author_list}"
sendEmail.pl --subject "${mail_subject}" --emaillist "${EMAIL_LIST}" --emailcclist "${EMAIL_CC_LIST}" --mailbody "$mail_body" --msg_type "text"
  ##转载注明出处:http://www.cnblogs.com/wade-xu/p/4378224.html
  
  现在我们来看一下更新后的CI 流程图
DSC0007.jpg
  
  那么,这个flow的前提是 所有的项目都是按这个流程来的,万一有些特别的项目呢? 比如一个项目,它在Build之前 需要Pre-Build一个CommonUtils包, 那怎么办呢,简单一点就是为了这个项目定制一下。
  为了更具通用性,扩展性,方便的插入一些special job, 我们可以在每个job之间加入 Exit Point, 以适应一些特别的项目想在任意点Plug in一些特别的job,
  除了要在Config job 加上一些规则, 比如 export ProjectX_EXIT_POINT=Template_Service_Commit_Auto_Build|Special ProjectX-PreBuild job
  还要在每个job里加一些判断语句,比如当前run的job name 等于ProjectX_EXIT_POINT以竖线分割的第一个值,则表明要在这个job退出, 第二个值表明要去调的special job name,当然 special job 里做完了自己的事之后还是要回调原来flow的下一个job
  
  流程图更新如下所示:
DSC0008.jpg
  
  感谢阅读,如果您觉得本文的内容对您的学习有所帮助,您可以点击右下方的推荐按钮,您的鼓励是我创作的动力。
  ##转载注明出处:http://www.cnblogs.com/wade-xu/p/4378224.html
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-146861-1-1.html 上篇帖子: 用python将jenkins构建的apk下载地载生成二维码提供下载 下篇帖子: 在Ubuntu12下安装配置Jenkins
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表