GitLab之持续集成实践

持续集成介绍

持续集成(Continuous integration,简称CI)是一种软件开发实践,即团队开发成员经常集成他们的工作,在每一天的时间中,可能会发生一次或者多次集成。而每一次的集成都是通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早的在持续集成的阶段发现软件中的错误。 持续集成给团队所带来的好处,不言而喻:

  • 减少并降低软件开发中的风险:在每天一次或者多次的集成中,通过相应的测试,能尽早的发现软件中的缺陷,尽量把软件中的错误暴露在开发阶段。最常见的场景,就是在多人的团队中,别人改动相关代码影响了你的代码逻辑,但他们不知道你写过这些单元测试或者没有跑单元测试的习惯,而持续集成能帮助解决这样的问题。
  • 减少重复而又枯燥的单元测试过程:代码的改动不能避免的就是需要重复并且不断回归的运行之前写好的单元测试,而这一过程往往让工程师头疼,因为编译代码,准备测试数据,运行测试并查看结果,完全是重复的体力劳动。通过自动化的持续集成,不需要人工干预,完全可以把工程师从痛苦的循环中拯救出来,降低心智负担,让工程师能够把精力放在具有更高价值的事情上。
  • 随时生成可运行和部署的软件:利用持续集成的特性,我们随时可以得到可以运行和部署的软件,对于客户来说,可以部署的软件产品是最实际的资产。而对于团队成员来说,也能让他们更有信心,因为他们清楚的知道每一次构建的结果,他们知道他们对软件的改动造成了哪些影响,结果怎么样。

GitLab对持续集成的支持

上面提到了持续集成的各种好处,其实,持续集成的好处还不止如此。在GitLab中,不仅仅提供了代码托管的功能,而内置的持续集成功能,也是它功能上的一大亮点。从GitLab 8.0以上的版本,就提供了GitLab CI的功能。从官网的介绍可以了解到,GitLab CI拥有许多不错的特性,其中比较惹眼的几点,包括:

  • 多平台支持:很巧的是,GitLab CI的Runner是由Go所开发的,这意味着在众多支持Go的平台上,都可以运行构建,甚至是树莓派上哦!
  • 多语言支持:编译脚本是基于命令行驱动的,支持Java, PHP, Ruby, C及其他语言。
  • 并行构建支持:GitLab CI会把多个同时出发的构建分派到不同机器上,以实现更快的并行执行。
  • 自动伸缩:在保证最小化成本的基础上,自动启动与关闭虚拟机来进行构建。

关于GitLab CI的特性还有很多,可以查看官方文档了解更多特性。

GitLab CI的大致架构,如下图:

主要分为GitLab CI和GitLab Runner两个部分。GitLab CI部分,实际上已经集成到GitLab的Web中,主要负责提供友好的界面,供用户管理项目与构建。而GitLab Runner,主要负责生成构建与运行单元测试以及完成其他后续的持续集成任务。GitLab Runner主要通过API与Web端的GitLab CI进行交互。为了实现持续集成,我们可以选用的最小化配置是一个GitLab CI实例与一个GitLab Runner。当然,如果要提高构建的效率,我们可以在条件允许的情况下,部署任意多个GitLab Runner。

GitLab CI实践

使用GitLab CI的功能,首先需要安装GitLab Runner。官方不推荐在同一台服务器上既运行GitLab,又跑GitLab Runner,因此,建议搭建单独的服务器用以运行GitLab Runner。这次实验中,用到了另外一台在Azure印尼机房的Linux服务器来安装GitLab Runner。在Linux的服务器上安装GitLab Runner,过程是比较简单的:

首先,需要添加GitLab的官方源到apt或者yum中:

1
2
3
4
5
# For Debian/Ubuntu
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.deb.sh | sudo bash

# For CentOS
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.rpm.sh | sudo bash

完成过后,就可以直接用apt或者yum来安装了:

1
2
3
4
5
# For Debian/Ubuntu
sudo apt-get install gitlab-ci-multi-runner

# For CentOS
sudo yum install gitlab-ci-multi-runner

安装过后,就是注册的过程。注册的过程,实际上就是把某台服务器上的GitLab Runner跟GitLab的Web关联起来。在GitLab中,runner分为两种类型:Shared Runner(共享型)和Specific Runner(指定型)

  • Shared Runner: 这类Runner是全局的,意思是为整个GitLab系统范围内的project提供构建服务,只有系统管理员能创建这类Runner。
  • Specific Runner: 这类Runner是被指定为某个project提供构建服务的,这意味着系统中的任何用户,都可以建立自己的Runner,并把它指派给自己的某一个project。

在注册Runner的时候,需要填入Token,GitLab根据不同的Token确定这个Runner是被设置为Shared Runner还是Specific Runner。

在这里,我们注册一个共享类型的Runner。首先,需要在GitLab的管理后台,拿到Runner的Token,然后开始注册。注册过程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sudo gitlab-ci-multi-runner register

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci )
https://gitlab.com/ci
Please enter the gitlab-ci token for this runner
xxx-token-xxx
Please enter the gitlab-ci description for this runner
my-runner
INFO[0034] fcf5c619 Registering runner... succeeded
Please enter the executor: shell, docker, docker-ssh, ssh?
docker
Please enter the Docker image (eg. ruby:2.1):
golang:1.6.2
INFO[0037] Runner registered successfully. Feel free to start it, but if it's
running already the config should be automatically reloaded!

在这里,为了自动化构建Go相关的项目,我们采用docker作为Runner运行的方式,并选择golang:1.6.2的docker镜像。注册成功之后,会提示可以启动Runner了。另外,顺便提一下更新Runner的方法:

1
2
3
4
5
6
7
# For Debian/Ubuntu
sudo apt-get update
sudo apt-get install gitlab-ci-multi-runner

# For CentOS
sudo yum update
sudo yum install gitlab-ci-multi-runner

注册成功之后,我们便能在GitLab的管理后台中看到这个Shared Runner:

接下来的过程,就是在项目中创建.gitlab-ci.yml配置文件,这个文件的意义在于告诉CI在构建的过程中应该做哪些事情,比如如何初始化环境,如何运行我们的test case。这个文件需要签入到我们工程的源代码中,并随项目的源文件一同提交。更加详细的配置项目,可以参考这里

最后一步,就是给我们的Go工程编写test case并commit,之后push给GitLab,在检测到push的改动之后,会主动触发Shared Runner的运行和构建的动作。成功运行之后,我们能在Runner的运行情况中查看到结果:

构建情况总览:

还可以通过点击,查看某个构建的具体情况:

对于成功编译和构建的项目,我们还可以为这个项目打上徽标。徽标能让团队的其他成员更加直观的了解最近的一次自动构建的结果。徽标的访问URL大致如下,根据自己域名和项目名称的不同,稍有变化: http://example.gitlab.com/namespace/project/badges/branch/build.svg

总结

通过设置,我们已经开启了GitLab CI的自动构建之旅,并配置了一个简单的Shared Runner,一切看来都非常简单。在实际的需求中,我们甚至可以根据团队的需求,配置多个Shared Runner,并为特殊的project设置指定的Runner。这样能大大节省构建的时间,提升GitLab CI的效率。

GitLab是一个贴心的开发者伙伴,内置集成的GitLab CI提供更为贴心的持续集成功能,Runner中搭配Docker更有锦上添花的感觉,最关键的是我们能以正确的姿势去使用它们,从而为团队带来最大化的收益,提升软件质量和开发效率。

支持原创技术分享,据说打赏我的人,都找到了女朋友!