GitLab merge request 脚本

介绍我的编写的 GitLab merge request 脚本,包括脚本每次版本迭代的内容、脚本的功能等。

GitLab merge request 脚本
Photo by Pankaj Patel / Unsplash

背景

2022 年 5 月,我们把公司的 iOS 项目从 phab 迁移到了 GitLab 上。

迁移之前,我们提代码合并可以用 arc 指令,它会自动 lint 并创建一个 land 请求,抛出链接。点击链接就可以找同事领导合并代码了。但迁移之后,在不借助三方工具(比如 Tower 高级版)的情况下,创建一个 GitLab 的 merge request (以下简称 mr)需要提出人先把分支 push 上去,然后在 GitLab 的工程页面点击创建 mr,填写 title 等信息。然后再把创建的 mr 地址复制给同事领导。这一套流程无疑是很繁琐的。

初版 2022.07

在 GitLab 的官方文档里,我发现了执行 git push 指令时携带一些参数可以直接创建 mr,并且会在终端输出 mr 的链接。

借着 GitLab 的这个特性,我用 shell 语言写了初版的脚本,文件名是 mergeRequest.sh

脚本大致流程:

  1. 检查是否有未提交的改动。如果有,终止脚本
  2. 要求输入目标分支。默认是 master,可以直接回车
  3. 要求输入 mr 标题。默认是最近一次提交的信息,可以直接回车
  4. 获取当前分支(源分支)
  5. 从当前分支上创建并切换到一个缓存分支
  6. 将缓存分支 push 到 remote。push 的时候携带了创建 MR 需要的一些信息
  7. 将分支切回本地的源分支,并删掉缓存分支
  8. 输出 mr 链接

初版 shell 脚本为了能截获 git push 后的输出,以便在输出中拿到 mr 链接,是把输出重定向到了一个 txt 文件里,然后读取文件、正则匹配出 mr 链接。

初版 shell 脚本流程

mergeRequest.sh 脚本在速度上是非常快的,推广给了几位同学,他们也非常乐意在开发过程中使用。

二版 2023.04

公司在 2023 年上半年推出了几项新的开发「政策」,要求在 review 比较大的 mr 时必须添加几个评论,另外 iOS 主工程上的 mr 必须补上组件库的 mr。

我入职时,我们的 iOS 开发人员就在搞组件化了。到 2023 年,主工程几乎就是个壳子了。因此我们主工程的 mr 几乎都是对 Podfile 的改动,改一下组件库的 commit。但 review 时,光看 Podfile 的改动肯定是不行的,需要提出人把组件库的 mr 或者 commit 也贴出来,方便 review 具体改动代码。

这样就对我的脚本提出了新的需求——创建 mr 时根据 Podfile 改动获取相关组件库的改动,并且把组件库的 mr 放到主工程的 mr 里。

这时候再用 shell 实现肯定是不行了。因此我转向了使用 Python,并且借助了 python 的 python-gitLab package。这个 package 能够读取和操作 GitLab 上的工程。

使用 Python 写的脚本文件是 createMR.py。但是每次用类似 python createMR.py 的指令来执行这个脚本有点麻烦。我就用 shell 重新包装了一下,写了 createMR.sh 脚本。这个脚本内部默认执行 createMR.py,但也可以通过 --fast 参数来指定使用初版的 mergeRequest.sh。毕竟初版的脚本速度快,不需要获取各种工程配置,不需要处理 Podfile,在组件库中创建 mr 还是挺方便的。

在写二版脚本时,我发现我自己角色的权限有限,没法直接用 python-gitLab 提供的 mr 创建 API。不得不用 os.system 模拟 shell 指令,像初版脚本那样在输出重定向文件里找到 mr 链接。

二版脚本的整体流程是和初版差不多的,只不过多了对 Podfile 的处理,mr 的 description 里面带了相关组件库的 mr 或者 commit 链接。

GitLab 截图

三版 2023.06 ~ 2023.07

机器人消息

这一版在二版的基础上添加了发送飞书机器人消息的支持,添加了懒人模式,以及支持了本地自动更新脚本仓库。

机器人消息是利用了飞书机器人提供的 webhook 能力。我没有申请高级版机器人,用的是普通版。高级版机器人需要企业审核,能随意给单个用户发送消息,还能获取用户信息,普通版只能在指定的群里发消息,但也够用了。

创建飞书机器人

机器人消息是在 mr 创建完成后发送的,发送前会弹出多选选择器,选择自己想要 @ 的人。

懒人模式

懒人模式是一个非常 feature 的功能,大大提高了创建 mr 的效率。

