golang项目对接travis ci

travis ci是一个免费的持续集成平台,当我们在github提交代码时会触发travis ci对我们代码的编译或者做任何自定义的行为(例如单元测试),一般用以验证最新提交是否可以正确编译和测试通过。

本次我将bigpipe项目对接到了travis ci,它采用golang语言开发,在README.md中显示的一个pass图标说明当前代码成功编译。

travis ci的注册与对接可以参考一篇博客:《使用 Travis 自动构建 Hexo 到 GitHub》,我就不描述操作流程了,而是记录对接过程的一些注意点。

原理

travis ci平台会通过Oauth协议获得你的github仓库授权,然后它就有权限实时的获知你的github仓库有提交事件。

其次,需要在使用travis ci的项目下放置一个配置文件,它描述了如何才能编译这个项目,它的名字叫做:.travis.yml

当我们提交代码时,travis ci检测到事件,读取项目下的.travis.yml,根据其中的环境依赖启动一个容器(类似docker),然后在某个目录下clone我们的项目,再执行我们的安装流程。

配置

在我的bigpipe项目中,我是这样编写的:

至于我怎么学会其规则的,其实参考travis ci的官方指导就差不多了,每一种语言都有自己的指导文档,我参考的是golang版本

你会发现,在文档中主要有2个配置项,它们都有默认行为,重要的是理解它们的意义。

  1. install:默认go get -t ./…,说明它会通过go get命令帮我们安装golang项目的依赖。然而我是用glide管理的包依赖(支持版本),所以我需要覆盖这个默认行为,自己来安装编译项目所需的所有依赖。
  2. script:默认是make和go test,说明它会通过makefile编译我们的项目,并执行go test进行单元测试。然而我是用build.sh编译项目的,并且我也没有单元测试,所以我要覆盖这个默认行为。

综合理解下来,install实际上是用来安装依赖的步骤,script是用来编译项目的步骤,它们有默认行为但都不是我想要的,所以需要自定义它们。

还有其他3个配置项,也简单的说一下:

  1. language:项目的语言环境依赖,travis ci会在容器里为我们安装好对应的语言,这里就是go了。
  2. go:因为language指定了go,所以go标签下就是指示项目需要在哪些(多个)golang版本下编译,travis ci会在多个golang版本环境下都编译一次,任何一个报错都将导致失败。
  3. sudo:是否需要root权限,这里required就是需要root权限。

实践

搞定travis ci并不简单,我提交了几十个版本才成功,主要是因为travis ci对项目的结构有一定的假设。我的项目采用glide管理依赖,整个项目的目录结构与travis ci的假设并不一样,它会给我设置一个错误的GOPATH路径,导致后续步骤都出现错误。

为了减少走弯路的时间,我的经验就是先提交一个基础的.travis.yml到项目下,然后观察travis ci的控制台日志,看看它到底是怎么下载、部署、设置环境变量的。同时,也搞明白install、script分别在哪个阶段被执行。

这个简单的travis ci可以这样写:

提交这个.travis.yml,然后去travis ci控制台观察执行日志,就可做到心中有数。

在bigpipe代码提交后,travis ci后台会看到这样的日志(内容过长,已经被折叠),请在新窗口打开图片:

你会发现它已经很明确在右侧标识出了install的6个步骤。

在install之前的命令其实都是travis ci的行为,你会发现它最后cd到了目录$HOME/gopath/src/github.com/owenliang/bigpipe,也就是我的项目目录下。

GOPATH默认被设置为golang的安装路径,我用glide安装配置需要设置GOPATH为项目目录,所以我在install环节重置了GOPATH。

因为我用到了kafka客户端,所以我还下载了librdkafka进行编译安装。因为要安装到系统路径,所以用到了sudo:

整体来说,只要知道了travis ci的默认行为,那么编写安装脚本就和在自己的linux上安装没有什么区别了,travis ci只是开了一个容器环境来做这件事而已。

最后别忘了,点击travis ci后台里的pass小图标,选择对应代码分支以及markdown语法,并将相关代码贴到README里,这样就可以让项目变得很酷了!

如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~