有个奇怪的想法,基于 Github Actions 支持代码热更新,配置网络下发的自动定时任务。

2020-10-15 10:39:29 +08:00
 Junzhou

这个想法诞生的缘由

快毕业了,因为没有出去实习,闲得慌,前两天写了一个利用 GitHub Actions 进行 Bilibili 每日投币,签到的程序BILIBILI-HELPER,详见利用 GitHub Action 定时任务实现哔哩哔哩签到,轻松获取每日 65 点经验。

重点来了 由于更新比较频繁,功能逐步增加,但是 Fork 仓库的用户用的基本上都是 Fork 的那个版本的,只有极少的用户会从源头仓库拉取最新更新的代码,以及极少的用户是删库重新 fork 这样就很繁琐。

于是在和另一个网友的讨论中,想起了Travis CI可以对仓库写入,只需要一个对用户仓库具有读写权限的Personal access tokens,然后进一步发现了使用Github Actions使用 GitHub 的机器人并不需要使用Personal access tokens就能对仓库进行写入,于是乎有了下面的自动更新脚本,每周五的 16 点 自动从源头仓库拉取最新的版本文件,更新到 Fork 仓库里。

name: auto_merge

on:
  workflow_dispatch:
  schedule:
    - cron: 0 16 * * fri
    # cron 表达式,每周五 16 点执行一次,可按照需求自定义。  

jobs:
  merge:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v2
      with:
        ref: main
        fetch-depth: 0
        lfs: true

    - name: Set git identity
      run : |
        git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
        git config --global user.name "github-actions[bot]"
    - name: Load upstream commits
      run: |
        git update-index --assume-unchanged ./src/main/resources/config.json
        git pull https://github.com/JunzhouLiu/BILIBILI-HELPER.git --log --no-commit
    - name: Apply commit changes
      run: |
        if [ -f ./.git/MERGE_MSG ]; then
        mkdir ./tmp && cp ./.git/MERGE_MSG ./tmp/message
        sed -i "1c [bot] AutoMerging: merge all upstream's changes:" ./tmp/message
        sed -i '/^\#.*/d' ./tmp/message
        git commit --file="./tmp/message"
        else
        echo "There is no merge commits."
        fi
    - name: Push Commits
      env:
        DOWNSTREAM_BRANCH: main
        TZ: Asia/Shanghai
      run: git push origin $DOWNSTREAM_BRANCH

但是问题又来了,我是使用仓库里的config.json来支持自定义功能配置的,如果采用这种方法,后续版本config.json更新或者扩充了就会导致用户仓库的 config 文件被覆盖。。。。于是乎,今早上灵光一现。。。 最终方案。

自定义配置可以从网络加载,自建一个配置服务,用户通过 UID 在网页上进行配置自定义功能,仓库只负责储存功能代码和敏感的Secrets(因为登录 B 站需要 Cookies ),当程序运行时根据用户 uid,当前版本库版本,向配置服务请求配置下发。 这样就能做到源头仓库更新代码,下游仓库自动同步代码,并且不影响配置,并且做到了前后兼容

做到这些只需要两个 Action Job,一个执行定时任务,一个定时从源头仓库拉取更新然后 Merge 。 我也只需要用很少的资源自建一个配置下发服务,然后就完成了一整套的代码热更新服务。

查了下,发现 Github Actions 有每个用户有资源限额,如果在限额内,害,这应该就不算 abuse 吧。

3047 次点击
所在节点    程序员
15 条回复
zouzou0208
2020-10-15 10:58:00 +08:00
感谢作者~
1. config 可以用 actions 解决已经有人做出来了 e.g.https://github.com/antfu/action-write-config
2. 用户不多的话资源限额是绝对够的,我大概有 5 个没小时一跑的 actions 都没问题
3. 我觉得下游自己同步代码还是用户解决比较好,如果帮忙的话有悖于 fork 的初衷了吧
Junzhou
2020-10-15 11:08:00 +08:00
@zouzou0208

1. 使用 actions 做 config 的话,用户自定义 config 的话,如果我更新源仓库,那按照自动拉取 fork 的脚本,这个 config.yml 应该也会被更新掉。 用户的自定义配置就丢失了。

2. 资源限额,定时脚本都是由 fork 的仓库自己跑的,并不是都在我的源头仓库上跑。限额应该不会超,但是这种行为,算不算滥用 我有点虚。。。

3. 我也这样认为,不过这类工具绝大部分使用者 fork 只是为了使用服务,并不会自己二次开发。可以增加个确认项,是否开启自动拉取源头仓库代码并 merge 。就有点类似于应用是否启用自动更新?

这样做也是一个折衷的办法,Cookies 比较敏感,所以没统一的在我的服务器上跑用户的定时任务,即使用户信任我把账号 cookies 交给我了,我也不敢拿啊。。万一被人拖库了。cookies 信息还是写在用户仓库的 secrets 里比较安全。
zouzou0208
2020-10-15 11:22:40 +08:00
@Junzhou 嗯啊,同意 Cookies 写在 secrets 里安全些。
不算滥用吧,参考 waka time.
warcraft1236
2020-10-15 13:46:34 +08:00
问个 actions 的问题,如果我要执行的代码是需要 mysql 的,怎么能连接到我自己的 mysql 上呢?
xrr2016
2020-10-15 16:26:27 +08:00
@warcraft1236 mysql -h xxx -P 3306 -u xxx -p xxx 哈哈
Junzhou
2020-10-15 16:30:48 +08:00
@xrr2016 #5 最好-u -p 的值写在 secrets 里 @warcraft1236
warcraft1236
2020-10-15 17:45:04 +08:00
@xrr2016 命令行?
warcraft1236
2020-10-15 17:45:48 +08:00
@Junzhou 我的代码里连数据库的代码,我发现连的 IP 不是我自己的 MySql,看起来像是 actions 给我拦截替换了
Rhilip
2020-10-15 18:54:33 +08:00
代码热更新不用这么麻烦。actions/checkout 支持对另外仓库的 checkout,所以你只需要分库就好。
一个仓库放主代码,另外一个仓库放 Action 以及相关配置( SECRET ),放 Action 的每次从主仓库 checkout 就好了。
用户可以 fork 使用 Action 的仓库,而不需要 fork 主仓库。
而你对主仓库的修改,在用户那也能得到同步更新。
Junzhou
2020-10-15 18:58:10 +08:00
@Rhilip 这样啊,那我晚上看看文档,Actions 的文档还没完整的看过。
Rhilip
2020-10-15 19:00:26 +08:00
举个我用过的例子,希望能对 lz 有启发。
https://github.com/lingsamuel/EpicGamesGiveawaysAutoClaimer

他就每次都 从另一个仓库拉取文件( refs 不写就是只拉最新的), 然后每一步都 cd 到另一个仓库的目录,在对应目录做相关 workflow 。
所以你只需要处理好你代码和用户配置的关系就好了。
Junzhou
2020-10-15 19:12:21 +08:00
@Rhilip 感谢!
axu0411
2020-10-16 12:05:44 +08:00
昨天早上逛 github 把你的库 fork 了,有一个 bot 叫 pull bot,介绍说 fork 后上游更新代码,最晚 3 个小时自动同步代码。github.com/apps/pull
Junzhou
2020-10-16 12:54:48 +08:00
@axu0411 目前已经解决自动 fork 源头仓库代码了,增加一个 actions job 。
Ecalose
2020-12-14 20:50:19 +08:00
楼主我也遇到了这个问题,能求问一下大佬你是怎么解决这个问题的吗?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/715122

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX