一. 需求背景
需求背景在 基于ProtoBuf协议消息体的自动化代码生成工具 一文中已有描述,有兴趣的同学可以了解一下,这篇文章相对比较简单,只是上篇文章流程环节中的一个叙述。
首先说明下需求,由于目前前端origin_proto目录中的消息体文件都是从后端拷贝过来的,后端一有修改就必须通知到前端的改动点,并且将具体文件,改动内容发给前端,前端替换完对应的文件内容才能进行正确的联调,这样的操作很傻x,效率也是比较低下的。由此,我就可以从这点入手,做一个同步代码任务, 用以同步前后端的代码
二. 方案选择
- 方案一: 基于gitlab提供的webhook钩子触发同步任务执行
原理:每次后端提交完代码都会发送一个请求都中台, 中台检测后端的proto目录,若有检测到更新,则将后端的proto目录更新到前端。大概流程就是这么简单。不过短短几句话,却是很麻烦的操作,而且在实际的使用的中,也是会遇到问题。这里大概罗列下可预见的缺点:
- 更新检测太过频繁
每次后端提交代码后,都会触发检查, 这里就会存在很多不必要的检查
- 没必要的合并工作
后台更新了proto目录中的其他文件(不提供给前端使用的文件),但是服务端还是检测到目录的更新,这就会导致多了一次不必要的代码合并
- 合并冲突
在每次合并操作前,虽然服务端都会拉取最新的代码,但是不排除前端有人修改到origin_proto目录中的文件,并在服务端进行合并操作过程中提交代码, 而此时服务端再进行提交的话就有可能会遇到冲突,后续就需要人工再发起一次请求, 偏麻烦
- 方案二: 基于Jenkins的定时触发同步任务执行
由于方案一存在的缺点,并且实现复杂程度偏高, 我们在实际运用中还是选择了方案二;
原理: 在打包服务器中新建一个目录, 存放前端与后端两个项目,编写shell脚本,脚本的大概流程如下:
################################################################################
# 具体步骤
# 1. 打开后台项目, 拉取最新代码, 使用git log -- {路径}/{后端项目的proto菜单}, 记录后端proto目录最近提交记录时间, 记为backTime
# 2. 打开前端项目,清空暂存区的代码(这里是为了干掉上次代码提交冲突,没提交成功的文件), 拉取最新代码,以同样方式获取记录proto目录最近提交时间, 以为fontTime
# 3. 对比两个时间, 如若backTime > fontTime, 则表明后台更新了proto文件,需要更新,进入第4个步骤, **否则退出流程**
# 4. 清空前端proto目录底下的文件,将后台项目proto目录底下的所有proto复制一份, 并粘贴到前端对应的目录文件
# 5. 运行命令 git add . => git commit -m "[{项目名称}][{版本号}][AUTO TASK][MERGE PROTO] 自动化合并proto文件" => git push
# 6. 完成任务, 退出流程
################################################################################
接下来是代码实现
...
function LogInfo()
{
echo ""
echo "[INFO#]==================================================================="
echo "[INFO#] $1 "
echo "[INFO#]==================================================================="
}
function main() {
### base param 获取传入参数
## 分支名称
branch_name=$1
## 是否强制合并 0:否 1:是
isforce=$2
echo "[==================BASE_PARAM==================]"
echo "分支名称: ${branch_name}"
echo "是否强制更新: ${isforce}"
echo "[==================BASE_PARAM==================]"
################################
LogInfo "(1). Get Proto Folder Update Time"
################################
### 打开后台项目目录, 获取proto文件夹最近一个更新时间
BACK_WORK_PATH="${xxx路径}"
BACK_PROTO_PATH="${xxx路径}"
cd $BACK_WORK_PATH
git checkout ${branch_name}
git pull origin ${branch_name}
### 用以获取具体目录的更新时间戳
BACK_LAST_MODIFY_TIMESTAMP=`git log -1 --pretty=format:"%at" ${BACK_PROTO_PATH}`
### 输出后端上次更新的时间戳
echo "Back last modify time is : ${BACK_LAST_MODIFY_TIMESTAMP}"
### 打开前端项目目录, 获取proto文件夹最近一个更新时间
FRONT_WORK_PATH="${xxx路径}"
FRONT_PROTO_PATH="${xxx路径}"
cd $FRONT_WORK_PATH
### 打开目录后先清空前端的暂存区
git reset --hard HEAD@{0}
git clean -xdf
### 清空操作结束
git checkout ${branch_name}
git pull origin ${branch_name}
### 用以获取具体目录的更新时间戳
FRONT_LAST_MODIFY_TIMESTAMP=`git log -1 --pretty=format:"%at" ${FRONT_PROTO_PATH}`
### 输出前端上次更新的时间戳
echo "Front last modify time is : ${FRONT_LAST_MODIFY_TIMESTAMP}"
LogInfo "(2). Compare Last Modify Time"
### 开始对比时间
### 后台更新时间如果大于前台更新时间, 或强制更新为1, 则进入更新阶段
if [ $BACK_LAST_MODIFY_TIMESTAMP -gt $FRONT_LAST_MODIFY_TIMESTAMP -o ${isforce} -eq 1 ]; then
### 后台更新的时间比前端大, 说明后台有更新, 进行COPY操作
echo "Need to Update"
### 后端proto路径下的所有后缀名为proto的文件
BACK_FILE_PATH="${xxx路径}/*.proto"
FRONT_FILE_PATH="${xxx路径}"
### 先删除前端的proto目录底下的所有文件
rm -r ${FRONT_FILE_PATH}/*
### 开始复制
\cp -f ${BACK_FILE_PATH} ${FRONT_FILE_PATH}
### 复制操作结束, 开始commit, 并进行提交
LogInfo "(3) Copy Finish, Start Commit"
### 输出修改项
git status
git add .
git commit -m "[${项目名称}][$1][AUTO_TASK][PROTO_MERGE] 自动化同步proto文件" --no-verify
LogInfo "(4) Commit Finish, Start Push"
git push origin ${branch_name}
LogInfo "(5) Push Finish, Task Exit"
else
### 没有改变, 无需更新
LogInfo "No Change, Exit";
fi;
}
### Start
main $@
OK, 整个脚本的实现到此就完了,是不是非常简单呢
接下来是Jenkins的接入
- 新建一个Jenkins任务
- 配置任务
必选参数git分支配置 可选参数isforce配置 然后是定时构建配置(默认凌晨2点执行同步任务) 接着是Build配置, 选择运行的机器, 然后填入执行命令就可以啦
Bingo! 这样整个流程就结束了
- 三. 结果展示
看看同步任务的log, 可以看到已经是完美合并的
然后不需要合并的情况下也不执行合并, 完美!
好啦,这个模块的分享到这里就结束啦!
这是萌新的第二篇文章,希望大佬们多给点建议!
射射大家
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!