懒人模式利用 python-gitlab 提供的 API,在 Podfile 列出的所有组件库(除三方外)里,检索各自的 commit 是不是组件库主分支最新的 commit。比如下面主工程 Podfile 列出的 KEPPrimeKitModule,对应的 commit 是 42fba9031a8f7de1b0b4bf97f7daa1f8b3bf1879,如果 KEPPrimeKitModule 仓库主分支的 commit 不是 42fba9031a8f7de1b0b4bf97f7daa1f8b3bf1879,那就说明这个仓库还有提交没有合并到主工程。

pod "KEPPrimeKitModule", :git => "git@gitlab.gotokeep.com:ios/ug/KEPPrimeKitModule.git", :commit => "42fba9031a8f7de1b0b4bf97f7daa1f8b3bf1879", :inhibit_warnings => false

检索时会过滤掉超过七天没有合并的提交,因为这样的提交大概率是作者本人也不想合并的。另一方面,既然我想用懒人模式创建 mr 了,那我肯定是刚刚在组件库提交了改动。

检索完成后,会显示一个多选列表,脚本使用者可以选出来自己想要更新的组件库。选择完后,会再次弹出来一个单选列表,这个列表列出来的是刚才选择的那些组件库里最新提交的 commit message,以便生成 mr 的 title,当然也可以自己输入。脚本会在 Podfile 里修改已选择组件对应的 commit,并且自动 git commit,message 当然是刚才选择的 message 了。

上面操作做完后,剩下的流程就跟二版类似了,最后会发送机器人提醒消息。

以下是懒人模式的流程(画面下方的 sublime merge 界面是为了展示脚本对仓库的改动):

0:00
/0:50

懒人模式

仓库自动更新和依赖自动安装

脚本起初只有我和我旁边的几位同事在用,后来别的组同事也在用了。这样的话,每次脚本仓库有 feat 或者 fix 时就不能口头说 pull 脚本仓库最新代码了。我就写了个 repo_update_check.sh,放在了 createMR.sh 的最后面执行。每次 mr 创建完成后,就会触发脚本仓库的自动更新,就像软件更新版本一样。

这一版还引入了几个三方库,比如 pick。有些同事第一次用脚本时,电脑里很大可能没有安装这些 package,就会报错。所以我在脚本的入口加了依赖的检测和自动安装。

# 安装依赖
declare -a arr=("python-gitlab" "GitPython" "pick" "dacite" "numpy")
for package in "${arr[@]}"
do
	# echo "$package"
	env_check=$(pip3 --disable-pip-version-check list | grep -F "$package")
	if [[ -z "$env_check" ]]; then
		echo "$package 没有安装. 安装中..."
		pip3 install "$package"
	fi
done

第四版 2023.09 ~ 2023.10

这一版主要就是引入了服务端,代码 Sirius 部署在我的 DO 服务器上。

新功能包括:

  1. mr 合并后,发送机器人消息通知提出人。这样提出人就不需要时不时刷新 mr 网页看看代码有没有被合并了。
  2. mr 创建后,超过半个小时没有被合并的话,会定时向群里发送提醒消息,@ 相关人员。这个定时任务只会在工作日的 10 点到 19 点执行。
待处理通知
定时提醒
已合并通知

这一版的更新灵感来源于 GitLab 的 webhook 能力。GitLab 有很多事件可以触发 webhook,比如 mr 的创建/合并/关闭,pipeline 事件,push 事件,issue 事件等等。想要使用这个,就需要咱们在 GitLab 仓库的设置里添加一个 webhook 地址,以及选择监听的事件。事件触发 webhook 时,GitLab 就会向配置的那个 webhook 地址发送一个 post 请求,请求体里携带了事件的数据。

我用 Spring Boot 在我的服务器上部署了一个 post 接口,并把接口地址配置在 webhook 里。这样当有 mr 被合并时,我就能通过这个接口拿到事件的数据,接着再调用飞书机器人的 webhook,发送提醒消息,告知提出人 mr 已合并。

做定时提醒的话,需要我的接口在收到 post 请求后,把数据存到数据库里,主键是 mr 的 iid (没打错,是两个 i)。这样定时任务触发时,遍历一下数据库数据,发送提醒消息就好了。然后收到 mr 合并事件时,再把数据里对应 iid 的数据删掉,防止无用数据累积。

数据库用的是开源的 MariaDB,不得不说占用内存是真高。我的服务器一共才 2GB 内存,这个服务启动后内存占用就涨到了 500MB。优化空间还是挺大的。

开发的时候我是在本地的 Docker 环境里运行一个 MariaDB 服务,要不然执行时会出现连接数据库失败的错误。部署后可以在本地用 DataGrip 这样的软件连上服务器上的数据库,进行数据查看或删除。

