likes
comments
collection
share

如何让github机器人自动帮你发消息

作者站长头像
站长
· 阅读数 12

why

为什么要做、背景

最近给umi写一个机器人,用于邀请新人进 umi contributor 群,希望有更多人来参与建设。umi是个react开箱即用的开源解决方案,详情可以看官网。 PR详情看:ci: PullRequest Checker by txp1035 · Pull Request #10319 · umijs/umi · GitHub

what

解决方案是什么样子,做好后达成什么效果

  1. 非 doc pr 被合并时,发个消息 感谢 PR。如果有兴趣一起参与维护 Umi,可先用钉钉扫下方二维码(注明 github id)加我钉钉,然后我会拉到群里。+图片
  2. 如果已经在群里或者有仓库write权限的同学就不发送消息了

how

怎么实现的

主要是通过gitHub action来实现的。 不了解gitHub action的朋友可以看GitHub Actions 入门教程 - 阮一峰的网络日志

文件放在项目里的.github/workflows

分析条件

非 doc pr 被合并时

这里拆分成两个条件来解决

  1. 非 doc 提交。在umi中,文档的变更都是在docs/**里的,所以用户只改动这个文件夹里的文件忽略执行action就行了。当然也可以去判断pr的标题是不是doc: 来过滤。如果你知道欢迎评论~👏🏻
  2. 被合并的时候。就是在pr关闭时,判断这个pr是不是被合并的状态。前者在on做判断,后者在jobs做判断。

发个消息 `感谢 PR

这里用到了一个第三方action,actions-cool/maintain-one-comment@v3。就用用来发送消息的,配置这个需要打开设置,给机器人权限,否则会报错。

如何让github机器人自动帮你发消息

判断条件不发送消息

不发送消息有两个情况:

  1. 在钉钉群里的同学不发送消息
  2. 有仓库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我也不常用,所以记录一下踩坑和解决方式。

踩坑

  1. 别人action写readme的不一定适合新手, 如果按照action的README文档使用执行失败可以到仓库里找找例子,也许它还依赖其他的action。而且直接看仓库例子也更直观,例子在.github文件夹下面。
  2. 调试:因为我这个需求是做pr关闭来的,我自建了个仓库一直通过建立pr的方式进行调试,快完成的时候反应过来了,通过push触发action更快~I'm so stupid.

如何让github机器人自动帮你发消息

解决方式和技巧

  1. 推荐在官方文档查api,输入对应关键词。
  2. 如果api都懒到不想看,可以试试谷歌。主要原因是文档不能针对action进行查询有点不友好。
  3. 如果功能复杂可以先试试看action社区里搜索下。
  4. . 因为action日志输出对象是个object,所以想知道里面是什么可以通过toJSON这个方法来转成字符串,不过这个方法也可能失灵,比如打印gihub这个上下文,具体原因还没有查,我猜里面有无法序列化的东西。我想到的只能是看api,有知道怎么能打印出来的的大佬可以告诉我~thanks

如何让github机器人自动帮你发消息

闪念

经常做需求就会给自己挖坑,脑子会蹦出一些好玩的想法。比如做这个机器人,我就想可不可以定时基于钉钉群人员名字自动更新github共建者列表,或者通过可以@机器人添加。这个单纯是好玩的想法ROI有点低哈哈😄。

最后

祝大家元宵节快乐。欢迎使用umi,如果你使用过程中遇到问题可以提issue,也欢迎提pr解决。

参考

表达式 - GitHub Docs docs.github.com/en/actions/…