Gitalk批量及自动初始化

前面聊到我在blog的repo内做了Gitalk的适配,然后也有离线的脚本做了一次将近七百篇文章的批量初始化的动作,原本是打算不再去做自动初始化的Action内容了,但是出于对Github Action本身的兴趣,我还是打算把这段时间的一些零零碎碎的工作整理下,因为这里有些步骤的内容,可能的确并不好找,即使是本来并非使用Gitalk而只是和我一样刚接触Github Action的人也可以有所参考。

内容就逐步更新吧—— 顺便,这是也是第一次正好测试自动初始化功能的文章,刚才从结果看,一切正常

关于Gitalk安装使用与配置

以下部分引用自Gitalk的Github页面

Gitalk 是一个基于 GitHub Issue 和 Preact 开发的评论插件。

Gitalk特性

  • 使用 GitHub 登录
  • 支持多语言 [en, zh-CN, zh-TW, es-ES, fr, ru, de, pl, ko, fa, ja]
  • 支持个人或组织
  • 无干扰模式(设置 distractionFreeMode 为 true 开启)
  • 快捷键提交评论 (cmd/ctrl + enter)

Readme || 在线示例

Github上作者已经有了很不错的文档描述,只需要按部就班的按照Install的指示执行,如果说哪里还有稍微可以说得更清楚的地方,那就是在Gitalk配置中js部分提到的repo是指用来放置issue/评论的repo而不是blog本身所在的repo;而admin部分就是指定有资格初始化评论的github用户名——初始化的方法很简单,只需要具备权限的用户打开某一篇文章,那么就会自动刷新建立评论对应的issue。

换言之,如果作者写完文章推送之后并没主动访问编译后的文章页面,而其他人先访问,就会看到说评论issue不存在,请联系@xxx之类的错误提示;这也是为什么很多人觉得Gitalk不方便的原因。

对于新建文章问题可能还不大,但是对于如果有大量存量文章想转移到Gitalk的人,就不太友好了。

但是,作者也解释了,这么做有着安全上的考虑,即,假如任何人都能触发新建评论(即对应issue),那么理论上issue也能被随意删除和篡改;有些其他的方案通过一个第三方的server来实现集中化的管理(比如,可授权的Github App),这个思路就很可取,其实和我下面做的Action本质上是一样的,那就是托管Admin的token来实现issue的自动化初始和安全并存。

我把相应的脚本和内容整理到了GitHub并将在下面做一点展开解释。

本地执行批量初始评论区

我在自己的Blog的Github Readme里简单提了一下,不过仔细想想,如果要实际操作,可能有些相关的信息还是要展开一下。而以下说明是以Github Page搭建的Jekyll Blog为例来说明的,而且,有如下假设,以方便理解和需要的定制:

  1. Jekyll 本身文章都是放置在_posts内的md文件;
  2. 文章的文件名是以YYYY-MM-DD-POSTNAME.md组织的;
  3. 文章内部关键tag必须在前30行有title:XXXXX

这个需求主要是针对的如果用户有大批量的存量文章,目前希望迁移到Gitalk的评论系统,可能涉及到成百上千的数量,所以从出发点上,就不以Github Action为出发点,重点考虑在本机做一次性的批量处理(当然,理论上,也可以在Github Action侧做,不过没有测试过,而且考虑到特别大数据的情况下,甚至可能超出Action的执行时长限制)

步骤如下:

  1. 将自己的github page克隆到本地;
  2. 配置python环境,确保requests 包安装;
  3. 在blog的根目录下,复制config.ini.template 到config.ini并且做相应修改,尤其是修改为自己有效的个人token值;(注意,务必确保config.ini 文件不要纳入repo,以避免token泄露失效)
  4. 根目录下,执行python autoissue.py scanAllPosts,就可以等待完成了(Github的issue的限制是1小时内不能超过5000次访问,所以,假如万一真的超了,可能要稍微等待到期)

然后,有几个重点需要关注(针对不同的blog设置),可能需要一些代码修改适配而不是仅仅配置修改来实现:

  • 如果是文章文件名和上面的假设2不符合, 那么请修改parseFile中lre = re.match(r".*/\d+-\d+-\d+-(.*)\.md",filepath)这一部分;
  • Issue的label我是按照Gitalk的某缺省配置设置的做法用url(relative)作为label,而且因为在Jekyll配置中,也是依靠文件名来分解的,这部分的定制也是在parseFile函数中,可以参考link、label等的匹配语句进行修改。

Github Action自动为新文章初始化Gitalk评论

虽然我说过对于单独新增的文章,初始化本来不应当成为问题,但是到底是顺手的事情,所以,我就把Github Action的部分也做好了,后面每次如果发生post的变化就会自动触发编译以及单独的trigger评论初始化的动作:

Workflow Example

为了方便特意把脚本和文件整理了下放到了GitalAutoAction 这个repo下面。

当然首先要有Github Action的基本知识,这里不妨参考官方文档

然后还有一个前提是,最好是把前面的本地脚本已经测试过没有问题之后,再来尝试Action,因为毕竟调试起Action是靠反复的提交,效率是很低的。

  1. 首先确认在对应的repo(blog所在的repo)的setting中正确的设置了Secret的Token,通过这种方法就可以避免在public的库中明文存储的隐私信息,而脚本在action中执行过程中就是靠调用存储在Secret中的Token值来认证的,具体文档可以参考How to use GitHub Actions secrets to hide your tokens and passwords 以及Github的官方文档;
  2. 把GitalAutoAction中的的文件都复制放置在希望实现自动评论的blog的repo根目录下(保持一样的目录结构)

注意:这里仅仅监控了_posts下的文件变化,如果如前面提到的假如放置目录有变化,那么需要调整对应的条件:

2 on:
3   push:
4     paths:
5       - '_posts/**.md'

另外,有个豆知识,假如想在action中侦测到某次push当中涉及到修改的所有的文件,那么就不能依靠某一次commit,我看到网上众说纷纭,但是和Action本身特性结合起来,其实原理上就是利用某次action before和after之间的git diff-tree来找到修改过的文件 - Ref Link - ,如下

13     - uses: actions/checkout@v3
14       with:
15           fetch-depth: 0
16     - run: echo "$(git diff --name-only --no-commit-id -r $\{\{ github.event.before \}\}..$\{\{ github.event.after \}\})" | tee chglist

然后,在同一个job中,输入输出可以依靠文件,例如上文中的chglist,不过我理解该文件应该是沙盒环境下的临时存在而已。

然后,之后,每次当有post中的文件发生变化之后,github Action就会自动检查对应修改过的文章是否有对应的评论issue存在,如果没有就会自动创建issue。

25 Apr 2022 , 写毕。