如何让github机器人自动帮你发消息
why
为什么要做、背景
最近给umi写一个机器人,用于邀请新人进 umi contributor 群,希望有更多人来参与建设。umi是个react开箱即用的开源解决方案,详情可以看官网。 PR详情看:ci: PullRequest Checker by txp1035 · Pull Request #10319 · umijs/umi · GitHub
what
解决方案是什么样子,做好后达成什么效果
- 非 doc pr 被合并时,发个消息
感谢 PR。如果有兴趣一起参与维护 Umi,可先用钉钉扫下方二维码(注明 github id)加我钉钉,然后我会拉到群里。+图片
- 如果已经在群里或者有仓库write权限的同学就不发送消息了
how
怎么实现的
主要是通过gitHub action来实现的。 不了解gitHub action的朋友可以看GitHub Actions 入门教程 - 阮一峰的网络日志
文件放在项目里的.github/workflows
分析条件
非 doc pr 被合并时
这里拆分成两个条件来解决
- 非 doc 提交。在umi中,文档的变更都是在
docs/**
里的,所以用户只改动这个文件夹里的文件忽略执行action就行了。当然也可以去判断pr的标题是不是doc:
来过滤。如果你知道欢迎评论~👏🏻 - 被合并的时候。就是在pr关闭时,判断这个pr是不是被合并的状态。前者在on做判断,后者在jobs做判断。
发个消息 `感谢 PR
这里用到了一个第三方action,actions-cool/maintain-one-comment@v3。就用用来发送消息的,配置这个需要打开设置,给机器人权限,否则会报错。
判断条件不发送消息
不发送消息有两个情况:
- 在钉钉群里的同学不发送消息
- 有仓库write权限的同学不发送消息
先解第一个问题,方案是维护一个数组json文件,文件里维护群里同学的github id。然后判断提交者是否在这个数组里面,在就不发送消息。这里通过juliangruber/read-file-action@v1读取文件、contains方法来判断提交者(github.actor)是否在这个数组(fromJSON(needs.read-file.outputs.require-result))里面。
再解第二个问题,这里直接通过actions-cool/check-user-permission@v2库就能知道用户是不是有权限。
具体源码如下:
name: PullRequest Checker # 名字,随便取,符合你自动化的主题就行
on: # 满足什么条件触发
pull_request_target: # pr关闭的时候
types: # pr关闭的时候
- closed # pr关闭的时候
paths-ignore: # docs下目录内容变更忽略
- 'docs/**' # docs下目录内容变更忽略
jobs:
read-file: # 名字,随便取,符合你自动化的主题就行
runs-on: ubuntu-latest # 在什么平台运行
outputs: # 选项
require-result: ${{ steps.contributors.outputs.content}} # 导出参数
steps: # 执行什么事情
- name: Checkout # 名字,随便取,符合你自动化的主题就行
uses: actions/checkout@v1 # 检查库,否则读取不到文件
- name: Read contributors.json # 名字,随便取,符合你自动化的主题就行
id: contributors # 文件导出的字符串存储的变量
uses: juliangruber/read-file-action@v1 # 读取文件插件
with:
path: ./contributors.json # 路径参数
check-permission: # 名字,随便取,符合你自动化的主题就行
runs-on: ubuntu-latest # 在什么平台运行
outputs: # 选项
require-result: ${{ steps.checkUser.outputs.require-result }} # 导出参数
steps: # 执行什么事情
- uses: actions-cool/check-user-permission@v2 # 权限插件获取用户插件
id: checkUser
with:
require: 'write'
check_merged: # 名字,随便取,符合你自动化的主题就行
runs-on: ubuntu-latest # 在什么平台运行
needs: [read-file, check-permission] # 导入参数
if: needs.check-permission.outputs.require-result == 'false' && contains(fromJSON(needs.read-file.outputs.require-result), github.actor) == false && github.event.pull_request.merged == true # 发送消息需要满足的条件
steps: # 执行什么事情
- uses: actions-cool/maintain-one-comment@v3 # 发评论插件
with:
body: 感谢 PR。如果有兴趣一起参与维护 Umi,可先用钉钉扫下方二维码(注明 github id)加我钉钉,然后我会拉到群里。<img src="https://img.alicdn.com/imgextra/i2/O1CN01DLiPrU1WsbDdnwRr9_!!6000000002844-2-tps-340-336.png" width="20%"/>
后记
github action我也不常用,所以记录一下踩坑和解决方式。
踩坑
- 别人action写readme的不一定适合新手, 如果按照action的README文档使用执行失败可以到仓库里找找例子,也许它还依赖其他的action。而且直接看仓库例子也更直观,例子在
.github
文件夹下面。 - 调试:因为我这个需求是做pr关闭来的,我自建了个仓库一直通过建立pr的方式进行调试,快完成的时候反应过来了,通过push触发action更快~I'm so stupid.
解决方式和技巧
- 推荐在官方文档查api,输入对应关键词。
- 如果api都懒到不想看,可以试试谷歌。主要原因是文档不能针对action进行查询有点不友好。
- 如果功能复杂可以先试试看action社区里搜索下。
- . 因为action日志输出对象是个object,所以想知道里面是什么可以通过toJSON这个方法来转成字符串,不过这个方法也可能失灵,比如打印gihub这个上下文,具体原因还没有查,我猜里面有无法序列化的东西。我想到的只能是看api,有知道怎么能打印出来的的大佬可以告诉我~thanks
闪念
经常做需求就会给自己挖坑,脑子会蹦出一些好玩的想法。比如做这个机器人,我就想可不可以定时基于钉钉群人员名字自动更新github共建者列表,或者通过可以@机器人添加。这个单纯是好玩的想法ROI有点低哈哈😄。
最后
祝大家元宵节快乐。欢迎使用umi,如果你使用过程中遇到问题可以提issue,也欢迎提pr解决。
参考
转载自:https://juejin.cn/post/7196321890301902906