需求, calcit-runner 目前提供了一个 cr_once 命令用来跑 CI 脚本.
原始的 cr 命令存在对 SDL2 和 fswatch 的依赖, 这个场景并不方便.
所以 cr_once 这个命令是专门编译提供的, 托管在 http://bin.calcit-lang.org/li... .

其他的项目运行 GitHub Actions 跑测试时, 就需要使用 cr_once 来执行.
思路上讲, 就是要把这个命令加载到容器当中, 然后给与可执行权限.
然后, 项目本身会有依赖, 就需要下载依赖, 存放到指定的位置.

目前 calcit 相关项目, 依赖的管理方式只是指定路径加载文件, 所以直接用 git clone 就可以了.

按说理想的完善方案是 cr 命令本身不要依赖奇怪的东西, 直接能在 CI 运行,
然后通过扩展模块的方案, 也就是动态加载动态链接库或者其他模块引入扩展功能, 比如 SDL2,
其次模块管理也内置一个命令来做, 自动下载, 自动维护依赖关系....
目前 calcit 功能残缺, 这些只好先不管了.

回到 GitHub Actions, 就需要加载二进制文件到容器, 我尝试了两个方案,

Dockerfile 方案(最终未采用)

首先, GitHub 是支持在 Actions 里边使用容器的,
https://docs.github.com/en/fr...
按照教程, 我写 Dockerfile 打包一个容器, 这个容器内部包含 cr_once.
调试完成一些报错, 我也能在容器里正常运行起来了.

但是这个方案让我了解到 GitHub Actions 这个环境的一些限制,
或者说 docker 容器本身的限制, Dockerfile 里边定义的命令是在容器内部跑的.
然后容器运行完成, 对外部没有影响(具体不知道怎么配才能暴露能力).
于是我在项目里尝试 git clone, 那个容器内部算是能访问到,
但是那个容器内部 git clone, 容器运行结束, 外部就访问不到了.
这样也就是说, 最终运行是容器内部的, 我在外部就比较难做各种配置了. 逻辑就不自然.

setup 方案

然后我去看一眼别的编程语言怎么做的, 比如 Nim 也是二进制执行文件:
https://github.com/jiro4989/s...
大致思路是用 Node.js 脚本形式的 Action, 下载安装 Nim, 从而得到一个环境.
看了一下 nodejs 的思路, 也是这样的, 直接下载到当前环境当中安装.

然后我转变思路也改过来, 最终得到这样一个脚本:
https://github.com/calcit-lan...

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1
    - name: wget
      run: mkdir ci-bin/ && wget -O ci-bin/cr_once http://repo.calcit-lang.org/binaries/linux/cr_once
    - name: "permission"
      run: chmod +x ci-bin/cr_once

    - name: "prepare modules"
      run: mkdir -p ~/.config/calcit/modules/ && cd ~/.config/calcit/modules/ && echo 'no deps'

    - name: "test"
      run: env=ci ./ci-bin/cr_once

这个步骤是:

  • 通过 wget 下载 cr_once 的可执行文件, 对应 Linux 环境的,
  • 创建 calcit-runner 使用的模块目录, 然后有依赖模块的话, 直接 clone 代码进去,
  • 运行可执行文件, 按照需要加上一个 env=ci 的环境变量加以区分.

最终运行也是成功了, 而且比较方便按照需要改写定制. 满足目前的需要.

其他

我尝试的时候, Docker 使用 Ubuntu 默认系统是什么都没有的,
GitHub 提供的容器倒是方便, git, wget 这些命令都在里边了, 就比较省事了.
从原理上说, 安装 cr_once 这一步可以抽出来写成一个 Action,
那样使用的实在会方便很多, 而且方便后续升级, 只要升版本号就好了.
暂时先这样.


题叶
17.3k 声望2.6k 粉丝

Calcit 语言作者