一、需求背景
就目前公司,拆分四条业务线,每条业务线涉及服务达到十多个,开发版本迭代迅速,但是开发使用git的规范确是有点惨不忍睹,所以根据git框架提供的钩子定制了一套规范研发整体成员的约束规则。下面讲解下如何将需求进行拆分的
二、分析步骤
- 了解,调研研发成员使用git进行代码管理的习惯,根据习惯择其优势,去其糟粕
- 深入了解git提供的钩子的原理,选择符合自己公司发展的钩子进行使用
- 定制方案,整理自己的规范流程,脚本设计思路,进行评估
- 待方案最终落地,进行开发设计,实现这一套规范
三、讲解自己的设计思路
- 根据内部研发成员使用习惯,发现开发进行提测使用的是tag,分支仅作为开发设计代码的基线,而分支来源是从master上建立的
- 目前开发成员对tag、branch命名实在有点难看,不方便业务经理及各个成员进行良好的代码管理
- 所以针对tag、branch的名称都是自己要进行脚本校验的
- branch命名:分支前缀 - 业务线名称 - 服务名 - 部署环境 -日期号
- tag命名:分支前缀 - 业务线名称 - 服务名 - 部署环境 - 日期号 - 版本号
分支前缀:以feature、bugfix、hotfix、restructure、release命名顾名思义
业务线名称:实现CI通知业务经理进行代码review 服务名:实现CI通知业务经理进行提交服务的代码review
部署环境:由于公司版本迭代迅速,测试环境有多套,通知CI具体部署哪一套环境
日期号:确定创建分支,tag时间,避免多人开发同一个服务重名问题 版本号:branch,tag区分;开发进行版本迭代的标签
四、git钩子选择解析
- 由于git钩子框架提供比较多,分为本地git钩子、git服务端钩子
- 根据公司业务场景及需求,在本地Git钩子选取,commit-msg进行提交内容校验;在服务端选取pre-receive进行分支、tag命名校验,post-receive实现CI
- commit-msg文件存在本地git项目隐藏目录下:.git/hooks
- 服务端pre-receive、post-receive存在,git仓库中的,项目名.git目录下有个hooks文件
5.hooks文件是个软连接,指向gitlab下的hooks目录(由于本公司源码是通过gitlab进行管理的)
6.hooks目录就是存放pre-receive、post-receive
7.关于本地钩子校验、服务端钩子校验实现原理可参考以下链接
https://www.git-scm.com/book/zh/v2/自定义-Git-Git-钩子
https://www.jianshu.com/p/527e34f53b51?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
五、脚本分析
1.pre-revceive脚本校验内容
- 校验:分支前缀 - 业务线名称 - 服务名 - 部署环境 - 日期号 分支前缀:
- 获悉当前分支开发的功能方向
- 业务线名称:获悉归属哪条业务线,触发邮件通知业务经理review代码
- 服务名:获悉服务进行CI部署测试环境
- 部署环境:根据编号部署具体哪套测试环境
- 日期:了解分支创建时间
#!/bin/bash
function init(){
echo -e "\033[31;47m 分支校验异常,详细内容请参考:URL \033[0m"
}
#分支名头部校验
function headCheck(){
if [ $headName == "feature" -o $headName == "hotfix" ];then
echo "分支头校验正常"
else
init
exit 1
fi
}
#业务线名称校验
function businessCheck(){
if [ $businessName == "sdk" -o $businessName == "eusdk" -o $businessName == "gamecat" -o $businessName == "wogame" ];then
echo "业务线名称校验正常"
else
init
exit 1
fi
}
#服务名称校验
function serverCheck(){
if [ $businessName == "sdk" -o $businessName == "gamecat" ];then
value=`echo "${arrayGamecat[@]}"|grep -wq $serverName && echo true || echo false`
if [ $value == true ];then
echo "$serverName服务名校验正常"
else
init
exit 1
fi
elif [ $businessName == "eusdk" ];then
value=`echo "${arrayEusdk[@]}"|grep -wq $serverName && echo true || echo false`
if [ $value == true ];then
echo "$serverName服务名校验正常"
else
init
exit 1
fi
elif [ $businessName == "wogame" ];then
value=`echo "${arrayWogame[@]}"|grep -wq $serverName && echo true || echo false`
if [ $value == true ];then
echo "$serverName服务名校验正常"
else
init
exit 1
fi
fi
}
#环境校验
function environmentCheck(){
value=`echo "${arrayEnv[@]}"|grep -wq $testNumber && echo true || echo false`
if [ $value == true ];then
echo "环境校验正常"
else
init
exit 1
fi
}
#日期校验
function dataCheck(){
if [ ${#length} -ne 12 ];then
init
exit 1
fi
echo "日期校验正常"
}
#tag版本号校验
function tagVersionCheck(){
value=`echo "${arrayTag[@]}"|grep -wq $1 && echo true || echo false`
if [ $value == true ];then
echo "tag版本号校验正常"
else
init
exit 1
fi
}
#初始化游戏猫服务数组
arrayGamecat=(base baseservice gamecatoms catapp gamecatmeng report androidsmsmonitor cat gamecatsdk util trade dashboard wechat uc statis tradetimer pack meng operation sensitiveword framework rocketmq gamecates gamecatmonitor packandroid bizdata cpsplatform commonlib)
#初始化EU服务数组
arrayEusdk=(HDSdkWeb HDSdkManage HDSdkRely framework manage-server apiserver pack capital channel tools registercenter task oms manage base statis utrade util demogateway omsstatis demobase)
#初始化Wogame服务数组
arrayWogame=(uc woapp register-center tools account biz trade statis oms timer womeng wosdk es common)
arrayEnv=(1 2 3)
#初始化tag版本
arrayTag=(v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15)
#获取输入流数据
read oldVersion newVersion branch;
echo ${oldVersion}
echo ${newVersion}
echo ${branch}
#获取tags或heads
tagOrHead=`echo $branch|awk -F"/" '{print $2}'`
#获取分支名
branchName=`echo $branch |awk -F"/" '{print $3}'`
#根据分支名获取分支头名
headName=`echo $branchName|awk -F"-" '{print $1}'`
#根据分支名获取服务名
serverName=`echo $branchName|awk -F"-" '{print $3}'`
#根据分支名获取业务线名
businessName=`echo $branchName|awk -F"-" '{print $2}'`
#根据分支名获取部署的测试环境
testNumber=`echo $branchName|awk -F"-" '{print $4}'`
#获取分支日期
length=`echo $branchName|awk -F"-" '{print $5}'`
#调用方法
if [ $tagOrHead == "heads" ];then
headCheck
businessCheck
serverCheck
environmentCheck
dataCheck
else
tagVersion=`echo $branchName|awk -F"-" '{print $6}'`
headCheck
businessCheck
serverCheck
environmentCheck
dataCheck
tagVersionCheck $tagVersion
fi
post-recevice脚本实现CI
- 实时通知业务线经理review代码
- 部署测试环境
#!/bin/env bash
#初始化邮箱变量
sdkMail=通知邮件人
gamecatMail=通知邮件人
wogameMail=通知邮件人
#初始化基础方法
function sendMail(){
sendEmail 命令发送邮件通知收件人
}
function excuteJenkins(){
curl -XG -s -u 用户名:密码"Jenkins远程构建URL"
}
#初始化方法
function sdk(){
if [ $businessName == "sdk" ];then
#推送邮件至SDK
sendMail $sdkMail server
#远程构建Jenkins部署测试环境
if [ $testNumber -eq 1 ];then
echo "测试一套环境构建中"
excuteJenkins
exit 0
elif [ $testNumber -eq 2 ];then
echo "测试二套环境构建中"
excuteJenkins
exit 0
else
echo "测试三套环境构建中"
excuteJenkins
exit 0
fi
elif [ $businessName == "eusdk" ];then
#推送邮件至SDK
sendMail $sdkMail eusdk
#远程构建Jenkins部署测试环境
if [ $testNumber -eq 1 ];then
echo "融合一套环境构建中"
excuteJenkins
exit 0
else
echo "融合二套环境构建中"
excuteJenkins
exit 0
fi
fi
}
function Wogame(){
if [ $businessName == "wogame" ];then
#推送邮件至wogame
sendMail $wogameMail wogame
#远程构建Jenkins部署测试环境
if [ $testNumber -eq 1 ];then
echo "wogame环境构建中"
excuteJenkins
exit 0
else
echo "testNumbe错误环境未构建"
fi
fi
}
function Gamecat(){
if [ $businessName == "gamecat" ];then
#推送邮件至游戏猫
sendMail $sdkMail server
#远程构建Jenkins部署测试环境
if [ $testNumber -eq 1 ];then
echo "测试一套环境构建中"
excuteJenkins
exit 0
elif [ $testNumber -eq 2 ];then
echo "测试二套环境构建中"
excuteJenkins
exit 0
else
echo "测试三套环境构建中"
excuteJenkins
exit 0
fi
fi
}
read oldVersion newVersion branch
#获取tags或heads
tagOrHead=`echo $branch|awk -F"/" '{print $2}'`
#获取分支名
branchName=`echo $branch |awk -F"/" '{print $3}'`
#根据分支名获取服务名
serverName=`echo $branchName|awk -F"-" '{print $3}'`
#根据分支名获取业务线名
businessName=`echo $branchName|awk -F"-" '{print $2}'`
#根据分支名获取部署的测试环境
testNumber=`echo $branchName|awk -F"-" '{print $4}'`
#调用方法
if [ $tagOrHead == "tags" ];then
sdk
Gamecat
Wogame
fi
六、流程
以上内容不喜勿喷,共勉!!!