结合 GIthub Actions 持续集成第三方库

375 阅读4分钟

接触到 Github Actions 的契机

最近开发了一个js缓存库,这个缓存库提供了三种高效的缓存策略:最近最少使用(LRU)、先进先出(FIFO)和最不经常使用(LFU)。

感兴趣的同学可以看看:github.com/algok-876/j… ,如果觉得还不错的话,可以给一个小小的 Star。

最初我想在我的仓库README文件中添加一些徽章,后面经过一番搜索,找到了这个网站:shields.io/ ,在这上面可以在线自定义生成徽章,将提供的Markdown链接粘贴到README文件中就可以看到下面的徽章了。

截屏2024-02-05 15.54.47.png

在这个项目中使用Jest进行单元测试,我想在READEME文件中放置一个可以展示测试覆盖率的徽章,类似下面这种

截屏2024-02-05 16.00.37.png

这个测试覆盖率总不能自己乱写吧,那这样还有什么意义。在本地测试倒是可以生成测试覆盖率,但是每次将代码推送到远程仓库时,都要重新手动生成这个徽章,非常麻烦。

我的想法就是如果每次推送代码能自动执行单元测试生成覆盖率,并且可以自动更新这个徽章,岂不美哉。

又经过了一番搜索,发现可以使用 Travis CICoveralls 生成测试覆盖率的徽章。

  • Travis CI:用于构建和测试托管在 GitHub 和 Bitbucket 上的软件项目。当你向仓库提交代码时,Travis CI 自动运行构建过程,包括运行项目指定的任何测试。
  • Coveralls:与持续集成(CI)结合,用于追踪软件项目的代码覆盖率,Coveralls 提供了一种可视化的方式来监控你的代码覆盖率随时间的变化,帮助开发者识别未测试的代码部分。

这样我们可以使用 Travis CI 在我们推送代码时自动执行单元测试,然后将测试报告上传到 Coveralls,展示在线的测试报告,我们的测试覆盖率徽章也是在这个平台上生成的。

可是Travis CI不再免费了,所以我就将目光转向了Github Actions,Github Actions同样也是一个持续集成的平台,而且还可以很好地与Github仓库互动,而且社区也有大量可用的 workflows。

初探 Github Actions

了解学习一个工具最好的办法就是 提出问题+阅读文档+实践+针对性扩展学习,这里贴出 Github Actions 的官方文档:docs.github.com/zh/actions 。官网内容很多,可以针对性地阅读,所以接下来对核心概念以及基本的使用方法做一个概括。

基本概念

  • workflow(工作流程):持续集成一次运行的过程,
  • job(任务):一次持续集成的运行,一个 workflow 可以包含多个jobs,多个job可以顺序运行,也可以并行运行
  • step(步骤):每个 job 由多个 step 构成,一步步完成。
  • action (动作):每个 step 可以依次执行一个或多个命令(action),比如运行一个脚本就是一个action,是具体的操作,Gihtub社区也提供了很多现成的action,例如actions/checkout@v2 将仓库代码加入工作流。

基本配置

workflow的配置文件存放在项目根目录下的 .github/workflows 目录中,需要自行创建。目录下的每个.yaml文件就是一个workflow,在将代码推送到远程仓库时,Github会自动执行所有workflow。

workflow的配置非常多,这里列举一些基本的配置,更多详细配置可以去官网工作流程语法上查看

name: learn-github-actions
run-name: ${{ github.actor }} is learning GitHub Actions
on: [push]
jobs:
  check-bats-version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v3
        with:
          node-version: '14'
      - run: npm install -g bats
      - run: bats -v
配置项含义
name工作流的名称,可以在actions的选项卡中看到,如果不指定则以workflow文件路径作为名称
run-name工作流一次特定运行的名称,如果省略,则run-name将设置为工作流运行的事件特定信息,例如push事件触发的工作流,设置为提交信息
on指定自动触发工作流程的事件,详细的事件列表,可以查看 events-that-trigger-workflows
run使用操作系统的shell执行命令行程序
uses使用可重用的代码单元作为 steps 的一部分 action
with以map键值对的形式给 action 传递参数

