简介
GitHub Actions是Github提供的一个自动化CI/CD工具,非常强大且易用,这里有一份入门教程可以学习。其本质上相当于GitHub提供一个虚拟机环境,可以在特定条件下触发,执行一些脚本命令等。
在明日方舟工具箱中,有人推荐使用这一功能来执行自动编译、自动部署,并帮助实现了一份on push
(即推送时触发)的workflow,可以在每次原repo更新后,自动执行Node CLI安装依赖等,并推送到GitHub Pages和Coding Pages服务上,详细配置见这里。
工具箱中有部分数据信息依赖拆包数据,因此一开始需要在拆包数据的Repo更新后,手动同步更新并推送。但这样有个问题:如果当时我在忙,忘记更新,就会导致数据的延迟更新。既然GitHub为我们提供了Actions这样一份便利的功能,其实也可以让它来执行自动检查。
初步尝试
最初,考虑到数据Repo和代码Repo同在GitHub上,有没有可能通过内部的WebHook等方式实现。Actions为外部事件提供了repository_dispatch
的Trigger,即“当接收到POST请求时触发”。
该方法看上去可行,但在尝试时发现,这要求数据Repo在更新完后(使用该Repo内的Actions Workflow)向我发送一个POST请求,然而我并没有数据Repo的管理权限,因而使用这一方法还需要外部服务器支援,故而可行性不高,尝试其它办法。
最终方案
最后考虑到数据更新频率并不快(约每个月一次更新),而且对时效性要求并不是特别高(当天内更新即可),因此使用on schedule
选择每日定点执行。
Actions使用POSIX Cron语法,可以使用crontab guru生成。要注意Actions使用的是UTC时间,也就是说每日0:00对应的是北京时间8:00。例如下面的时间配置,表示每日(北京时间)8:00和20:00自动执行:
on:
schedule:
- cron: '0 0/12 * * *'
其次是监控数据更新的方式。我们本质上是要监控数据Repo的最新commit的版本号,这可以通过Feed或者API的方式。其实这两者没有本质区别,只是Feed使用的是XML,而API使用JSON,后者更简洁一些。
检测更新的步骤其实很简单:
\1. 使用如下命令在Repo的根目录下创建version/data文件,获取到commit信息里最新的含有"CN UPDATE"的一行并保存。grep -m1
表示只取第一行数据,> version/data
用于直接覆盖掉原文件。
curl -sL https://api.github.com/repos/Kengxxiao/ArknightsGameData/commits |grep -m1 "CN UPDATE" > version/data
\2. 将该文件添加到Git Repo中;
\3. 在每次定时任务执行时,再次执行1.中的命令,使用git status --porcelain
检查是否与之前的存储不同,不同则代表有更新,则下载新数据,执行脚本,并推送。git status --porcelain
在没有差异时输出为空,因而若没有更新则直接跳过。
if [[`git status --porcelain`]]; then
# Do something
fi
\4. 由于Repo已经设置好了on push
的Trigger,因此推送完成后,会自动触发编译、更新Pages等过程,这样就完成了数据的自动更新。
8 条评论
文末内容都删除了,博主方便贴一下吗
> 完整的配置文件可以参考:这里
仓库移动导致链接失效了。[新链接](https://raw.githubusercontent.com/gneko/aktools-closed/master/.github-ignored/workflows/autoupdate.yml)
前面也有人说过用ifttt来触发,我也是看到了这个回复才确定了自己一个项目更新的方法用上游项目的rss更新来触发ifttt→github webhook→触发github action更新自己的项目。为了实现这个也有很多坑:
1,ifttt更新频率不确定,理论上是15分钟?实际半小时延迟也遇见过。由于这个我一直想找ifttt的替代者,也试了integromat 还有 microsoft flow。前者能准确定时运行,但免费计划限制运行次数,算了一下也就能每小时运行一次,实际还不如ifttt;后者的rss更新时间也不确定,当然也可以用定时任务触发,不过最重要的“发送网络请求”动作还是需要高级版付费计划…
2,最坑爹的地方,给github webhook发送请求需要带有token和user-agent,文档中要求是加在请求的header里,然而ifttt不支持自定义请求头……于是我就想到用cloudflare worker,在收到请求后,可以运行js代码,利用这个可以修改请求(添加请求头,修改请求体)并且将请求代发给github…
这里就得表扬integromat和Microsoft flow都可以对请求做自定义…
实现的具体细节见https://github.com/zhongfly/now-subconverter/wiki
IFTTT对更新频繁的源是15分钟,更新不频繁的是30分钟。
追求实时性的话,如果你对上游Repo有修改权限,可以考虑直接添加一个推送消息的Action,这样就几乎是实时的了。
或者可以使用一些(大陆以外)的云主机,每分钟更新RSS,当然这就是另外一个话题了。
要是我有权限的话,就不会用这种麻烦的办法了,不知道之后github action能否加上其他repo更新的触发条件,感觉这种需求还是有一些的
不依赖自己的服务器通过 WebHook 触发是可行的,有一个叫 IFTTT 的免费的第三方服务,我相信你应该多少有听说过
IFTTT 可以提供 RSS Feed -> WebHook 的服务,而 GitHub 恰好有 commit 的 RSS Feed
https://github.com/Kengxxiao/ArknightsGameData/commits.atom
而我自己因为做了多服支持,所以其他服的解包更新我也会监听,由于可能短时间内有多个 commit,为了不频繁构建,我没有选用 WebHook 方式,而是绕了点弯用 IFTTT 创建 issue,然后用 Actions 定时检测 issue 来启动更新流程
blog服务器迁到国内后,忘记改评论提醒邮件的发件人了,用的gmail发不出来,现在才看到,抱歉(っ °Д °;)っ
ifttt当然是知道的,但其实你这样还是绕了一圈,检测rss更新可以在ghactions里完成,不需要绕到ifttt上,方法很简单,文中有描述。
而且ifttt的rss检测频率是无法控制的,最低为15min,在一些极端场景下不太适用 (当然ghactions有总时长限制,也做不到这么极端的频率,不过有cron格式自由度会高很多)∠( ᐛ 」∠)_
嘛,主要是如果为了检测 feed 更新而设置成间隔非常短的 cron 来执行 actions 的话总觉得有点太麻烦 github 了 而且还要自己记录最新 commit 来比对
15 min 的延迟是可以接受的,我选择这么做主要是很无脑,检测 issue 的 actions 也是现成的,不需要自己写记录那一套逻辑