• 请不要在回答技术问题时复制粘贴 AI 生成的内容
Junzhou
V2EX  ›  程序员

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

  •  
  •   Junzhou · Oct 15, 2020 · 4468 views
    This topic created in 2214 days ago, the information mentioned may be changed or developed.

    这个想法诞生的缘由

    快毕业了,因为没有出去实习,闲得慌,前两天写了一个利用 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 replies  •  2020-12-14 20:50:19 +08:00
    zouzou0208
    zouzou0208
    Oct 15, 2020
    1
    感谢作者~
    1. config 可以用 actions 解决已经有人做出来了 e.g.https://github.com/antfu/action-write-config
    2. 用户不多的话资源限额是绝对够的,我大概有 5 个没小时一跑的 actions 都没问题
    3. 我觉得下游自己同步代码还是用户解决比较好,如果帮忙的话有悖于 fork 的初衷了吧
    Junzhou
    Junzhou
    OP
    Oct 15, 2020
    2
    @zouzou0208

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

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

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

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

    他就每次都 从另一个仓库拉取文件( refs 不写就是只拉最新的), 然后每一步都 cd 到另一个仓库的目录,在对应目录做相关 workflow 。
    所以你只需要处理好你代码和用户配置的关系就好了。
    Junzhou
    Junzhou
    OP
    Oct 15, 2020
    12
    @Rhilip 感谢!
    axu0411
    axu0411
    Oct 16, 2020 via Android
    13
    昨天早上逛 github 把你的库 fork 了,有一个 bot 叫 pull bot,介绍说 fork 后上游更新代码,最晚 3 个小时自动同步代码。github.com/apps/pull
    Junzhou
    Junzhou
    OP
    Oct 16, 2020
    14
    @axu0411 目前已经解决自动 fork 源头仓库代码了,增加一个 actions job 。
    Ecalose
    Ecalose
    Dec 14, 2020 via iPad
    15
    楼主我也遇到了这个问题,能求问一下大佬你是怎么解决这个问题的吗?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1730 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 12:29 · PVG 20:29 · LAX 04:29 · JFK 07:29
    ♥ Do have faith in what you're doing.