什么是gitlab-ci

gitlab-ci是gitlab内置的持续集成工具,相比jenkins等重量级框架,她有如下优势

  • 轻量 界面美观友好

  • 与gitlab集成度高,而且很多公司都使用gitlab作为代码管理平台,因此具有一定便利性

  • 配置友好 在项目中添加yml配置文件即可

  • 原生支持docker

  • 支持webhook,可灵活的支持各种自动化流程

因为比较轻量,缺点也显而易见

  • yml配置文件不适合复杂的构建流程,复杂的流程需依赖编写shell脚本或者docker

  • 生态不完善,不支持插件拓展功能

结合上述优缺点,大规模并且依赖复杂的系统更适合用jenkins来部署,轻量应用或者是内部工具可使用gitlab-ci来部署

下面整理几个基于gitlab的基础架构流程

npm私服包发布流程

为统一维护管理公司内部公用组件库,npm私服成了一个流行的方案

而npm私服包若不加规范化的发布流程约束,会导致难以维护,往往是每个人负责自己的包,当其他人想加入开发的时候,开发和沟通成本就比较大,为此基于gitlab-ci制定了一套私服npm包的发布流程。

统一发布工具

开发了一个npm命令行工具,该工具兼容所有官方npm命令,特有init和ci命令

  • init 作用同npm init,但增加了个别字段的特殊处理,同时初始化过程中会在gitlab上的package组中新建一个项目用来托管代码

  • ci 为已存在的npm包项目添加gitlab-ci配置文件
统一发布流程
  • npm私服设置只允许指定的账户发布包

  • 初始化必须用专门的命令行工具

  • npm包必须编写单元测试

  • 开发人员将开发分支提交merge request到专门的发布分支

  • code review通过以后,合并开发分支到专门的发布分支

  • merge到发布分支将触发ci,ci自动执行单元测试

  • 单元测试成功以后,执行npm publish

  • 完成发布

基于webhook消息通知

gitlab提供了webhook,利用这个特性我们可以进行很多自动化的操作。
在目前工作流程中,经常有需要通知同事的场景,比如通知code review,预发布等,如果都手动通知,累积下来也是很长时间的,借助webhook可以实现监听某些事件,然后发送钉钉通知到相关人员,节省时间。 此流程关键在于webhook服务和接入钉钉api,另外钉钉和gitlab必须都是用ladp账户,保证是相同的用户信息,否则webhook事件里拿到操作人信息与钉钉用户信息不一致将无法推送钉钉消息

应用持续集成与部署

开发流程

遵循git-flow
在实际应用中开发使用开发分支,提测使用测试分支,发布使用发布分支分支
流程如下

  • 切开发分支本地进行开发
  • 提测时,提交merge request到测试分支,并指定code review人员
  • review通过以后,合并到测试分支
  • 发布时,合并测试分支到发布分支进行发布
  • 发布成功验证通过以后将发布分支合并到master
ci配置

上述流程分为测试,发布两个阶段,每个阶段都用特定的分支,借助ci中的only指令,可以为不同的阶段配置不同的脚本,例如

// 测试阶段 测试分支必须以test开头
only:
  - /^test/

// 发布阶段 发布分支必须以release开头
only:
  - /^release/

当测试和发布分支发生变动,比如merge,push时,将触发相应的脚本执行。脚本定义位于script字段中,可编写shell命令,如果部署过程复杂可以在项目中增加deploy脚本,然后ci执行此脚本即可

产出artifact

大部分前端node应用部署的时候都是采用pm2,而weex或者react native,app本地包等项目,项目编译之后并不需要启动服务,而是需要拿到产出的文件,下面举一个weex的例子

客户端打开weex页面时候,请求一个weex服务获取weex文件,weex文件统一通过专用发布平台发布,并将文件地址记录到数据库中。
在实际工作中发现发布weex的效率很低,最初使用的是jenkins来打包,然后将文件手动下载,再通过发布平台上传,浪费很多时间,还容易出错。 由于weex打包过程很简单,因此将打包流程迁移到了gitlab。 发布平台一键调用gitlab-api开启流水线,然后轮训产出结果,拿到产出后上传到存储空间,如此大大提高了发布效率

gitlab api

gitlab提供了标准的REST风格的api,文档参考https://docs.gitlab.com/ee/api/
基于这套api,可以实现很多自动化工具,例如上文提到的命令行工具和获取产出,内部实现都是使用了api,另外复杂一点可以实现分支比对,防止发布错误版本,文件变动监控,防止误操作重要文件,下面举几个例子

监控文件变化

通过gitlab hook拿到每次变更的文件,如果有重要文件发生了变动,则自动发消息给相关负责人

分支落后检测

发布版本时,通过gitlab的接口判断当前分支是否合过最新的master,避免发布落后的版本
gitlab本身未提供这个接口,解决方案是

  • 获取master分支信息,拿到master的commit
  • 获取当前发布分支的commit
  • 判断当前分支的commit中是否包含有master的当前commit
  • 如果有则说明当前分支有合过最新的master