视频云SDK iOS持续集成项目实践

1. 前言
2016年, 我们维护的 iOS推流播放融合SDK KSYLive_iOS 在github上发布了40多个版本, 平均两周发布一个新版本,经历了最初痛苦的全手动版本构建和维护, 到后来慢慢搭建起来的持续集成系统, 在这里简要的总结一下这个搭建过程中的一些实践经验。

1.1 持续集成的作用

持续集成系统主要在如下两个环节提供服务:

开发阶段(build), 开发人员提交代码后, 在服务端能够自动对提交的版本进行构建和测试, 保证提交能够编译,并自动测试通过的代码可以不给同事添麻烦,提高工作效率. 对代码审查的人来说,能减轻不少负担。

发布阶段(release), 当阶段性完成了开发任务后, 通过tag触发版本发布, 能够减少手动进行版本构建的工作, 并减少人工引入的疏忽和错误。

后面讲到每个工程组件的持续集成时,都需要针对这样两个环节分别说明:

1.2 持续集成的工具

持续集成可选的工具比较多, 比如Jenkins, Travis CI等等.由于我们内部的版本管理工具是gitlab[http://gitlab.com], gitlab作为代码管理仓库, 和code review的工具. 而gitlab最近的版本中直接提供了CI的server, 可以非常方便的用起来. 权限管理, 代码提交触发等都变得非常自然, 我们大部分的CI工作都是通过gitlabCI进行的.

视频云SDK iOS持续集成项目实践
gitlab ci Architecture

gitlab ci 的 server直接集成在了gitlab server中, 每当我们提交代码时, ci server就会生成一个构建任务, 在gitlab的页面上可以很直观的追踪到任务的执行情况和执行结果.

gitlab ci runner 是一个独立的应用程序, 跑在worker设备上. 他负责从ci server 领取一个任务并完成它.

gitlab ci的基本使用方法可以参考gitlab 自己的指南, 或者简书上搜搜中文版的图文教程.

2. 视频云SDK 持续集成实施

KSYLive_iOS 是一个提供了在手机上直播推流和播放的SDK, 在开发过程中, 我们有不同的同事分别维护demo代码,推流代码,播放内核代码和底层公用部分代码, 只是最后编译打包为一个完善的SDK提供给客户使用. 因此开发过程中涉及到每个模块自身的编译测试,以及多个模块之间的版本同步更新的问题.

2.1 SDK 项目结构
视频云SDK iOS持续集成项目实践
SDK arch
上图中,每个框都是一个gitlab上的代码仓库,存放着代码或编译后的二进制文件

codecs: 其实是多个开源项目的仓库, 包括aac,264等音视频的编码器, 作为FFMpeg的依赖项.
FFMpeg: 为推流和播放依赖的多媒体框架
libyuv: 对图像进行颜色空间转换的工具库
KSYCommon: 项目中推流和播放的公共代码
GPUImage: GPU图像处理的框架
KSYStreamer: 推流相关代码
KSYPlayer: 播放相关代码
KSYGPUFilter: 美颜滤镜相关代码
libksylivedep: 所有代码编译后的二进制库文件和头文件
KSYLive_iOS: 最终对外发布的SDK库和demo
整个持续集成系统要保证的是KSYLive_iOS中demo能够顺利build 通过和功能正常.
持续集成系统的中枢则是 libksylivedep, KSYLive_iOS中的SDK本质上是将libksylivedep中的静态库进行组合得到的, 其他项目的git仓库中都只存放代码.
libksylivedep 主要是因为有一些第三方库的构建过程比较耗时,且改动频率不高, 将其构建的结果直接存放到libksylivedep中, 能够起到节约时间的作用. 并且因为有libksylivedep的隔离, 每个项目的持续集成任务更加清晰,减少了项目依赖带来的复杂性.

2.2 SDK 持续集成结构

整个SDK的持续集成简单来说就是给以上的每个项目都添加CI配置. 这里一共有4种CI任务

代码仓库的build任务
每当开发人员对SDK代码进行了修改, 提交代码到gitlab之后, 都会触发此任务. 任务内容主要是保证SDK代码能够顺利编译出对应的静态库文件, 并保证sdk更新到KSYLive_iOS中去之后,demo能够也是正常工作的.
这里有一些代码库的是没有依赖项的, build任务比较简单, 可以直接完成.
而有的代码库则需要依赖其他库, 这个依赖关系主要是通过libksylivedep来解决的.
代码仓库的release任务
当每个迭代完成的时候, 一个代码仓库的所有改动汇总后打上对应版本号的tag, 可以发起一次release任务. release任务是在build通过的前提下, 将build的结果, 发布到libksylivedep中. 在libksylivedep的master分支的基础上, 更新本项目对应的静态库和头文件, 发起合并请求.
KSYLive_iOS 的build任务
KSYLive_iOS 的build任务主要是用于检查demo代码修改和SDK静态库更新的正确性.
KSYLive_iOS 的release任务
当完成一个迭代, 对应版本通过了QA的测试时, 可以出发release任务, 将SDK和demo更新到对外的github上.

3. 总结
视频云SDK iOS持续集成项目在开发阶段能够保证每次代码提交的质量, 能够提前发现自己引入的破坏开发环境的"坏"提交, 对提高开发效率有比较大的帮助. 在版本发布阶段, 可以将大量重复的操作自动完成,将发布环境和开发环境分离, 减少人为发布引入的不确定性问题。
在视频云 iOS SDK这个依赖关系比较复杂的项目中, 通过引入预编译二进制库存放的仓库, 减少了项目的构建时间, 隔离了依赖关系。

作者:金山视频云