以前构建android工程都是使用jenkins,最近想试试gitlab-ci-runner,于是一发不可收拾,忙活了一个晚上,也遇到了一些坑,总的来说,它和gitlab的结合比jenkins更紧密了,jenkins毕竟是gitlab之外的一套ci工具,和gitlab的配合上是不如gitlab-ci的,但不可否认,jenkins同样是一款强大的ci工具,两者并没有孰优孰劣之分。
本篇文章不是讲如何搭建环境之类的,这些资料网上比比皆是,我写这篇文章的目的是想分析下gitlab-ci是如何运作的,于是我花了点时间画了下面这张图。

首先早期的gitlab是没有gitlab-ci-runner的,也就是在早期它就是一个纯粹的代码仓库,后面gitlab引入了gitlab-ci工具(gitlab-ci-runner),这个工具它本身不具备构建的功能,它类似于zookeeper这种服务治理中心,真正的干活的是gitlab-runner-client,这些client需要在这个gitlab-ci-runner(server)中进行注册,gitlab-ci-runner(server)就可以对它们发号施令,这其实就是一种cs结构,runner server可以分三种,group runner、shared runner、specific runner 三种runner 本质是一样的,就是作用域不同,group runner作用在工程组上的,利用这个特征,我们企业开发过程中可以划分不同开发小组,因为android、ios、web、h5 它们的构建是完全不同的,正好使用不同的runner server,而shared runner可以作用在任何一个工程上,实际上,没有哪个构建runner会是通用的,specific runner是特定的工程上的,一些构建差异比较大的工程可以采用这种方式。
所以开发团队在gitlab使用中分组是非常有必要的,分组后可以定义各组专有的gitlab-ci-runner,互不干涉。
我们以构建android 工程为例,分析gitlab-ci从代码提交到构建经过了哪些步骤
1、部署远程或者本机的一套gitlab-runner-client 包括android编译环境,这里就采用docker方式,先安装docker,后安装gitlab-runner也就是gitlab-runner-client,这里以centos7为例
# 更新yum
sudo yum update
# 卸载旧版本
sudo yum remove docker docker-common docker-selinux docker-engin
# 安装需要的软件包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 设置yum源
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装docker最新版
sudo yum install docker-ce
# 启动docker 设置开机启动
sudo systemctl start docker
sudo systemctl enable docker
# 获取gitlab-runner脚本运行(脚本作用是添加gitlab-runner源)
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
# 安装最新版本的gitlab-runner
sudo yum install gitlab-runner
# 注册gitlab-runner到gitlab-ci-runner server 需要填写gitlab上提供的信息
sudo gitlab-runner register
进入gitlab android组页面-->设置--->CI/CD-->展开Runner 获取到url 和token,在上面的注册步骤中填入,executor执行环境填docker,镜像名称填 jangrewe/gitlab-ci-android 该镜像包含了android sdk等一系列android构建所需的环境,最后要求填tags自定义一个并且记住,比如填入android。
2、注册成功后在gitlab android组的设置-->CI/CD-->展开Runner 可以看到一个可用的runner客户端。
3、在android工程根目录下创建一个文件.gitlab-ci.yaml 文件名必须是这个,当然也可以自定义,但需要在gitlab上做相应更改。然后贴入以下脚本。
image: jangrewe/gitlab-ci-android
# 用来编译 android 项目的镜像
variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false" # 禁用 gradle 守护进程
before_script:
# 配置 gradle 的缓存目录
- export GRADLE_USER_HOME=/cache/.gradle
# 获取权限
- chmod +x ./gradlew
stages:
- build
# 提交代码自动编译
build:
stage: build
only:
- master
script:
- ./gradlew assembleDebug
artifacts:
paths:
- app/build/outputs/apk/debug/
tags:
- android
image指的是你要gitlab-runner使用哪个镜像构建,only: master是指针对master分支的提交才有效,artifacts:paths是指将打包完成的该目录下的文件上传回gitlab工程中,tags就是在client注册过程中填写的android,这里指定tags就是指定使用哪个gitlab-runner-client。
4、android工程有代码提交,gitlab-ci-runner中的android group runner 按照.gitlab-ci.yaml脚本中的流水线配置向已经注册在gitlab-ci-runner(server)中的 gitlab-runner-client(centos7中的runner)发布构建命令。
5、centos7中 gitlab-runner-client收到命令,拉取名为jangrewe/gitlab-ci-android 的 docker镜像,拉取gitlab-runner的docker镜像,运行这两个镜像, 执行git clone 工程,克隆完毕执行构建,构建完成后上传构建完成的包到gitlab
6、gitlab在工程中可以下载打包好的android包
以上是我对gitlab-ci-runner的流程分析总结,在搭建过程中遇到了一个坑,在centos7中的docker 执行 git clone拉代码失败,经过分析,是因为docker容器内无法连接网络所致,解决办法是
重新建立docker桥接,执行以下命令
service docker stop
ip link set dev docker0 down
brctl delbr docker0
brctl addbr docker0
ip addr add 172.17.42.2/24 dev docker0
ip link set dev docker0 up
service docker start
完成后这个坑解决了,解决之后顺利完成打包作业。
After reading the topic several times, I feel that I need to republish it on my blog. After the admin’s permission, I will share the topic on my personal page. I hope for more useful topics of this type.