这一版是我写这篇文章时的最新版。功能基本上闭环,感觉也没有什么新功能新灵感可以往上加了。如果非要加的话,那就是和 CI/CD 的深入集成吧,又或者加入评论通知啥的,不过那样需要向公司审批高级版的飞书机器人。最近可能要离职,没有心思和精力搞了。也许到了下家公司,我做的这脚本就派不上用场了,不过那是后话了。

最后,简单总结一下。mr 脚本库从去年开始迭代到现在,功能越来越多,越来越方便,使用的同事也越来越多。它给同事们带来了工作效率上的提升,我是感到非常开心和有成就感的。当然我也从这一过程中学到了很多东西,比如我全栈梦想里面的服务端开发,以及软件(我是把它当做了一个没有 GUI 的软件)的设计。一开始脚本库用的是 ini 作为配置文件格式,但后来迁移到了 json,如果一开始就想到用 json 的话,就不需要写一堆迁移适配的代码了。

「磨刀不误砍柴工」,「工欲善其事,必先利其器」。把研发的效能工具做好,是真的能提高咱们的生产力。

Read more

怀念小时候吃过的食物

怀念小时候吃过的食物

前两天下班骑车回家的路上听到了路旁有人在讨论泡馍。他们口中的泡馍应该是类似西安羊肉泡馍之类的食物。但是我却想起来了小时候吃的不一样的泡馍以及其他吃食。 不一样的泡馍 小时候我们那里普遍比较贫穷,家家户户除了过年过节基本上很难吃到大块肉。小孩子饭量时小时大,中午吃的饭,半晌就又饿了。家里有大葱或者豆糁的话,可以拿着一个馍就着就吃了。整根的葱是最下馍的,葱白部分甜又辣,葱叶里面会有像鼻涕一样的粘液,要把它挤出来才下得嘴吃。豆糁是黄豆的发酵产物,煮熟的大豆加盐发酵几天,黏丝丝的时候团成球,放到发黑就能吃了。吃的时候从球上掰下来几小块就行。豆糁是咸的,因而也能下饭。不过最妙的吃法是将豆糁和鸡蛋一起炒。鸡蛋的香气和豆糁稍微发臭的味道混在一起,形成一种独特的香味。像北京的臭豆腐一样,闻着臭,吃着香。 如果家里没葱没豆糁了,馍又很干,那泡馍就是解决饿肚子的绝好办法。将干硬的馍掰成几瓣,不能太碎小,放到瓷碗里。倒入炒菜的肉味王佐料,或者是平时攒下来的方便面调料。再提溜着暖水瓶,倒进去冒着热气的水。当然香油是少不了的,拿着油光光的瓶子,滴进去几滴喷香的香油。最后用大碗盖住,或者干脆啥也不盖,静等

By Gray
Swift Server Push Notification 配置

Swift Server Push Notification 配置

获取证书 在 Apple Developer 开发者账号 Certificates, Identifiers & Profiles 里选择 Keys。新增一个 key, configure 里选择 Sandbox & Production。下载该 p8 证书,并且保存好(只能下载一次)。 终端 cd 到证书所在路径,输入下面指令。 openssl pkcs8 -nocrypt -in AuthKey_XXXXXXXXX.p8 -out ~/Downloads/key.pem cat key.pem 得到 PRIVATE KEY 字符串,复制好。 服务端配置 服务端有多种技术栈方案,包括 Java、

By Gray
香港游记——一个传统而又现代的城市

香港游记——一个传统而又现代的城市

这是 2024 年的最后一场旅行,从北京到香港,跨越了大半个中国。去香港,一方面是想领略一下它的文化和风光,另一方面是想办一个香港银行卡,买港美股以及海外收付款。 从北京到香港,动卧是一个不错的选择。乘坐 D903 次动车,晚上八点登车,睡一觉,第二天一早就到深圳北了。再从深圳北坐高铁过口岸到香港西九龙,差不多上午九点多就能到达香港。深圳北到西九龙的高铁车次非常多,不用担心买不到票。 密集的建筑 香港给我的初印象就是——这里的楼房真的很密集。不光是住宅区又高又密,商业区的建筑物与建筑物之间也几乎只有街道相隔,很少见到大型的公园或者绿化带。土地利用率很高。这一点和北京差别还是挺大的。北京虽然也是寸土寸金,但是市内绿化面积很高,大型公园也很常见。 街上密集的建筑,让人第一眼看就知道这是香港。 旧与新,传统与现代 在香港,不同地区的风格面貌会相差很多。你既能见到破旧不堪、需要修缮的古老楼房,也能见到银光闪闪、科技感十足的现代化大厦。这种新与旧的切换,传统和现代的反差,总是能给人强烈的震撼。这正是香港的魅力所在。 维多利亚港和中环摩天轮 维多利亚港是香港的中心,是香港旅游

By Gray