用 TypeScript 编写 CI/CD Pipelines
相信大家平时或多或少接触过 CI/CD Pipelines。GitHub 有 GitHub Actions,GitLab 有 GitLab CI/CD,它们都鼓励使用 YAML 来做配置。
但是我自己平时都是用 TypeScript 来开发,感觉 YAML 实在不顺手,网上也不只我一个抱怨这个问题,比如 noyaml、The yaml document from hell。那有没有人像我一样,想要一个用 TypeScript 来做配置的 CI/CD Pipelines 呢?有的,那就是今天的主角——cicada。
什么是 cicada
cicada
是蝉的意思。官网上它是这样介绍自己的。
Cicada is a modern CI/CD engine that lets you write your pipelines in TypeScript. No more YAML-hell. Write your automations in a real programming language.
Cicada is perfect for JS/TS engineers who want to write CI in the same language as their application and for DevOps/Infra engineers looking to leverage more powerful tools & abstractions.
简单翻译一下:
Cicada 是一个现代 CI/CD 引擎,可以让你使用 TypeScript 编写管道。不再有 YAML 地狱。用真正的编程语言编写你的自动化。
Cicada 非常适合想要用与应用程序相同的语言编写 CI 的 JS/TS 工程师,以及希望利用更强大的工具和抽象的 DevOps/Infra 工程师。
看这个介绍,非常适合我这种 JS/TS 切图崽啊!IDE 支持,能共享代码,能抽象封装,还能用 NPM 包。
但我还是没有冲动,万一收钱呢?幸好,个人免费,每月 1000 分钟,够用了。我二话不说就开始了试水。
试水
官网右上角可以选择 LOG IN 或者 SIGN UP,但貌似都是一样的,会跳到 GitHub 让你登录。
登录后,只显示了我的个人仓库,没有显示组织仓库。
在这里,我选择使用 unocss-preset-element-plus 仓库来做尝试。
我在仓库内执行命令 pnpx @cicadahq/cicada init
做初始化,然后顺着提示完成了设置。中途会询问我是否安装 VS Code 的自动完成提示,如果选是会自动安装 deno
插件并设置 .vscode/settings.json
,可以说是相当友好了。值得注意的是,如果像我一样是新安装插件,需要自己安装一下 deno
并重启一下 VS Code。
什么是 deno
deno 是一个主打安全和简单的 JS/TS 运行时。你可以在 官网 了解更多。
我这里选择的模板是 Node
,名字叫 ci
,所以为我生成了 .cicada/ci.ts
这个文件。
模板比较简单,可以看到它是直接从 URL 中导入模块的。比较尴尬的是,我需要手动缓存一下,否则会提示 Uncached or missing remote URL: "https://deno.land/x/[email protected]/mod.ts"
,而且不会有 TS 类型提示。我使用 deno info https://deno.land/x/[email protected]/mod.ts
做了缓存,你也可以在 这里 查看更多缓存说明。
模板主要用到了 Job
和 Pipeline
,其中 new Job
所生成的实例对应 GitHub Actions 下 Jobs 的某一项,new Pipeline
所生成的实例对应 GitHub Actions 配置文件。这里不再赘述相关内容。
接下来自然是要把模板改造成实际可用的 Pipeline 了。这里我打算把它改造成仓库里负责检查和测试的 GitHub Action,以下就是这个 GitHub Action 的内容。
可以看到这个 GitHub Action 还是比较简单的。它会在 main
分支收到推送或者 PR 时触发做三项 Job,第一个是 lint
,本质上就是配置环境后跑 pnpm run lint
,其余两个分别是 typecheck
和 test
,和第一个类似,配置环境后分别跑 pnpm run check:types
和 pnpm run test
。
我们首先来实现 lint
相关的 Job。
我们指定 image
为 node:18-alpine
,表示在 node 18
上运行 Job。
如果你使用过 Docker,那一定会很熟悉,在这里 cicada 就是使用 Docker 镜像来运行 Job 的。
如果你不太了解 Docker,你可以把 image
理解成类似于 GitHub Actions Job runs-on 的东西,不一样的是 runs-on 一般需要填写系统,比如 ubuntu-latest
,而 image
可以填写更具体的运行环境,比如这里用到的 node:18-alpine
,只要是 Docker 镜像就可以。
什么是 docker
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到流行操作系统机器上,也可以实现虚拟化。你可以在 官网 了解更多。
另外指定 cacheDirectories
为 ["node_modules"]
,这样就可以缓存 node_modules
文件夹,达到优化的目的。
然后我们本地运行来测试一下。如果想要本地运行测试 GitHub Actions,act 是一个不错的选择。而 cicada 自带本地测试功能,和 act
一样也依赖 Docker,所以务必在测试前安装、运行 Docker。
pnpx @cicadahq/cicada run ci
输出日志比较长,我就不一一截图了,这里就只给出开头和结尾两部分。可以看到执行了相关命令,也有输出相关的结果,最终是成功完成。
仿照已有实现,我们可以轻松地完成另外两个 Job,下面就是最终版的实现。
本地测试通过后,我们就可以把改动推送到仓库了。之后,我们可以到 cicada 控制台里查看。
正确配置之后,仓库显示样式会有所不同。
创建一个提交,控制台就会显示相关信息了。
遗憾的是,需要等待的时间实在是太久了。我等了两个多小时,还是没有运行起来,CI/CD 等这么久还不如本地跑 😅 试水也就只能到这里遗憾收场了。
小结
cicada 的优势和劣势都非常明显。
优势在于,它使用 TS 来做 CI/CD Pipelines 的配置,可以使用大量 JS/TS 的特性和功能,而不必受到 YAML 的折磨。比如你想使用 GitHub Actions 里面的 matrix,你完全可以使用数组和 Array#map
来实现,这写在了官方的 Example 内。
它的劣势在于成熟度不足。如果 CI/CD Pipelines 需要等待几十分钟甚至更久,远远超过本地运行的时间,那我为什么还要用它呢?本地运行不是更快更舒服吗?此外,它还没能支持并发执行 Job / Pipeline,需要联系来帮助设立自托管运行器等。
长远来看,cicada 对于我这个重度使用 JS/TS 的人来说还是很 有吸引力 的,但我认为 目前不能投入实际使用,起码没给钱的不能,玩一下得了。