作为程序员,代码是一定要写的,而且要天天写。在好多地方见过这样一种说法:
只会写程序的程序员不是好程序员
当然,我不赞同这种观点,因为有的人他天生就是为程序而生的。但是掌握一些代码之外的理论知识也是一个不错的选择,它能让你的代码质量上一个新的台阶,能极大的提高你的“抠码”效率。
最近新的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 repository 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服务器,还有一个专业的人在需要打包里把代码down下来在自己机器上打包,然后部署到测试环境跑一把,没什么大问题就上生产环境。现在想想还是真“土”。
这几年,我和我的团队主要是基于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_firstpage.png空空如也……
使用gitlab评审代码
在这里可以创建组织、项目,基本概念和github一样,这里我们直接创建我们要演示的项目ios_ci_demo。
gitlab_newproject.pngOK,多的不解释了,一看就懂。
gitlab_projecthome.png创建完成后,进入项目首页,看到黄色的提示信息了吧,为了能从远程把代码推到服务器,需要配置一个ssh公钥,点击add an SSH key把你自己的公钥添加完成,就可以把代码上传上去了,这个过程就不截图了哦,看到我的公钥也不是太好……呵呵。
添加完公钥后,回到项目首页,如下图所示:
gitlab_codeuploadmethod.png我们根据第三种方法把现有的代码上传到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很简单,如下图所示:
Simulator_hello.png很明显, word是错的哦,后面我们将演示另一个用户修改完后提交代码,并做代码审核。
上传完代码后,进入项目首页,如下图所示:
gitlab_project_home_first.png再注册一个新用户jack,然后用cjzhao登录后,进入项目设置页面(如下图所示),把jack增加到项目中,这样他就能提交代码了。
gitlab_project_setting_menu.png添加的过程自己研究吧,很简单,要不编辑会认为我的文章就靠截图凑数了。加完后如下图所示:
gitlab_add_user_to_project.pngOK了,接下来用用户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,如下图所示:
gitlab_create_merge_request.png点击Create Merge Request,填写一些修改内容的描述信息,请求cjzhao将代码合并到master即可提交。
cjzhao登录系统后就能看到jack请求合并的分支,如下图所示:
gitlab_accept_merge_request.png在完成代码评审后,点击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配置页面,如下图所示:
gitlab_config_runner.png在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页面,如下图所示:
gitlab_runner_running.png我们的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已经在开始执行编译、测试、打包等工作了。见下图所示:
gitlab_project_build_status.png看到绿色的passed
了吧?这就说明编译、测试、打包都成功了(我可是耗费了好长时间才成功的哦,中间总会出现各种各样的问题)。就写到这儿吧,最后再给大家提供一点CD的思路(技术层面的),刚才的过程已经完成了app的打包,我们可以创建一个Releases的分支,在脚本中增加APP上传到itunesconnect的脚本,这样就可以在发布新版本的时候完成APP的整个发布流程。
Apple给我们提供了一套命令行工具altool可以直接把ipa上传到itunesconnect,很方便的,详见:用 altool 上传您的应用程序二进制文件
OK,真的结束了,自己去研究吧。
希望本文对您有所帮助,谢谢。
CJ推荐:
程序员的编辑器-VIM(爱就是爱)
向开源社区贡献您的代码
在github上写博客
DevOps是什么东东?
js依赖管理工具bower
JS模块化编程-requirejs
网友评论
1,开发者请求是直接合并到master分支吗?git push代码后运维应该是怎么样发布的流程?master是指正式发布的环境,那预生成环境应该在哪个环节?
2,gitlab的CI/CD这项功能,在jenkins上能够很快速的实现,为什么还要使用gitlab来进行CI/CD?
stage: build
only:
- master
except:
- feature
- develop
为什么每次往develop和feature上提交代码的时候build这个job还执行呢?
on mac_runner (de7cbe25)
Using Shell executor...
Running on xxxxxMacBook-Pro.local...
Cloning repository...
Cloning into '/Users/xxxxxxx/builds/de7cbe25/0/xxxx/xxxxxxx-iOS'...
fatal: unable to access 'http://gitlab-ci-token:xxxxxxxxxxxxxxxxxxxx@localhost:8088/xxxx/xxxxx-iOS.git/': Failed to connect to localhost port 8088: Connection refused
ERROR: Job failed: exit status 1
楼主 CI一致报这个错 怎么搞
gitlab ci这台机器是单独另外一台机器,还是就在代码所在本机,如果不是在本机,那么在push的时候自动构建,另外一台机器需要先拉取代码 才能构建吧。
楼主也来体验一下 flow.ci 的 iOS 持续集成;
https://flow.ci
stages:
- build
build_project:
stage: build
script:
- xcodebuild clean -workspace ShowStart_3.0.xcworkspace -scheme ShowStart_3.0
- xcodebuild build -workspace ShowStart_3.0.xcworkspace -scheme ShowStart_3.0
这是我的yml 文件 pip 哪里看到 一直在转圈