layout: post
title: "iOS项目使用GitLab的CI"
description: "Gitlab自带CI,文章主要讲解如何在gitlab上使用iOS的CI"
tag: swift,CI, iOS
[TOC]
这篇文章大部分来自谷歌翻译!我只是让他更通顺并加上自己构建中遇到问题的解决方法。文中图片和配置
以下是正文
在本文中,我将逐步向您展示如何为您的iOS项目设置GitLab CI。
为什么选择CI?
持续集成(CI)是帮助开发人员提高生产力和编写更高质量代码的绝佳工具。通过在每次提交时自动运行一套测试,每个人都可以看到对代码库所做更改的结果,并采取措施使集成变得更快,更容易。
GitLab 免费为所有项目内置CI。
有关CI的最佳实践,工作流以及优缺点的详细信息超出了本教程的范围。简而言之,为Xcode项目启用它时,会发生以下情况:
- 您对代码库的副本进行更改,然后将提交推送到GitLab。
- GitLab识别出代码库已更改。
- GitLab使用您在Mac上为该项目设置的GitLab Runner触发构建。
- GitLab Runner运行您在中指定的构建和测试过程.gitlab-ci.yml。
- GitLab Runner将其结果报告回GitLab。
- GitLab向您显示构建结果。
这篇文章建立在Jeremy White的博客文章的基础上,进一步介绍了一些细节,并针对下一部分中描述的环境纠正了一些步骤。
假设与环境
这篇文章将提供从头到尾为您的iOS项目设置GitLab CI的分步指南。但是,首先,我们需要做一些假设。
GitLab's strategy document取决于一个关键思想:每个人都可以做出贡献。因此,本文是为几乎所有经验水平的读者编写的。但是,鉴于CI是一个相对高级的主题,我们将假设您具有一些有关如何创建Xcode和GitLab项目的基本知识,以及对Terminal和git的一些熟悉。
撰写本文时考虑了以下开发环境:
- 运行OS X 10.11.3 El Capitan的Mac
- 带有命令行工具的Xcode 7.2.1和已安装的iOS 9.2 SDK
- GitLab.com v8.5
我们还将假设您已经创建了一个新的GitLab项目。如果还没有,请立即执行。
设置您的Xcode项目
我们将从在Xcode中创建一个新的单视图iOS项目开始。
创建一个新的Xcode项目。
<img src="/images/iOSCI/1.png" alt="image">
为您的项目命名,并确保为该项目启用了“Include Unit Tests”和“Include UI Tests”选项。Xcode将创建带有一些示例测试的模板测试类,在本文中我们将使用它们作为GitLab CI运行以验证构建的测试套件。为您的项目选择一个名称,然后单击Next。
<img src="/images/iOSCI/2.png" alt="image">
在项目中启用单元和UI测试
选择保存iOS项目的位置。如果愿意,让Xcode在Mac上创建git存储库。
<img src="/images/iOSCI/3.png" alt="image">
Xcode创建并打开您的iOS项目后,您需要共享schemes。苹果的文档很好地定义了schemes:
方案是设置的集合,这些设置指定启动目标指定的产品时要构建的目标,要使用的构建配置以及要使用的可执行环境。
通过共享您的方案,GitLab CI获得了构建和测试项目所需的上下文。
要在Xcode中共享方案,请选择Product > Scheme > Manage Schemes
<img src="/images/iOSCI/4.png" alt="image">
单击关闭按钮。
您的Xcode项目已使用两个测试文件创建;一个包含样本单元测试,另一个包含样本UI测试。您可以运行Product > Test 来运行这些测试,这将构建您的项目,启动模拟器,在Simulator设备上安装项目,然后运行测试套件。您可以在Xcode中直接看到结果:
<img src="/images/iOSCI/5.png" alt="image">
测试功能旁边的绿色复选标记(在文件中和在“测试”导航器中)均表示所有测试均已通过。我们将不再引用Xcode项目,因此,如果您愿意,可以将其关闭。
接下来,打开终端并导航到为iOS项目创建的文件夹。
添加标准.gitignore文件很方便。对于Swift项目,输入:
$ curl -o .gitignore https://www.gitignore.io/api/swift
对于Objective-C项目,输入:
$ curl -o .gitignore https://www.gitignore.io/api/objective-c
curl命令可方便地将给定gitignore.io 的URL下的页面内容下载到名为.gitignore的文件中。
如果Xcode为您初始化了git存储库,则需要将原始网址设置为您的GitLab项目(用<username>您的GitLab用户名和<project>项目名称替换):
$ git remote add origin git@gitlab.com:<username>/<project>.git
这里的最后一步是安装xcpretty。当Xcode构建和测试您的项目时,xcpretty会将输出转换为您更易读的内容。
安装和注册GitLab Runner
GitLab Runner是Mac上安装的一项服务,它运行您在配置文件中设置的构建和测试过程。您可以按照OS X的安装说明进行操作,但是我们需要对注册运行程序步骤进行一些更改:
这里也可以按照这里的配置来安装
$ gitlab-ci-multi-runner register
WARNING: Running in user-mode.
WARNING: The user-mode requires you to manually start builds processing:
WARNING: $ gitlab-runner run
WARNING: Use sudo for system-mode:
WARNING: $ sudo gitlab-runner...
如果您使用的是自托管的GitLab,则协调器URL将为http(s)://url-of-your-gitlab-instance/ci。
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci):
https://gitlab.com/ci
您的项目的CI令牌可在GitLab的“项目设置”页面上的Advanced Settings下找到。每个项目都有一个唯一的令牌。
Please enter the gitlab-ci token for this runner:
<CI runner token from Project > Settings > Runner>
该register过程会建议您使用Mac的名称作为Runner的描述。您可以根据需要输入其他内容,也可以按回车键继续。
Please enter the gitlab-ci description for this runner:
[Your-Mac's-Name.local]:
输入您想要的标签,以进一步识别该特定Runner。当您需要特定的构建环境时,它特别有用.例如,iOS9.2,Xcode 7.2,OS X 10.11可以使用标签ios_9-2,xcode_7-2和osx_10-11。这样,我们可以通过工具链,平台等在GitLab中过滤构建阶段。
Please enter the gitlab-ci tags for this runner (comma separated):
ios_9-2, xcode_7-2, osx_10-11
GitLab运行程序将注册运行程序并为其提供唯一的runnerID。
Registering runner... succeeded runner=s8Bgtktb
GitLab Runner必须运行xcodebuild才能构建和测试项目,因此我们选择shell作为执行者:
Please enter the executor: virtualbox, ssh, shell, parallels, docker, docker-ssh:
shell
Runner registered successfully. Feel free to start it, but if it's running
already the config should be automatically reloaded!
根据文档,继续执行Runner安装说明的其余部分(install和start)。
转到“ 项目设置”中的“ Runner”页面,然后:
<img src="/images/iOSCI/6.png" alt="image">
GitLab Runner在GitLab的项目设置中得到认可。
您的GitLab Runner已被识别,并且(几乎)已准备就绪!
您可以通过运行来验证
$ gitlab-ci-multi-runner verify
WARNING: Running in user-mode.
WARNING: The user-mode requires you to manually start builds processing:
WARNING: $ gitlab-runner run
WARNING: Use sudo for system-mode:
WARNING: $ sudo gitlab-runner...
Veryfing runner... is alive runner=25c780b3
请注意,它们具有相同的ID(在本例中为25c780b3)。
最后要做的是配置构建和测试设置。为此,打开您的文本编辑器并输入以下内容:
stages:
- build
build_project:
stage: build
script:
- xcodebuild clean -project ProjectName.xcodeproj -scheme SchemeName | xcpretty
- xcodebuild test -project ProjectName.xcodeproj -scheme SchemeName -destination 'platform=iOS Simulator,name=iPhone 6s,OS=9.2' | xcpretty -s
tags:
- ios_9-2
- xcode_7-2
- osx_10-11
将此文件保存为Xcode项目文件夹中的.gitlab-ci.yml,不要忘记文件名开头的句点!
更新:为明确起见,该.gitlab-ci.yml文件应放入您为iOS项目创建的文件夹中,该文件夹通常也位于Xcode项目文件(ProjectName.xcodeproj)所在的位置。感谢评论员Palo指出这一点!
这个名字其实是可以自定义名字和位置的
<img src="/images/iOSCI/7.png" alt="image">
当然,如果你这样放的话,实际执行的时候,GitLab到响应位置(图示为Sources/.gitlab-ci.yml)找到yml文件,然后在最外层文件夹找xx.xcodeproj文件,当然是找不到的。所以你要在script里面指定到响应文件夹
... stage: build
script:
- cd Sources
- xcodebuild clean -project CIDemo.xcodeproj -scheme CIDemo | xcpretty
...
让我们详细了解一下该文件:
- 该文件首先描述了stages每个文件可用的文件job。为简单起见,我们有一个阶段(build)和一个工作(build_project)。
- 该文件为每个文件提供设置job。该build_project作业运行两个脚本:一个用于清理Xcode项目,然后另一个用于构建和测试它。您可能可以跳过清理脚本以节省时间,除非您要确保从清理状态开始构建。
- 在tags下方,添加您注册GitLab Runner时创建的标签。
还有一些注意事项:
- 确保将所有引用替换ProjectName为您的Xcode项目的名称;如果您使用的方案与默认方案不同,请确保您SchemeName也输入正确的方案(默认方案与相同ProjectName)。
- 在xcodebuild test命令中,请注意,该-destination选项已设置为在Simulator中启动运行iOS 9.2的iPhone 6S图像;如果您要运行其他设备(例如iPad),则需要进行更改。
- 如果您使用的是工作区而不是项目(例如,因为您的应用程序使用Cocoapods),请将-project ProjectName.xcodeproj 选项更改为-workspace WorkspaceName.xcworkspace。xcodebuild有多种选项可用于自定义构建。在终端中运行xcodebuild --help以进一步探索这些内容。
- 关于tags,需要保证Runner的标签和.gitlab-ci.yml文件内的标签一致,否则Gitlab会找不到特定的Runner导致无法执行。
GitLab提供了一个简单的工具可以“整理”(或者验证).gitlab-ci.yml文件。在您的GitLab项目页面上,单击侧边栏中的Builds,然后在右上角单击CI Lint:
<img src="/images/iOSCI/8.png" alt="image">
将.gitlab-ci.yml文件内容粘贴到文本框中,然后单击Validate。您应该看到类似以下内容:
Status: syntax is correct
这不会告诉您项目名称或所选的模拟器是否正确,因此请务必仔细检查这些设置。
该.gitlab-ci.yml文件是高度可定制的。您可以将作业限制为成功或失败,也可以根据分支或标签来决定是否构建,你可以阅读管饭文档以了解其灵活性和强大性。
设置CI的GitLab项目
实际上,这里实际上没有什么可做的!默认情况下,在新项目上启用CI。如果您的iOS项目中有一些环境变量需要保密,但您想在GitLab上将该项目保持公开状态,则可以在项目设置 > Continuous Integration”中禁用Public builds。这将隐藏除项目成员以外的所有人的构建结果。
你可能想在你的项目设置中找到Runner,然后点击Disable shared runners,但是这是不对的——因为我们使用的是特定于项目的Runner。
我们现在准备触发CI构建!
如何触发构建
要触发构建,您所要做的就是将提交推送到GitLab。从终端:
$ git add .
$ git commit -m "First commit."
[...commit info...]
$ git push origin master
[...push info...]
如果一切正常,并且您在同一台计算机上安装了GitLab Runner,您会注意到Simulator启动,安装iOS应用并启动,然后返回主屏幕。
转到您的GitLab项目的Builds页面,然后查看结果!
<img src="/images/iOSCI/9.png" alt="image">
单击<span style = color:green>✔︎ success</ span>按钮以查看构建输出:
<img src="/images/iOSCI/10.png" alt="image">
在这里,您
将看到.gitlab-ci.yml 文件中请求的所有步骤的输出。在日志的底部,您应该看到类似以下内容:
All tests
Test Suite GitLab-CI-for-iOSTests.xctest started
GitLab_CI_for_iOSTests
. testExample (0.001 seconds)
T testPerformanceExample measured (0.000 seconds)
. testPerformanceExample (0.324 seconds)
Executed 2 tests, with 0 failures (0 unexpected) in 0.325 (0.328) seconds
All tests
Test Suite GitLab-CI-for-iOSUITests.xctest started
GitLab_CI_for_iOSUITests
. testExample (3.587 seconds)
Executed 1 test, with 0 failures (0 unexpected) in 3.587 (3.589) seconds
Build succeeded.
现在,您可以继续为代码编写测试,每次您提交提交时,GitLab都会勤奋地获取项目,清理项目,然后进行构建和测试。如果构建失败,则可以采取措施来修复提交。
在Mac上启动和停止Runner
GitLab Runner包含几个方便的命令,您可以轻松列出这些命令:
$ gitlab-ci-multi-runner --help
NAME:
gitlab-ci-multi-runner - a GitLab Runner
USAGE:
gitlab-ci-multi-runner [global options] command [command options] [arguments...]
VERSION:
1.0.4 (014aa8c)
AUTHOR(S):
Kamil Trzciński <ayufan@ayufan.eu>
COMMANDS:
archive find and archive files (internal)
artifacts upload build artifacts (internal)
extract extract files from an archive (internal)
exec execute a build locally
list List all configured runners
run run multi runner service
register register a new runner
install install service
uninstall uninstall service
start start service
stop stop service
restart restart service
status get status of a service
run-single start single runner
unregister unregister specific runner
verify verify all registered runners
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--debug debug mode [$DEBUG]
--log-level, -l "info" Log level (options: debug, info, warn, error, fatal, panic)
--help, -h show help
--version, -v print the version
您可能要停止Runner,以便不会因推送的提交立即触发构建:
$ gitlab-ci-multi-runner stop
$ gitlab-ci-multi-runner status
gitlab-runner: Service is not running.
在这种情况下,任何推送的构建都将显示为pending,并在重新启动Runner后立即触发:
$ gitlab-ci-multi-runner start
$ gitlab-ci-multi-runner status
gitlab-runner: Service is running!
这将触发队列中任何pending状态的构建,然后启动Simulator并正常运行测试套件。
其他一些可能用到的
gitlab-ci-multi-runner这个命令太长了,你可以在.zshrc中配置一个别名
# GitLab-Runner
alias glr="gitlab-ci-multi-runner"
别忘了使用source ~/.zshrc来更新配置
使用的时候就可以这样:
$ glr start
常用命令:
列出当前所有注册的机器
$ glr list
Listing configured runners ConfigFile=/Users/bmac/.gitlab-runner/config.toml
iOSCIDemo Executor=shell Token=562a7c02cb6849942c2cb022fde03e URL=http://172.16.5.31/
register命令可以将你的电脑注册到Gitlab网站上,正如上文提到的。
unregister命令可以移除当前电脑上已经注册的机器,需要指定需要移除的token和url。-t是--token的简写,-u是--url的简写。
glr unregister -t a60d3845daf5b02fa8833cae68a858 -u http://172.16.5.31/
还有一种情况:如果你在Gitlab上删除了这个Runner,但是电脑上没有删除,然后你再运行unregister命令,你会收到这个提示:
$ glr unregister -t auxdVqH4ysV6gSDAsz3K -u https://gitlab.com/
WARNING: Running in user-mode.
WARNING: Use sudo for system-mode:
WARNING: $ sudo gitlab-runner...
ERROR: Unregistering runner from GitLab forbidden runner=auxdVqH4
FATAL: Failed to unregister runner
这是因为网站上已经找不到这个Runner,所以无法删除,这时候你需要使用
$ glr verify --delete -t auxdVqH4ysV6gSDAsz3K -u https://gitlab.com/
WARNING: Running in user-mode.
WARNING: Use sudo for system-mode:
WARNING: $ sudo gitlab-runner...
ERROR: Verifying runner... is removed runner=auxdVqH4
Updated /Users/bmac/.gitlab-runner/config.toml
重启所有Runner
$ glr restart
运行一个Runner
$ glr run-single ...
强制关闭所有Runner
$ sudo killall -SIGHUP gitlab-ci-multi-runner
高级:自动归档项目
假设,如果我们提交到master分支,我们希望GitLab CI不仅可以构建和测试项目,而且还可以具备一些连续交付的能力,在那里它创建了一个应用程序归档,并将其上传到GitLab。
我们首先修改.gitlab-ci.yml文件以添加archive阶段和archive_project工作:
stages:
- build
- archive
build_project:
stage: build
script:
- xcodebuild clean -project ProjectName.xcodeproj -scheme SchemeName | xcpretty
- xcodebuild test -project ProjectName.xcodeproj -scheme SchemeName -destination 'platform=iOS Simulator,name=iPhone 6s,OS=9.2' | xcpretty -s
tags:
- ios_9-2
- xcode_7-2
- osx_10-11
archive_project:
stage: archive
script:
- xcodebuild clean archive -archivePath build/ProjectName -scheme SchemeName
- xcodebuild -exportArchive -exportFormat ipa -archivePath "build/ProjectName.xcarchive" -exportPath "build/ProjectName.ipa" -exportProvisioningProfile "ProvisioningProfileName"
only:
- master
artifacts:
paths:
- build/ProjectName.ipa
tags:
- ios_9-2
- xcode_7-2
- osx_10-11
该archive_project作业运行两个脚本:第一个脚本清理并存档Xcode项目,第二个脚本构建.ipa文件。上面脚本里的only设置意味着该作业仅在我们提交到master分支的时候才运行。注意,它也定义了artifacts,在创建ProjectName.ipa存档后,此选项会将其上传到GitLab,您以后可以在Build页面中下载它。
在archive_project作业的exportArchive脚本中,确保您传递正确的ProvisioningProfileName。如果您的developer keys位于登录钥匙串中,archive_project这一步骤还是可能会失败,因为没有在脚本中解锁。无需在脚本中输入密码即可解决此问题的最简单方法是在Mac上打开“钥匙串访问”并将其拖放到“系统钥匙串”中。😷
现在,当我们提交代码到master分支时,该构建还将向我们显示归档后的结果,以及下载或浏览构建工件的选项!
<img src="/images/iOSCI/11.png" alt="image">
其他要点
- 此工作流程适用于任何类型的Xcode项目,包括tvOS,watchOS和Mac OSX。只需确保在.gitlab-ci.yml文件中指定适当的Simulator设备即可。
- 如果要推送提交但不想触发CI构建,只需将其添加[ci skip]到提交消息中即可。
- 如果安装了GitLab运行程序的用户未登录,则Runner将不会运行。因此,如果pending状态时间过长,您可能需要检查一下配置!
- 如果您在团队中工作,或者您的项目是公开的,则可能需要在专用的构建机器上安装GitLab Runner。
此特定教程中使用的测试项目可在这里下载,但是项目带的Runner已经没有了。如果在构建输出中看到证书文件错误,则可能需要向.gitlab-ci.yml文件的脚本中添加一些参数。