背景
语言:C++,Qt
操作系统:麒麟、凝思、红帽子
版本管理:SVN
持续集成工具:Jenkins
语言工具:shell,java
小目标
由于系统应用很大,src模块多,操作系统多,手工编译费时费力,而且是毫无技术含量的工作,于是用Jenkins pipeline+shell脚本实现多操作系统环境的自动编译功能,编译成功后,自动提交到SVN,编译出错时,自动发送包含错误信息的邮件给相关研发人员。
实现
Jenkins添加pipeline任务,并添加pipeline脚本,这样可以在不同操作系统同时进行编译
完整的pipeline脚本如下:
pipeline {
agent none
parameters {
string(name:'branch_name', defaultValue: 'release', description: '分支名称')
booleanParam(name: 'make_type', defaultValue: false, description: '是否make clean')
}
stages {
stage('编译开始了'){
parallel{
stage('麒麟编译'){
agent {label '172.20.1.206-kylin'}
steps{
dir('/home/a5000/jenkins'){
sh 'sh build.sh 麒麟kylin ${branch_name} ${make_type}'
}
}
}
stage('凝思编译') {
agent {label '172.20.1.108-linx'}
steps{
dir('/home/a5000/jenkins'){
sh 'sh build.sh 凝思linx ${branch_name} ${make_type}'
}
}
}
stage("红帽子编译"){
agent {label '172.20.1.232-redhat'}
steps{
dir('/users/a5000/jenkins'){
sh 'sh build.sh 红帽子Redhat7.2 ${branch_name} ${make_type}'
}
}
}
}
}
}
}
脚本说明:
1.branch_name:pipeline中的参数,因为我有多个分支需要编译,所以通过参数控制编译哪个分支
2.make_type:执行qmake之前是否进行clean操作,默认值是false
3.build.sh:真正执行编译、提交编译结果等操作的shell脚本,放在编译节点机器上,直接调用
下面放上build.sh完整脚本:
#!/bin/sh
#name:build.sh
#auth:yaxxx
#usage:build.sh 麒麟 release false
echo "Current location $PWD"
echo "Home dir:$HOME"
echo "QTDIR:$QTDIR"
PARA_NUM=$#
if [ $PARA_NUM -lt 1 ]; then
echo "project folder required,using method:build.sh xxx xxx 0"
exit 0
fi
OS_TYPE=$1
MODULE_FOLDER=$HOME/smartsys_$2
BIN_FOLDER=$MODULE_FOLDER/bin
MAKE_TYPE=$3
LOG_NORMAL=$PWD/build_output_normal.out
LOG_ERROR=$PWD/build_output_error.out
SVN_INFO=$PWD/svn.txt
echo "**************$OS_TYPE环境:开始编译smartsys_$2分支******************"
echo "step1. go into $MODULE_FOLDER"
cd $MODULE_FOLDER
echo "step2. svn update dev and binary"
#source export.sh
source $HOME/.bash_profile $PWD
svn cleanup
svn up binary
svn up dev 1>$SVN_INFO
echo "step3. qmaked and make"
cd $MODULE_FOLDER/dev/src
if $MAKE_TYPE;then
echo "make clean before qmake"
make clean > $LOG_NORMAL
else
echo "Do not make clean"
fi
qmake -r CONFIG+=debug >> $LOG_NORMAL
make 1>>$LOG_NORMAL 2>&1
ERROR_STR=$(cat $LOG_NORMAL |grep -E '错误:|error:')
if [ -z "$ERROR_STR" ];then
echo "************$OS_TYPE环境:smartsys_$2分支 编译正确************"
echo "step4. bin svn commit"
cd $BIN_FOLDER
rm -rf *.gz *.tar
svn add * --force --no-ignore
svn commit -m "commit bin by jenkins/build.sh"
else
echo "************$OS_TYPE环境:smartsys_$2分支 编译有错误,发邮件给开发者************"
echo "step4. mail to developer"
echo "$ERROR_STR">$LOG_ERROR
if [[ "$OS_TYPE" =~ "7.2" ]];then
SRC_DIR=$(grep '进入目录' $LOG_NORMAL|awk 'END{print $2}'|sed 's/进入目录“//g'|sed 's/”//g')
else
SRC_DIR=$(grep 'Entering' $LOG_NORMAL|awk 'END{print $4}'|sed 's/`//g'|sed "s/'//g")
fi
cd $SRC_DIR
SVN_URL=$(svn info|grep 'URL'|awk '{print $2}')
SVN_VERSION=$(svn info|grep '最后修改的版本'|awk '{print $2}')
SVN_USER=$(svn info|grep '最后修改的作者'|awk '{print $2}')
sed -i "1i****************本次编译错误概况如下****************" $LOG_ERROR
sed -i "2i"****************操作系统:$OS_TYPE"" $LOG_ERROR
sed -i "3i"****************分支:smartsys_$2"" $LOG_ERROR
sed -i "4i"****************路径:${SVN_URL}"" $LOG_ERROR
sed -i "5i"****************程序:${SRC_DIR}"" $LOG_ERROR
sed -i "6i"****************作者:$SVN_USER"" $LOG_ERROR
sed -i "7i"****************版本:$SVN_VERSION"" $LOG_ERROR
sed -i "8i"****************详细编译错误信息如下:****************"" $LOG_ERROR
echo "************************************************************************************">>$LOG_ERROR
echo "USER:"$SVN_USER >> $LOG_ERROR
#拷贝日志到156邮件服务器上
#scp $LOG_ERROR root@172.20.1.156:/root/remote_build_log
fi
echo "************$OS_TYPE环境:smartsys_$2分支 编译完成************"
收到的邮件样例如下: