返回 登录
0

使用GitLab来实现IOS项目的持续集成CI

阅读5544

声明:本文经赵昌峻授权发布,如需转载请联系作者。
作者:赵昌峻,码农、全栈工程师,长期关注云计算、大数据、移动互联网相关技术,从事IT行业十载,有5年企业级应用开发及3年云平台(openstack)研发经历,目前从事移动APP的研发,坚持每天快乐的编程。
责编:陈秋歌,关注前端开发、敏捷开发等领域,寻求报道或者投稿请发邮件chenqg#csdn.net。研发心得、项目实战、前沿技术、外文翻译……,只要是技术干货,十分欢迎投稿至chenqg#csdn.net。人人都是主编,这里就是你的舞台。

作为程序员,代码是一定要写的,而且要天天写。在好多地方见过这样一种说法:

只会写程序的程序员不是好程序员

当然,我不赞同这种观点,因为有的人他天生就是为程序而生的。但是掌握一些代码之外的理论知识也是一个不错的选择,它能让你的代码质量上一个新的台阶,能极大的提高你的“抠码”效率。

最近新的APP即将上线,但在产品、研发、运营几个环节出了一些问题,也让我静下心来思考一些一个程序员觉得很难直面的问题。这其中和技术相关的问题包括:

  • APP版本更新较为频繁的问题。
  • 测试覆盖不到位的问题。

APP的开发可能跟以前我所经历的大部分企业级应用软件、IaaS/PaaS平台、大数据平台相关产品完全的不同,为了响应市场需求,APP的迭代周期要以周为单位(打开手机看看常用 的APP大部分每周一更新),IOS还受到苹果审核周期的影响,会有更多的不可控因素。为了解决这些问题,目前我们主要做的工作包括几个方面:

  • 解决运营和产品环节的反馈机制问题。
  • 优化APP的打包、测试的方式。
  • 合理的制定版本发布计划。

今天想给技术人员分享的主要就是持续集成和交付/部署(CI/CD)方面的一些基础知识,同时结合我们现在正在开发的APP中遇到的一些问题,和大家共同探讨如何才能更好的优化我们的产品打包、测试过程。

持续集成和持续交付/部署 CI/CD

Continuous Integration (CI) is a development practice that requires developers to integrate code into a shared pository several times a day. Each check-in is then verified by an automated build, allowing teams to detect problems early.

By integrating regularly, you can detect errors quickly, and locate them more easily.

上面对CI的定义参考thoughtworks,可能把它生硬的翻译过来也不太好理解,我从这些年的产品研发过程中见到过的各种CI工具来定义CI的话,可以做如下定义:

CI是软件(产品)研发生命周期中对代码质量、系统集成的一个持续构进的过程,当作为一个团队开发产品时,每个人都要开发自己的功能模块,最终都需要集成在一起,代码也需要集中托管到同一个地方,通过使用一些自动化的代码打包、测试工具,能够在开发人员每提交一次代码的时候,系统自动对程序进行打包和单元测试,如果出现问题,及时通过邮件等方式通知相关的开发人员。

5年前,我还在从事企业级应用软件的开发,那时根本就没有什么单元测试,更没有自动打包、测试的工具,也就大家开发完功能,提交到SVN服务器,还有一个专业的人在需要打包里把代码下载下来在自己机器上打包,然后部署到测试环境跑一把,没什么大问题就上生产环境。现在想想还是真“土”。

这几年,我和我的团队主要是基于Openstack开发一款企业级的云管理平台,从一开始的懵懵懂懂,到现在形成比较成熟的基于CI的整个开发流程,也爬过了一个又一个的坑和坎。

目前我们比较成熟的套路是: git+gerrit+jenkins。

其中git用于代码托管,gerrit主要是是代码的评审,jenkins用于打包和跑单元测试。这样的组合百度一下,会有很多先辈们已经写了很多博客和文章,我这里就不在烂费精力了。今天我想介绍一下的是目前我们的APP开发过程中想采用的gitlab。要不然大家都觉得我写的东西没干货,也不好意思啊。

GitLab

GitLab是一个集代码管理、测试、代码部署于一体的开源应用程序,它包括一个有非常好的权限控制的Git版本管理系统,代码评审系统,问题跟踪系统,活动反馈系统,wiki,持续集成CI系统等。

上面的翻译可能有点别扭,没办法,我就这水平了,咱们直接进入正题吧。

我个人比较喜欢的就是GitLab长的太像Github了,使用很方便,同时采用了Github的Pull Request方式来对代码进行审核,还集成了CI(虽然大部分还是要看你写脚本的水平如何)。

我将通过使用一个iOS的Demo项目来给大家展示如何用GitLab来管理代码、进行代码审核、CI等等。

安装GitLab

在Docker盛行的今天,我也就偷偷懒,跑个Docker实例给大家演示一下,如果您打算在生产环境使用GitLab,可以参考官方的安装文档,包括一些集群方案都能找到。用Docker跑GitLab就一个命令:

这里假设我们的服务器IP是:47.88.21.77,一定要记得根据您的实际情况更改IP地址。

sudo docker run --detach --hostname gitlab.example.com --env GITLAB_OMNIBUS_CONFIG="external_url 'http://47.88.21.77/'; gitlab_rails['lfs_enabled'] = true;" --publish 443:443 --publish 80:80 --publish 22:22 --name gitlab --restart always --volume /srv/gitlab/config:/etc/gitlab --volume /srv/gitlab/logs:/var/log/gitlab --volume /srv/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce:latest

服务启动后,浏览器进入:http://47.88.21.77/

图片描述

首次进入可以设置root的密码,注册用户即可进入系统,这里我们演示时使用的用户名是cjzhao,登录后如下图所示:

图片描述

空空如也……

使用GitLab评审代码

在这里可以创建组织、项目,基本概念和Github一样,这里我们直接创建我们要演示的项目ios_ci_demo。

图片描述

OK,多的不解释了,一看就懂。

图片描述

创建完成后,进入项目首页,可以看到黄色的提示信息,为了能从远程把代码推到服务器,需要配置一个ssh公钥,点击add an SSH key把你自己的公钥添加完成,就可以把代码上传上去了。

添加完公钥后,回到项目首页,如下图所示:

图片描述

我们根据第三种方法把现有的代码上传到GitLab,即执行下面的代码:

cd existing_folder
git init
git remote add origin git@47.88.21.77:cjzhao/ios_ci_demo.git
git add .
git commit
git push -u origin master

我们的App很简单,如下图所示:

图片描述

很明显, Word是错的哦,后面我们将演示另一个用户修改完后提交代码,并做代码审核。

上传完代码后,进入项目首页,如下图所示:

图片描述

再注册一个新用户jack,然后用cjzhao登录后,进入项目设置页面(如下图所示),把jack增加到项目中,这样他就能提交代码了。

图片描述

添加的过程自己研究吧,很简单。加完后如下图所示:

图片描述

OK了,接下来用用户jack修改代码,并提交到Git服务器。

jack的操作主要包括以下几个步骤:

git clone git@47.88.21.77:cjzhao/ios_ci_demo.git
git checkout -b wordbug
//将word改为world
git add .
git commit -m "change word to world"
git push origin wordbug

这时jack登录系统后,会看到提交的代码,同时系统会提示您创建一个Merge request,如下图所示:

图片描述

点击Create Merge Request,填写一些修改内容的描述信息,请求cjzhao将代码合并到master即可提交。

cjzhao登录系统后就能看到jack请求合并的分支,如下图所示:

图片描述

在完成代码评审后,点击Accept Merge Request即可将代码合并到master。选中Remove source branch同时将wordbug分支删除。

OK,这就完成了多开发人员合作的项目代码评审流程。

GitLab中的CI

在GitLab中完成持续集成CI包括两个操作:

  • 配置一个Runner(用来编译、测试、打包的服务器节点)。
  • 在项目根目录增加YAML格式的CI脚本文件.gitlab-ci.yml。

配置Runner

我们首先来为我们的项目配置一个Runner,由于我们的项目是iOS的,因此需要在安装了MacOS操作系统和Xcode的环境下才能编译、打包我们的APP,因此我们需要将一台Mac计算机配置成我们的一个Runner,基本原理就是在Mac上安装一个代理程序gitlab-ci-multi-runner,然后将Mac注册到GitLab服务器端,然后这台Mac机器就能接收到GitLab服务器下发的CI任务,完成相应的编译、测试、打包等工作,然后将结果反馈给GitLab服务器。

在一台Mac机器上执行如下命令安装gitlab-ci-multi-runner(可能需要翻墙才能装):

sudo curl --output /usr/local/bin/gitlab-ci-multi-runner https://gitlab-ci-multi-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-ci-multi-runner-darwin-amd64

sudo chmod +x /usr/local/bin/gitlab-ci-multi-runner

进入项目的Runner配置页面,如下图所示:

图片描述

在Mac机器上执行如下命令,将这台Mac注册到GitLab并绑定到我们示例项目。

gitlab-ci-multi-runner register
#Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci):
#输入上图中的URL.
#Please enter the gitlab-ci token for this runner:
#输入上图中的token.
#Please enter the gitlab-ci description for this runner:
#输入一个描述信息,这里我们输入mac_runner
#Please enter the gitlab-ci tags for this runner (comma separated):
#输入一些标签,这里我们输入"mac,xcode7.1"
# Registering runner... succeeded runner=euasz2j9 
#Please enter the executor: docker-ssh+machine, docker, docker-ssh, parallels, shell, ssh, virtualbox, docker+machine:
#这里我们输入shell,因为ios项目的编译、测试、打包我们都采用脚本来执行。
#Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
#注册成功,接下来启动它
gitlab-ci-multi-runner install 
gitlab-ci-multi-runner start

现在我们的Mac机器就注册为一个Runner了,查看项目的Runner页面,如下图所示:

图片描述
我们的Runner就成功注册上了。接下来就可以编写CI的脚本了。

增加CI脚本文件 .gitlab-ci.yml

在项目根目录创建.gitlab-ci.yml文件,内容如下:

stages:
  - build
  - archive

build_project:
  stage: build
  script: 
    - xctool -project ioscidemo.xcodeproj -scheme ioscidemo clean
    - xctool -project ioscidemo.xcodeproj -scheme ioscidemo test -test-sdk iphonesimulator9.3

archive_project:
  stage: archive
  script: 
    - xctool -project ioscidemo.xcodeproj -scheme ioscidemo archive -archivePath build/ioscidemo
    - xcodebuild -exportArchive -exportFormat ipa -archivePath "build/ioscidemo.xcarchive" -exportPath "build/ioscidemo.ipa"
  only: 
    - master
  artifacts:
    paths:
      - build/ioscidemo.ipa

上面脚本使用了xctool,它是Facebook推出的一款替代xcodebuild的App打包和测试工具,它日志输出更加友好,性能高效,我们需要在刚才安装了Runner的Mac机器上先安装它,可以使用如下命令安装:

brew install xctool

OK,接下来就是提交我们最新的代码了:

git add .
git commit -m "add CI cfg file"
git push origin master

如果没有什么异常的话,CI已经在开始执行编译、测试、打包等工作了。见下图所示:

图片描述

看到绿色的passed了吧?这就说明编译、测试、打包都成功了(我可是耗费了好长时间才成功的,中间总会出现各种各样的问题)。就写到这儿吧,最后再给大家提供一点CD的思路(技术层面的),刚才的过程已经完成了App的打包,我们可以创建一个Releases的分支,在脚本中增加APP上传到iTunes Connect的脚本,这样就可以在发布新版本的时候完成APP的整个发布流程。

Apple给我们提供了一套命令行工具altool可以直接把ipa上传到itunesconnect,很方便的,详见:用altool上传您的应用程序二进制文件

OK,真的结束了,自己研究研究吧。

评论