持续集成是一种软件开发实践方法。在软件开发过程中,团队成员频定期将各自开发的代码集成到一个共享的代码仓库中。每次代码提交后,会自动触发一系列构建、测试和验证的流程。这个流程包括编译代码、运行单元测试、集成测试等多种测试手段,来快速检测代码集成过程中可能出现的错误,如接口不兼容、新代码导致原有功能失效等问题。通过持续集成,可以尽早地发现并解决软件集成过程中的问题,使得软件的开发过程更加稳定和高效,让开发团队能够更及时地得到反馈,确保软件产品的质量随着开发进度持续提升。
持续集成的后续相关的流程还包括持续交付和持续部署。
- 持续交付:在持续集成的基础上,确保软件产品能够随时处于可发布状态。它涉及到将经过测试的代码构建成果通过一系列自动化或半自动化的流程,使其能够快速、可靠地部署到类生产环境(如预发布环境、测试环境等)。持续交付的重点在于交付过程的自动化和可重复性,能够让团队在短时间内将软件的新版本交付进行验证,同时保证软件的质量。
- 持续部署:将通过自动化的手段,将持续交付通过的代码自动地部署到目标环境中。
前端只需关注持续集成和持续部署。在引入两者之前,前端的研发流程通常如下:
- 在本地进行代码开发和调试
- 在本地运行测试脚本
- 通过git push将代码提交到远程的代码仓库
- 进行代码构建和部署
这4个步骤都要人力保障,涉及了大量的人工操作。如果引入了持续集成和持续部署,那么前端开发人员只需关注代码开发和调试工作。
1. Jenkins
Jenkins 是一款开源的自动化服务器,在软件开发和运维领域应用广泛。它主要用于实现持续集成和持续交付(CI/CD)流程,能够自动化地构建、测试和部署软件项目。通过 Jenkins,开发团队可以定义一系列的任务流程,如在代码提交后自动触发构建操作,包括编译代码、运行单元测试、集成测试等,还能进行打包和将软件部署到不同的环境中。它拥有丰富的开源生态圈,支持多种插件,这些插件可以帮助 Jenkins 与各种工具(如版本控制系统、测试框架、容器编排工具等)集成,从而灵活地适应不同的软件开发流程和技术栈,极大地提高软件开发的效率和质量,是现代软件开发过程中的关键工具之一。
1.1 Jenkins任务
Jenkins中的所有操作都是通过任务的形式体现的,Jenkins的任务主要分为6类:
- 自由风格的项目(Freestyle Project):这是Jenkins 中最主要的任务类型。它允许用户以自由的方式定义构建过程,用户可以通过添加各种构建步骤,如执行 shell 脚本、运行批处理命令、调用 Ant 或 Maven 等构建工具来构建项目。这种类型的项目对于简单的构建和测试场景非常适用。
- 流水线(Pipeline):通过流水线可以编排长期运行在多个节点上的任务,用于定义复杂的持续集成 / 持续交付(CI/CD)流程。它使用一种基于代码的方式(通常是
Groovy
脚本)来定义整个软件交付流程,从代码拉取、构建、测试、部署到环境等各个环节。流水线的优势在于可以将整个 CI/CD 流程作为代码进行版本控制,这样可以更好地跟踪和维护流程的变化。 - 多配置项目(Matrix Project):主要用于处理具有多个变量组合的构建场景。它允许用户定义多个维度的配置,如不同的操作系统、不同的数据库、不同的编译器版本等,然后 Jenkins 会自动为每个配置组合执行构建任务。用于多环境测试、平台指定构建等。
- 组织文件夹(Organization Folder):用于对多个相关项目进行组织和管理的任务类型。它可以根据项目的组织结构(如按照团队、产品线、技术栈等)来划分文件夹,并且可以在文件夹级别设置一些通用的配置,如共享的构建环境变量、共享的插件配置等。
- 多分支流水线(Multibranch Pipeline):专门为基于分支的开发模式设计的任务类型。它能够自动发现代码仓库中的分支(包括主分支、特性分支、修复分支等),并为每个分支创建一个独立的流水线。
- 文件夹(Folder):主要用于在 Jenkins 中对项目进行逻辑分组。
其中,自由风格的项目(Freestyle Project) 是Jenkins 中最基础且灵活的任务类型,也是最主要的任务类型,它由6部分组成:
- 基础配置:描述任务的基本信息。
- 源码管理:用于获取代码仓库。指定代码仓库的位置和访问凭证
- 构建触发器:描述了在什么情况下会触发项目的构建流程。它有多种触发方式,如定时触发(按照设定的时间周期自动触发构建)、代码提交触发(当代码仓库有新的提交时自动触发构建)等。
- 构建环境:描述构建运行时的环境情况。包括构建输出日志添加时间戳、工作空间清理、任务超时中断等
- 构建:核心配置,用于定义任务构建过程中需要执行的脚本。
- 构建后操作:用于定义构建完成后需要执行的脚本。
1.2 配置Jenkins Webhook
通过配置 WebHook
,Jenkins
能够监听 GitLab
的变更行为,并根据预先设定的规则来启动对应的 Jenkins
构建任务,从而实现代码仓库和构建系统之间的自动交互,让构建过程能及时响应代码变化,从而实现持续集成和持续部署。
在Jenkins
中配置WebHook
需要安装三个GitLab
插件:
- GitLab Hook:实现 Jenkins 与 GitLab 之间 WebHook 通信
- GitLab API:让 Jenkins 能够与 GitLab 的 API 进行交互
- GitLab Authentication:处理 Jenkins 与 GitLab 之间的身份验证
2. 持续集成
2.1 测试自动化
常用的自动化测试工具包括 Jest
、Cypress
和 LambdaTest
,为了实现测试自动化,可以将其配置到Jenkins任务的构建环节。
Jest
:单元测试,可以配置collectCoverage开启测试报告收集功能,然后通过coverageThreshold设置代码覆盖率的标准。Cypress
:一般通过可视化方式运作,然而在Jenkins中所有任务信息都是以文本的形式记录的。可以用无头浏览器模式运行测试用例,并且在控制台输出测试结果。还可以保存录制视频,用于回放,追踪问题。LambdaTest
:需要安装lambdatest-automation
插件,帮助Jenkins通过LambdaTest
的认证,同时将测试结果发送到Jenkins。
2.2 语法检测
开发人员使用babel等工具对JavaScript代码进行处理,对浏览器不支持的功能进行降级处理。为了检测语法,可以使用es-check
工具来扫描构建的代码是否符合开发人员的预期。
2.3 扫描注释
开发人员在开发过程中往往会将注意事项以注释的形式写进代码里,对代码内容进行补充说明。这些注意事项应该经过确认才能上线。fixme
工具就可以很好地处理这种场景,它对代码文件进行扫描并匹配注释类型,在控制台打印扫描结果。可以将fixme
工具配置到持续集成中,在分支集成时,如果检测到不合法的注释事项,开发人员应该进行事项确认并更新注释再合并。
fixme
可以检测以下7种注释类型:
- NOTE:描述代码的功能、用法
- OPTIMIZE:用于标记可能需要优化的代码部分
- TODO:标记待处理的事项
- HACK:标记临时解决方案,或者不能解释清楚的地方
- XXX:标记那些存在疑问或者可能有问题的代码部分
- FIXME:表示这部分代码能正常运行,但是存在需要修正的问题
- BUG:记录已经发现的错误
2.4 依赖检测
npm是前端的包管理工具,通过npm使用第三方工具包虽然可以提高前端的开发效率,但是也存在一些问题。npm在安装依赖时会自动生成package-lock.json
文件用于锁定版本,锁定的版本可能存在功能缺陷或漏洞,开发人员仅靠版本号无法感知当前的依赖版本是否存在问题。为此,npm官方提供了audit
。
npm audit
命令用于检查项目中安装的依赖包版本是否存在已知的安全漏洞,并将发现的安全问题以详细报告的形式展示出来,包括漏洞的严重程度、受影响的依赖包版本和修复建议等内容。对于发现漏洞,可以运行npm audit fix
一键修复。npm audit fix
只会自动升级不存在breaking change的版本,对于存在breaking change的版本则会在输出信息中提示。
如果要在持续集成 npm audit
,那么可以用--audit-level
参数配置报告检测中的缺陷风险等级,对依赖检测进行卡点。比如npm audit --audit-level=critical
检测到critical等级的风险时,npm audit
就会以非零的状态码异常退出,从而中断集成,提醒开发人员排查并修复缺陷。
2.5 自动构建
开发人员可以将资源上传后的工作全部添加到持续集成中。如果项目以master为基准分支执行发布工作,那么可以配置相应的Webhook,当基准分支出现内容更新时,Jenkins可以自动拉取Git仓库,并执行安装依赖、自定义脚本、打包构建等工作,构建相关的问题会在发布前暴露。如果构建成功,那么开发人员可以编写脚本将构建结果打包压缩,并使用 commit hash命名,上传到服务器中。
3. 持续部署
持续部署指通过自动化手段将通过持续交付的代码自动部署到目标环境中。一般来讲,持续部署只用于非生产环境。
Jenkins有很多种方式可以实现自动化部署,将更新后的代码自动部署到测试环境以供QA验收。比如,可以在Jenkins构建环节的最后一个步骤添加shell脚本,将构建好的代码部署到测试环境。或者新建一个部署任务,在持续集成任务的“构建后操作”中执行。