了解了 Github Actions 的基本使用之后就可以来完成最开始的需求了

自动化测试,生成测试覆盖率

注册 Coveralls

第一步需要先注册一个 Coveralls,选择使用 github sign in,授予相应的读写权限,就可以读取Github仓库内容了。

截屏2024-02-06 14.54.32.png

使用 Jest 作为单元测试框架

这一步需要根据自己的项目编写单元测试,并在 package.json 中配置 script

"test": "jest --coverage",

截屏2024-02-06 15.05.08.png

执行完单元测试之后,会在项目根目录下生成一个 coverage 文件夹,后续我们使用 工作流将这个文件夹中的信息上传到 coverall 平台

截屏2024-02-06 15.07.05.png

编写工作流配置文件

name: Tests
'on':
  push:
    branches:
      - dev
env:
  CI: true
jobs:
  test:
    name: Unit Testing
    runs-on: ubuntu-latest
    steps:
      - name: Clone repository
        uses: actions/checkout@v2
      - name: Set Node.js version
        uses: actions/setup-node@v1
        with:
          node-version: 20
      - name: Install npm dependencies
        run: npm install
      - name: Run tests
        run: npm run test
      - name: Coveralls
        uses: coverallsapp/github-action@master
        with:
          github-token: '${{ secrets.GITHUB_TOKEN }}'
          flag-name: ubuntu-node-20
          parallel: false
  finish:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - name: Coveralls Finished
        uses: coverallsapp/github-action@master
        with:
          github-token: '${{ secrets.GITHUB_TOKEN }}'
          parallel-finished: true
  • 首先,这个工作流在dev分支上发生push事件时自动触发
  • 第一步先下载仓库到服务器上
  • 第二步设置服务器上的nodejs版本
  • 第三步下载项目依赖
  • 第四步运行测试命令
  • 第五步将测试报告上传到coveralls平台上
  • 完成 test 这个 job 之后执行 finish 通知 Coveralls 上传完毕

在 Gihtub Actions 选项卡中查看 workflows 状态

截屏2024-02-06 15.29.58.png

截屏2024-02-06 15.28.22.png

可以看到一次工作流就执行完成了,再去Coveralls平台上看可视化的测试报告

截屏2024-02-06 15.35.35.png

截屏2024-02-06 15.36.09.png

直接把 coverage 徽章的 markdown链接粘贴到README文件中,就会显示出徽章。

自动发布 NPM 包

既然测试都自动化了,能不能借助Github Actinos把发包的流程也自动化了呢,当然可以,而且官网就提供了相关的workflow,详情链接:发布 Node.js 包

在此之前首先需要生成一个NPM的Token,用于发包时校验身份,具体操作方法查看:使用token发布npm包

将生成的 token 添加到 repositry secret 中,后续会在工作流中通过 secret 上下文拿到这个token

截屏2024-02-06 16.10.49.png

name: Publish Package to npmjs
'on':
  push:
    branches:
      - release
jobs:
  publish:
    name: publish package task
    runs-on: ubuntu-latest
    steps:
      - name: Clone repository
        uses: actions/checkout@v2
      - name: Set Node.js version
        uses: actions/setup-node@v1
        with:
          node-version: 20
          registry-url: 'https://registry.npmjs.org'
      - name: Install npm dependencies
        run: npm install
      - name: Build
        run: npm run build
      - name: Publish
        run: npm publish
        env:
          NODE_AUTH_TOKEN: '${{ secrets.NPM_TOKEN }}'

将开发好的代码合入release分支之后,就会触发自动发布的工作流,目前有个小缺点就是合入release之前需要手动变更一下npm包的版本号,否则可能发包失败

总结

结合 Github Actions 来对第三方库进行持续测试与发布,将重复的工作自动化,使我们更加专注于代码开发,而不需要担心基础建设层面上的问题,后续我想尝试在workflow中解决NPM包版本的全自动管理(如果你有什么解决思路,欢迎与我讨论),还会不断探索CI/CD在软件开发过程中发挥的作用。