使用Github Action检查Swagger文件过程中的问题总结

使用Github Action检查Swagger文件过程中的问题总结

Tags
git
git action
工作流
description
很多坑
更新时间
Last updated January 28, 2022

目标

我们希望通过github action的事件轮训,每隔5分钟检查一边swagger文件是否有更新
如果有更新,检查其是否是合法的swagger文件
如果是合法的swagger的文件,则通过飞书webhook向群聊中发起更新通知
如果是不合法的,同样通过飞书的webhook发起警告,告诉后端,文件存在问题
 

遇到的问题

在校验swagger文件的解决方案中,我们需要使用到一个swagger-editor-validate的库,这个库能检查出swagger文件的错误,测试时在runs-on: ubuntu-latest 的条件下是可以正常运行的,但是在实际环境中会遇到两个问题,
  1. 如果是公司的虚拟机环境runs-on: self-hosted 则会报错
(node:37080) UnhandledPromiseRejectionWarning: Error: Failed to launch the browser process! /root/actions-runner@2/_work/_actions/char0n/swagger-editor-validate/v1.2.1/node_modules/puppeteer/.local-chromium/linux-856583/chrome-linux/chrome: error while loading shared libraries: libatk-1.0.so.0: cannot open shared object file: No such file or directory
即无法启动浏览器
  1. 如果使用pluto的docker容器去跑,container: registry.xsky.com/xsky/ubuntu-pluto,也会报错
/__w/_temp/26f0364f-8af9-4632-bccf-c15535f63a2f.sh: line 1: cd: /root/actions-runner@1/_work/_actions/char0n/swagger-editor-validate/v1.2.1: No such file or directory
即找不到路径
 
这个问题无法跳过,于是只能深入swagger-editor-validator 源码进行研究,发现在docker容器环境中,报错的代码是
- run: cd ${{ github.action_path }} && npm install
此处的${{github.action_path}} 的对应地址是无法通过cd 命令到达的,这个变量理论上应该指向当前第三方action的根目录,经过搜索,发现有相关的issue 指出了,在自定义的容器中使用第三方action(复合操作)时${{github.action_path}} 似乎无法指向正确的路径,需要使用$GITHUB_ACTION_PATH 经过测试,确实如此。
 
于是修改将其中的${{github.action_path}} 全部替换为$GITHUB_ACTION_PATH ,问题消失,但是遇到了第二个问题。
(node:101) UnhandledPromiseRejectionWarning: Error: Failed to launch the browser process! /__w/swagger-editor-validate/swagger-editor-validate/node_modules/puppeteer/.local-chromium/linux-901912/chrome-linux/chrome: error while loading shared libraries: libgobject-2.0.so.0: cannot open shared object file: No such file or directory
可以看到,这与在主机下的报错原因相同。
研究swagger-editor-validator 原理可知,他利用了puppeteer这个库,模拟了swagger-editor 网页的操作并通过获取错误信息,puppeteer 库的原理是基于Chrome DevTools协议进行模拟的,所以我们需要安装官方的google-chrome。
在主机环境下,由于是CentOS,默认是不带有chrome的,需要安装,虽然puppeteer 的安装过程会安装chromium 但是缺少对相关依赖的安装,还需要另外安装,参考文章
在容器环境下,即使是ubuntu默认也是不安装chrome的(主机环境的ubuntu应该是默认装有chrome,或者默认有chrome相关依赖的,因为在runs-on:ubuntu-latest 下是可以正常调用swagger-editor-validator 的,没有环境,无法验证)
 
于是在github找到了提供puppeteer 运行环境的容器配置,
FROM ianwalter/pnpm:v1.3.0 LABEL "com.github.actions.name"="Puppeteer Container" LABEL "com.github.actions.description"="A GitHub Action / Docker image for Puppeteer, the Headless Chrome Node API" LABEL "com.github.actions.icon"="globe" LABEL "com.github.actions.color"="green" LABEL "repository"="http://github.com/ianwalter/puppeteer-container" LABEL "homepage"="http://github.com/ianwalter/puppeteer-container" LABEL "maintainer"="Ian Walter <[email protected]>" RUN apt-get update \ # See https://crbug.com/795759 && apt-get install -yq libgconf-2-4 \ # Install latest chrome dev package, which installs the necessary libs to # make the bundled version of Chromium that Puppeteer installs work. && apt-get install -y wget --no-install-recommends \ && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \ && apt-get update \ && apt-get install -y google-chrome-stable --no-install-recommends \ && rm -rf /var/lib/apt/lists/* # When installing Puppeteer through npm, instruct it to not download Chromium. ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true ENV PUPPETEER_EXECUTABLE_PATH /usr/bin/google-chrome-stable
该容器配置安装了最新版chrome及其相关依赖,可以让puppeteer正常的运行, 我们需要让swagger-editor-validate 在这个环境下运行
 
由于这两个库的star都不高,且puppeteer-container 的已经不再维护,所以考虑借鉴两种的代码来自己编写相关的逻辑。但是在实践过程中发现在Dockerfile打包,安装chrome依赖的过程中会报错,且自己打包Docker镜像的时间较长,由于时间不够,暂时不自己编写相关的Dockerfile文件,依然使用puppeteer-container 作为容器镜像运行swagger-editor-validate
 

总结

虽然问题看起来不复杂,但是由于涉及的环境较为复杂,包括了主机,容器,puppeteer,chrome依赖,github action上传运行等待时间等问题,所以在解决问题的时间上花费较大,虽然中途引入了act 来在本地运行github action,但是某些环境上的问题依然无法很快的在本地调试。
 
综合来看,需要提高对github action,Docker,CentOS的熟练度,才能更好更快的解决此类问题,这些能力也是在项目建设过程必不可少的问题,需要进一步的学习。