可以落地的 CI / CD 流水线
很幸运作为前端可以参与 DevOps 小组,流水线。
CI/CD核心:Tekton(为什么选Tekton:云原生、轻量级、扩展性好、有API接口,GitHub社区ok)
第一部分:发布平台
完整的流程:
- 创建发布单
- 初始化:Tekton 从 GitLab 上拉取代码,从最新 master 分支上切出 release 分支
- 持续集成 CI
- 代码检查
- 单元测试
- 报告生成
- 打包
- 制作镜像
- 镜像检测
- 测试
- 发布产线
- 完成
以上的流程可以统一运用于 Java, Python, Node, 静态页面
简单介绍一下界面
界面
界面设计的原则是提供详细的信息,有效的 UI 目的是提升使用者(开发、测试、运维..)的工作效率。发布详情页包含了发版过程需要了解的所有信息,不用再点开很多个页面。
1. 设计 + 开发:
2. 页面信息:
- 发布单信息(每次上线进行的一次发布)
- 常规发布:走完整的 CI/CD 流程
- 镜像发布:本地制作 docker 镜像后直接发布镜像
- 回滚发布:直接发布之前发布单的镜像
- 操作记录
- 实时流量监控(QPS、5xx)
- 测试报告(测试人员填写,支持添加外链到完整的报告内容)
- 本次发布涉及的 git commits
- k8s 各容器的实时状态
- 各CI/CD和流水线步骤的日志
- k8s 服务配置
第二部分:前端 CI/CD
CI / CD 的所有步骤都将会用 Tekton 来执行命令,具体执行的内容如下,可以在本地先确保都可以跑通。
1. 静态代码检测
这个就肯定是 ESLint 没跑了。推荐使用 Airbnb 或 Standard 的标准(接入说明),和插件。
使用 SonarQube 进行其他规范的检测。
统一的静态代码检测命令:
cnpm run lint
cnpm run lint-html
1. cnpm run lint
在 Package.json 中添加:
1 | "scripts": { |
lint:在/reports目录下生成eslint.json文件,用于之后sonar检测时读取的结果文件。
2. cnpm run lint-html
package.json 中需要添加:
1 | "scripts": { |
lint-html:在/reports目录下生成index.html文件,eslint报告的UI界面。
3. sonar
这里使用 Sonar 来上传 ESLint 的检测结果。
这一步无需配置,只要保证前面的 reports/eslint.json 文件成功生成就行。
可在本地安装 sonar 进行测试:
1 | sonar-scanner |
Artifacts:
reports
├── eslint.json
└── index.html
2. 单元测试
选了 Jest (和 React 同出一门,比较友好,Vue 也能用)。
Jest 提供了覆盖度报告,但是导出的 HTML 报告没有包含成功率之类的信息,所以决定用 Allure 来辅助一下。
选用 Allure 是因为为了配合其他的后端项目,统一单元测试报告。(Java、Python 配合 Allure 比较好用)
但如果前端用的是 Angular 用 Jasmine & Karma 更舒服。需要确保生成的测试报告是一致的(Allure 报告)。
统一的单元测试命令以及生成报告:
cnpm run test
allure generate --clean
1. cnpm run test
package.json中需要添加:
1 | "scripts": { |
在/coverage目录下生成覆盖度报告
2. allure generate –clean
2.1 生成 Allure 的报告,需要安装 jest-allure:
- cnpm i -D jest-allure
- 在 jest.config.js 配置文件中添加:配置完后每次运行 cnpm run test 就会在 /allure-results 目录下生成结果,用于之后的步骤。
1
2
3
4
5module.exports = {
testEnvironment: 'jsdom',
moduleFileExtensions: ['js', 'json', 'jsx', 'ts', 'tsx', 'node'],
setupFilesAfterEnv: ['jest-allure/dist/setup'],
}
2.2 生成 Allure 报告的 UI 界面
需要安装 allure(仅为了在本地跑通,也可以跳过,只要确保上一步的/allure-results生成即可)
Mac OS:
brew install allure
或:
直接下载,然后配置 $PATH
在项目根目录下运行:
allure generate –clean
在 /allure-report 目录下生成html文件
Artifacts:
coverage
├── clover.xml
├── coverage-final.json
├── lcov-report
└── lcov.info
allure-results
├── 2ed4135f-5ef3-4009-a9f0-bdc191e94680-testsuite.xml
allure-report
├── index.html
├── styles.css
3. 项目打包
静态检测和单测都没问题就开始打包。
命令:
cnpm run build
cnpm run upload-static
打包就不多说了,最后生成 build/ 文件夹包含所有静态文件,如果用 CDN 则需要在打包后上传,统一用以上命令。
生成一堆报告后别忘了在.gitignore里添加:
/reports
/coverage
/allure-results
/allure-report
/.scannerwork
Docker + k8s
CD 部分就是把 Docker 镜像部署到 k8s 就大功告成。由于 Node 版本很多,用于打包的基础镜像可以事先在本地准备好后,push 到 Gitlab,然后在 build 那一步用自己准备的基础镜像,就不用怕 CI 实际情况和本地差太多。
纯静态资源的前端项目用 Ngnix 即可,参考 Dockerfile:
1 | FROM nginx:1.18.0 |
1 | server { |
制作基础镜像可以参考:前端基础镜像
docker build -t #build-tag .
docker push
kubectl set image -n ...
企业微信通知
发布平台的通知接入企业微信,在测试和上线的时候会通知相关人员,上线成功后也会通知组内全员。
展望
可以看到发布详情页面上,当前有一个栏目是空缺的,也就是「灰度」的部分。
下一阶段,我们将通过 header、访问路径以及流量比例,三种方式来控制灰度发布。各业务可以各取所需地来配置。
第三部分:实际使用
遇到的最困难的就是让大家都接入这个流程。
比较方便的是 Java,因为每个 Java 项目都非常严谨,编译方式也都很统一。
其次是 Python,除了脚本特别多(需要另外解决)。
最难受的就是前端项目,不仅要考虑 node 版本,还要让各种花里胡哨的打包方式都统一,非常困难,要大家的配合。遇到一些需要其他语言 build 的依赖,更头疼,比如令人绝望的 node-sass。