V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Junzhou
V2EX  ›  程序员

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

  •  
  •   Junzhou · 2020-10-15 10:39:29 +08:00 · 3016 次点击
    这是一个创建于 1261 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这个想法诞生的缘由

    快毕业了,因为没有出去实习,闲得慌,前两天写了一个利用 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 吧。

    15 条回复    2020-12-14 20:50:19 +08:00
    zouzou0208
        1
    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
        2
    Junzhou  
    OP
       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
        3
    zouzou0208  
       2020-10-15 11:22:40 +08:00
    @Junzhou 嗯啊,同意 Cookies 写在 secrets 里安全些。
    不算滥用吧,参考 waka time.
    warcraft1236
        4
    warcraft1236  
       2020-10-15 13:46:34 +08:00
    问个 actions 的问题,如果我要执行的代码是需要 mysql 的,怎么能连接到我自己的 mysql 上呢?
    xrr2016
        5
    xrr2016  
       2020-10-15 16:26:27 +08:00
    @warcraft1236 mysql -h xxx -P 3306 -u xxx -p xxx 哈哈
    Junzhou
        6
    Junzhou  
    OP
       2020-10-15 16:30:48 +08:00 via iPhone
    @xrr2016 #5 最好-u -p 的值写在 secrets 里 @warcraft1236
    warcraft1236
        7
    warcraft1236  
       2020-10-15 17:45:04 +08:00
    @xrr2016 命令行?
    warcraft1236
        8
    warcraft1236  
       2020-10-15 17:45:48 +08:00
    @Junzhou 我的代码里连数据库的代码,我发现连的 IP 不是我自己的 MySql,看起来像是 actions 给我拦截替换了
    Rhilip
        9
    Rhilip  
       2020-10-15 18:54:33 +08:00
    代码热更新不用这么麻烦。actions/checkout 支持对另外仓库的 checkout,所以你只需要分库就好。
    一个仓库放主代码,另外一个仓库放 Action 以及相关配置( SECRET ),放 Action 的每次从主仓库 checkout 就好了。
    用户可以 fork 使用 Action 的仓库,而不需要 fork 主仓库。
    而你对主仓库的修改,在用户那也能得到同步更新。
    Junzhou
        10
    Junzhou  
    OP
       2020-10-15 18:58:10 +08:00
    @Rhilip 这样啊,那我晚上看看文档,Actions 的文档还没完整的看过。
    Rhilip
        11
    Rhilip  
       2020-10-15 19:00:26 +08:00   ❤️ 1
    举个我用过的例子,希望能对 lz 有启发。
    https://github.com/lingsamuel/EpicGamesGiveawaysAutoClaimer

    他就每次都 从另一个仓库拉取文件( refs 不写就是只拉最新的), 然后每一步都 cd 到另一个仓库的目录,在对应目录做相关 workflow 。
    所以你只需要处理好你代码和用户配置的关系就好了。
    Junzhou
        12
    Junzhou  
    OP
       2020-10-15 19:12:21 +08:00
    @Rhilip 感谢!
    axu0411
        13
    axu0411  
       2020-10-16 12:05:44 +08:00 via Android
    昨天早上逛 github 把你的库 fork 了,有一个 bot 叫 pull bot,介绍说 fork 后上游更新代码,最晚 3 个小时自动同步代码。github.com/apps/pull
    Junzhou
        14
    Junzhou  
    OP
       2020-10-16 12:54:48 +08:00
    @axu0411 目前已经解决自动 fork 源头仓库代码了,增加一个 actions job 。
    Ecalose
        15
    Ecalose  
       2020-12-14 20:50:19 +08:00 via iPad
    楼主我也遇到了这个问题,能求问一下大佬你是怎么解决这个问题的吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2749 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 52ms · UTC 12:47 · PVG 20:47 · LAX 05:47 · JFK 08:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.