LCTT 的 CI 已经在 Travis CI 上运转了多年,一致保持着良好的使用体验。自 2019 年 Github 推出了自家的 CI 工具 Github Action 后,我们就在考虑将 CI 从 Travis-CI 迁移到 Github,以降低维护和沟通的成本,并借助于 GitHub Action Marketplace 实现更强的功能。
最近,因为 TravisCI 屡屡部署出错,而我们的账户因为使用的较多,已经超出了免费使用的限制,以此为契机,将 CI 从 Travis CI 迁移到 GitHub Action。
项目介绍
Translate Project 是 LCTT 翻译组的主要协作项目,几百位译者通过 GitHub 进行围绕开源、Linux、软件工程等领域的文章翻译,从 2013 年来,累计了大量的 Commit,致使项目下有非常多的文件。
Transalte Project 借助于 CI 帮助译者进行基本的文章格式进行检查;并定时执行命令,以进行所有的文章检查,对于超时未完成翻译的工作进行回收;对于文章的状态进行标记,生成相应的 Badge。
迁移思路
Travis CI 和 Github Action 在使用方面,其实总体差异不会太大,都是基于 YAML 文件格式来编写配置文件。不过,和 Travis CI 不同的是,Github Action 支持多个不同的配置文件,因此,你可以根据不同的场景,设定不同的配置文件,降低单个配置的文件的复杂度。
此外,由于我们的脚本中依赖了一些 Travis CI 的环境变量,也需要将其替换为 Github Action 中的相应环境变量,从而确保脚本可以运转。
改造实践
1. 分析之前的 CI 流程
我们在 TravisCI 上的 CI 配置文件如图
总体可以分为三块:
- 命令区:说明了安装阶段和执行阶段的操作有哪些
- 条件区:指定了这个配置文件在哪些条件下会生效
- 部署区:写明了构建产物如何进行部署
在命令区中,有预置的安装过程和后续的执行过程。在安装过程中,安装了一些依赖,并将当前的 pages 资源克隆到本地,以继承上一次构建生成的资料。
在条件区则指明了仅作用于 master 分支
在部署区便是将前面命令区的执行结果进行部署。
在实际的执行过程中,还会根据环境变量不同,决定是否要执行特定的命令,这部分在后续的改造过程中,就可以调整部署,拆分到不同的文件中。
2. 直译配置文件
在完成了基本的分析后,就可以建立新的 Action 配置文件了。由于基本的语法很类似,对于其中的不少内容可以进行直译。
比如,我们的配置文件在直译后,结果如下
直译的文件已经可以直接运行,不过,这里有很多不满足需要的地方,所以需要做一些修改。
3. 恢复 Travis CI 的环境变量
由于我们使用的 Badge 等生成脚本并非我所编写,所以在这一次的迁移中,并不打算对齐进行调整,以避免出现故障。而脚本中依赖了一些变量,需要将其重新设置出来。
Github Action 提供了一些方法,可以让你手动设置环境变量。你可以在你的构建的 step 中,加入如下代码,从而在构建环境中设定 TRAVIS_BRANCH 和 TRAVIS_EVENT_TYPE 环境变量,确保你可以使用这个环境变量。
- <strong>name</strong>: Set ENV variables
run: |
echo "::set-env name=TRAVIS_BRANCH::${TRAVIS_BRANCH:-$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')}"
echo "::set-env name=TRAVIS_EVENT_TYPE::$(if [ "schedule" == "$" ]; then echo "cron"; else echo "$"; fi)"
Code language: JavaScript (javascript)
此外,由于 set-env 这个方法相对比较危险,你还需要在环境变量中,开启危险函数的执行。
jobs:
build:
runs-on: ubuntu-latest
env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
Code language: JavaScript (javascript)
4. 拆分配置文件
Github Action 和 TravisCI 不同的一点是你可以将你的 CI文件拆分成多个文件,从而降低每一个单独的配置文件的复杂度。
根据前面对于流程的分析,可以将我们的 CI 流程拆分成三个部分:
- 生成 badge 文件,应当跟随每一次 commit 进行
- 生成 status 文件,执行时间较长,可以定期执行
- 根据 Pull Request 内容进行整理,做核验
则将我们的配置文件拆分成三个不同的文件
也得益于拆分开,则在 checker 中就可以免于安装一些必要的依赖,从而精简 CI 流程,提升 CI 的执行时间。
5. 测试 CI 的运行情况
在完成了配置文件的编写和拆分后,就可以进行本地的执行测试。Github Action 写完了,难免要执行一下,确保整个流程是正常的。
这个时候你可以安装工具(https://github.com/nektos/act),来在本地执行 action ,从而确认你的代码执行是正确的。
如果你是 macOS ,只需要执行 brew install act
就可以安装 act 工具,来完成 act 的安装。
安装完成 act ,就可以通过执行 act 命令来在本地执行 action ,比如,执行 act pull_request
来触发 GitHub 的 Pull Request 事件
通过本地测试后,再将你的配置文件推送到 GitHub 上,进行生产环境的测试即可。
6. 移除 Travis-CI
通过上述的一些步骤,我们完成了从 Travis CI 到 GitHub Action 的迁移,此时,就可以移除项目根目录中的 .travis.yml
文件,彻底关闭 travis-ci。
7. 修改 GitHub 的 Branch 保护条件
为了确保修改符合标准,我们限制了新的 Pull Request 必须通过 CI 检查,才能合并进入 master,因此,也需要修改相应的分支保护规则,确保设定相应的保护。
一些注意事项
1. 环境变量不同
如果你依赖了环境变量,则需要进行相应的修改。或者可以像我一样,先通过 set-env 来让本地拥有临时的环境变量,后续再逐步进行迁移。
2. Action 运行依赖要注意安全
Action 执行过程中会有两个部分。action 本身流程依赖于 master,但执行过程中调用的脚本是根据 source 决定的,因此,从安全角度来看,你应当尽可能将所有的流程放在 Action 中,而不是放在你的源码目录中。
总结
通过对 TravisCI 的流程整理、代码修改等流程,我们将之前的 Travis-CI 迁移至速度更快、性能更好的 GitHub Action ,一方面可以优化我们的工作流,另一方面,也让我们的代码更加简洁明了。
对于还在使用 Travis CI 的项目来说,也可以考虑迁移到 GitHub Action 中,来优化自己的工作流。
参考阅读
- https://mauricius.dev/run-and-debug-github-actions-locally/
- https://jeffrafter.com/working-with-github-actions/
- https://developer.okta.com/blog/2020/05/18/travis-ci-to-github-actions