前言

众所周知,懒是人类进步的第一生产力
重复工作交给机器做比较方便,这样自己重复工作的时间就能做一些更有意义的事情了😈

对 GitHub Actions 还不了解的朋友可以去看阮一峰老师的文章,链接

Octokit 是 GitHub 官方推出的一套 SDK,用于调用 GitHub 的各种API,用这个东西我们可以做很多有趣的东西

  • 自动提 Issue,或者给 Issue 评论
  • Issue自动转换成 PR,可以参见 type-challenge 的做法,链接
  • 批量点Star

广告

这个项目主要是为催学社的小伙伴准备的,欢迎大家加入催学社一起来卷啊

想加入催学社的小伙伴,可以联系催学社的发起者 崔哥 @cuixiaorui, vx: cuixr1314

同时,崔哥也是 mini-vue 的作者,实现一个简化版 Vue3,来帮助大家理解 Vue3 源码,也欢迎大家给 mini-vue 点个 star

找需求

众所周知,之前大崔哥 @cuixiaorui 有一个 study-every-day 的 repo,打卡每日计划,那么,我们能不能把提交每日计划的这个过程自动化呢?
大致的需求就是:

  • 用 Markdown 写一个模板
  • 每天定时把上面的模板内容评论到当天 每日任务的 Issue
  • 如果在自动执行之前,已经评论过,就不再发送了
  • 如果没有找到这一天的 Issue,也跳过执行

这样我们就可以直接去改生成好的模板了,重复劳动减少了(虽然还是要手动去改)

当然可以!

于是就有了下面这个东西 ch3cknull/auto-issue-comment

用法

  1. fork本项目
  2. 修改 template.md 为自己适合的模板
  3. 申请一个 token
  4. 在 repo 的 SettingsSecrets 里添加新的 Secret
    1. 点击右上角 New repository secret
    2. Name 为 GH_TOKEN
    3. Value 为你申请到的 key

怎么做?

其实很简单,我们简单做一下任务拆分

  1. 从repo拿到所有的 Issue,过滤掉所有的 PR (因为PR也是特殊的Issue)
  2. 拿到当天对应的Issue
  3. 查看当天是不是已经发过了
  4. 发送模板评论

拆分任务之后,就该来具体实现了

具体实现

先熟悉一下 Octokit 的用法,在使用之前先安装一下,我推荐使用 pnpm 来管理包, 因为速度快,而且省空间

npm i -g pnpm
pnpm i octokit

简单试用一下,这里的 token 是你需要自己在 GitHub 申请的,申请 token 的流程我会放在文章的最后,需要先验证 token 才能使用下文的 API

import { Octokit } from 'octokit'

const octokit = new Octokit({ auth: '这里填写你的token' })

像我们上面所说的这些需求,比如:

  • 查看某个项目所有的Issue
  • 查看某个Issue所有的评论
  • 给指定的Issue发送评论
  • 给其他项目疯狂点Star

都是有对应的API用的

这里我们会用到以下几个API

const { listForRepo, createComment, listComments } = octokit.rest.issues
const { getAuthenticated } = octokit.rest.users

这几个API能用来

  • 列出指定 repo 的所有 Issue
  • 在指定的 Issue 添加一条评论,这是我们需要的主要功能
  • 列出指定 Issue 所有的评论
  • 获取当前登陆用户的信息,这里用来和评论匹配,确定之前有没有在这个Issue发过言

那么,开搞!

本地的话,可以先小步快跑,把token硬编码在里面,等实现功能之后我们再考虑重构

大概就是下面这个思路

  1. 先用 listForRepo 根据指定的 owner 和 repo 信息
  2. 根据每日计划Issue的标题格式,筛选出当天需要评论的 Issue(但是如果用 Issue 的创建时间应该更合理?设计之初没有想到这点)
  3. listComments 查看这个 Issue 的所有评论
  4. 判断今天是否评论过(用 getAuthenticated 获取登陆者的用户名来和所有评论匹配)
  5. 如果没有评论过,就发送评论(用 fs 读取模板 md,然后用 createComment 发送 )

和 GitHub Actions 结合

和 GitHub Actions 结合是需要做一些改动的,就比如 token 不能暴露在外,肯定不能硬编码在代码中(但我还是犯了这种错误,只需要重置一下,让旧 token 失效就行了),当然,GitHub也提供了这种存放秘密值的地方,配置的话,可以参见上面的用法。

我们需要做的改变是,从环境变量中读取 token,这里我们指定的环境变量名是 GH_TOKEN,这样我们就能在代码中直接使用这个环境变量了。

const { GH_TOKEN } = process.env

另外,配置执行的 yml 也是一件比较麻烦的事(我常常因为自己不会配置和大佬格格不入)

按理来说,作为 node 应用,可以直接在官方示例上做修改就行了,但是配置过程还是充满坎坷的,不是漏了分号就是缩进错误,由于 GitHub 提供的机器时区和我们不同,需要额外修改一下,这里可以参考项目的README

这里的 push 是我为了方便观察有没有成功运行才加的,正常情况只保留下面的 schedule 就行了

name: auto add template comment to cuixiaorui/study-every-day issue

on:
  push:
    branches:
      - master
  schedule:
      - cron: '30 0 * * *'

jobs:
  add-comment:
    runs-on: ubuntu-latest
    env:
      GH_TOKEN: ${{ secrets.GH_TOKEN }}
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v2
        with:
          node-version: '14'
      - run: npm install
      - run: tsc
      - run: node dist/index.js

至此,终于完成了,欢迎大家 fork 和 star

附录

申请 GitHub 的 token

  1. 打开你的 GitHub 的 Setting 的 Personal access tokens,点击这里快速跳转

  2. 点击右上角 generate new token

  3. 填写 token 的名称,然后选择 token 对应的权限

  4. 点击确定,并且复制 token

    需要注意的是,如果没复制,退出去就看不到当前 token 了,只能重置
    重置的时候,之前的 token 会失效,使用之前 token 的应用需要配置新 token