iOS与Xcode Server的持续集成说明

本文概述

  • 介绍
  • 设置Xcode服务器
  • 自动化应用分发
  • Xcode服务器分发
  • Xcode服务器自动应用测试
  • 本文总结
介绍 在Xcode 9之前, 使用Apple持续集成工具是一个繁琐而复杂的过程, 需要购买和安装其他macOS Server应用程序。这导致许多开发人员放弃了对其iOS项目进行持续集成或求助于第三方解决方案的想法, 但成功的程度却大不相同。
但是, 2017年9月发布Xcode 9.0之后, 该过程得到了极大简化, 包括自动代码签名选项, 现在已完全集成到Xcode中。因此, 它不需要任何其他应用程序或工具。
尽管第三方解决方案(如Fastlane, Bluepill等)很有帮助, 可以为你做很多艰苦的工作, 但本文将探讨仅使用Xcode和Apple工具来满足持续集成需求的功能。我们还将使用手动代码签名, 因为这通常对于很多人来说都是个问题, 并且在涉及多个构建配置时, 自动签名也不是最佳的解决方案。
注意:本文基于Xcode 9.4.1, 着重于iOS应用程序开发, 但其中很多内容适用于Xcode 10(当前以beta 5版本提供)和macOS应用程序开发。
设置Xcode服务器 除了简化实际的集成过程外, Xcode 9还简化了Xcode Server的设置过程。
在已指定为CI服务器的macOS机器上启动Xcode应用程序, 然后打开” 首选项” 。
导航到最后一个选项卡, 称为” 服务器和机器人” 。
iOS与Xcode Server的持续集成说明

文章图片
通过单击右上角的开关来打开Xcode Server功能。然后, 系统会要求你选择一个用户, 以在此计算机上运行和执行构建脚本。为此, 最好有一个专门的用户, 而不要使用现有的用户。
请注意, 该用户必须登录系统才能运行任何Xcode机器人。登录后, 你应该在用户名旁边看到一个绿色圆圈。
iOS与Xcode Server的持续集成说明

文章图片
而已!让我们仔细看看Xcode机器人。
如何配置Xcode机器人
现在, 你可以开始配置Xcode机器人以在该服务器上运行。这可以在与服务器连接到同一网络的任何开发机上完成。
在开发计算机上打开Xcode, 然后从顶部菜单中单击Xco??de> 首选项。然后, 转到” 帐户” 标签, 然后单击左下角的+图标。从出现的对话框中选择Xcode Server。
iOS与Xcode Server的持续集成说明

文章图片
【iOS与Xcode Server的持续集成说明】要创建机器人, 只需在Xcode中打开项目, 然后从顶部菜单中选择” 产品” > ” 创建机器人” 。漫游器设置包含许多步骤, 我们将在接下来的部分中进行探索。
自动化应用分发 iOS应用程序构建自动化中最常见的应用程序之一是配置一个机器人, 以将应用程序上载到iOS发行平台, 例如TestFlight, Fabric等。
如前所述, 本文将仅探讨上传到App Store Connect以及直接从Xcode Server下载的方法, 因为这些都是Apple的iOS应用分发工具。
使用Xcode的App Store Connect分发
在配置漫游器之前, 请确保你具有与应用程序开发项目的捆绑包ID匹配的App Store Connect应用程序记录。还值得注意的是, 每个构建都需要具有由构建版本和构建编号组成的唯一标识符。稍后讨论Xcode机器人设置时, 我们将探讨如何确保满足这些条件。
步骤1:设置正确的构建配置是获得所需内容的关键步骤。确保选择要生成要上传到App Store Connect的应用程序的方案和配置。这包括确保构建配置使用在团队的Apple Developer门户(用于代码签名)和App Store Connect门户(用于自动上传应用程序)中注册的适当捆绑软件ID。 。
步骤2:在” 配置” 标签上的同时, 我们需要指定导出选项。我们将探索导出选项属性列表, 因此请确保已选择” 使用自定义导出选项Plist” 。
步骤3:现在是我们制作导出选项属性列表的时候了。如果你输入xcodebuild – help, 则可以获得此文件中要使用的密钥的完整列表, 但是我们将在此处探索此机器人配置中使用的密钥:
  • compileBitcode –位代码是Apple的应用程序源代码的临时输出格式。换句话说, 它是你的源代码在转换为特定体系结构的机器代码之前进行转换的格式。它旨在拥有一个单一的代码容器, 如果在指令集中进行了优化, 则可以进一步优化它, 并且还能够将其从相同的格式编译为将来的体系结构。但是, 这对你的应用程序没有任何影响。由你决定是否要启用它。
  • 方法–此参数指定你要导出的产品类型。 Apple通过指定的受众来区分产品-_development_仅允许你将其安装在供应配置文件中指定的设备上, 企业允许所有人安装它, 但是他们需要在运行该应用之前明确信任该开发配置文件, 并且应用商店适用于将其分发到App Store或App Store Connect, 因此我们将使用此值。
  • ProvisioningProfiles –这是不言自明的。但是这里有两点需要注意:导出选项属性列表中的供应配置文件是一个字典, 其中的键对应于产品的包ID, 值对应于用于对其进行代码签名的供应配置文件的名称。
  • signingCertificate –另一个不言自明的论点。该字段的值可以是完整的证书名称或SHA-1哈希。
  • teamID –另一个不言自明的论点。这是你注册Apple Developer程序时Apple颁发给你的组织的10个字符的长标识符。
  • uploadBitcode –是否上传位码(如果你选择编译成位码), 以便可以在AppStore Connect中使用它生成新的优化版本或为将来的体系结构而构建。
  • uploadSymbols –上载调试符号, 以便你可以获得有意义的崩溃报告, 而不仅仅是内存转储和程序集堆栈。
因此, 现在, 你的导出选项属性列表可能如下所示:
< ?xml version="1.0" encoding="UTF-8"?> < !DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> < plist version="1.0"> < dict> < key> compileBitcode< /key> < false/> < key> method< /key> < string> app-store< /string> < key> provisioningProfiles< /key> < dict> < key> com.bundle.id< /key> < string> ProvisioningProfileName< /string> < /dict> < key> signingCertificate< /key> < string> Signing Certificate Exact Name or SHA-1 hash value< /string> < key> teamID< /key> < string> ??????????< /string> < key> uploadBitcode< /key> < false/> < key> uploadSymbols< /key> < true/> < /dict> < /plist>

步骤4:选择你创建的.plist作为导出选项属性列表。
步骤5:接下来是” 时间表” 标签-根据你的喜好进行设置。
步骤6:在” 签名” 选项卡上, 确保你取消选中” 允许Xcode Server管理我的证书和配置文件” 选项, 并在” 证书和配置文件” 页面上自己上载匹配的签名证书和配置文件。
第7步:应该保留” 设备” 标签, 因为我们要上传应用程序而不是对其进行测试。
步骤8:” Arguments” 选项卡允许你显式设置xcodebuild自变量或环境变量, 这些变量或环境变量可在构建或集成前和集成后脚本中使用。
步骤9:最后, 我们到达Triggers选项卡, 这也是配置Xcode持续集成bot的最后一个选项卡。这是Xcode服务器库中功能最强大的工具。首先, 我想添加以下两个命令作为预集成脚本:
#!/bin/sh set printenv

第一个打印在当前集成运行中Xcode Server使用的所有变量及其值。第二个打印所有环境变量及其值。正如预期的那样, 这可能有助于调试脚本, 因此我将其适当地命名为” 调试信息” 。
请记住, 我们提到我们需要确保上传到App Store Connect的每个版本都必须具有唯一的版本和版本号对。我们可以使用内置的PlistBuddy工具, 但我们还需要一种具有唯一内部版本号的方法。在Xcode Server集成过程中始终存在的一件事(也是方便唯一)是集成号, 因为它是自动递增的。我们将创建另一个集成前脚本, 名为” 设置内部版本号” , 其中包含以下内容, 以确保每次都有唯一的内部版本号:
#!/bin/sh buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}") buildNumber=$XCS_INTEGRATION_NUMBER /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"

如果你使用的是CocoaPods, 并且选择不将Pods目录提交到DVCS, 则还应包括一个具有以下内容的预集成脚本:
#!/bin/sh cd $XCS_PRIMARY_REPO_DIR pod install

第10步:我们快完成了, 但是我们还没有指定要将该版本上传到AppStore Connect或哪个帐户的任何位置。为此, 我们将添加集成后脚本和另一个名为Application Loader的内置工具。将以下内容放入脚本中:
#!/bin/sh /Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Support/altool --upload-app -f $XCS_PRODUCT -u $TESTFLIGHT_USERNAME -p $TESTFLIGHT_PASSWORD

$ XCS_PRODUCT是一个Xcode Server变量, 它包含当前集成运行中创建的应用程序的路径。但是, $ TESTFLIGHT_USERNAME和$ TESTFLIGHT_PASSWORD既不是系统变量, 也不是Xcode Server变量。这些必须由你设置, 并具有Apple ID和密码的值。不幸的是, Apple不再支持为AppStore Connect构建上传生成API密钥。由于这是机密信息, 因此, 最佳做法是直接在Mac服务器上(假设是你自己的)将其设置为环境变量, 而不是在Xcode Server机器人配置中进行设置。
Xcode服务器分发 实际上, Xcode Server分发漫游器使用与App Store Connect分发相同的配置, 但后期集成脚本除外。但是, 下载并安装应用程序仍然很棘手。你仍然必须确保与你的应用进行签名的配置配置文件允许将该应用安装在你使用的设备上。
设置好之后, 你将需要在iOS设备上打开Safari并导航到服务器的Xcode Server Web仪表板。例如, 如果你的服务器名称为” Mac服务器” , 并且与服务器位于同一网络上, 则可以在” mac-server-name.local / xcode” 中找到它。在这里, 你会找到所有Xcode机器人的列表及其最新集成的统计信息。
选择已构建你要下载的应用程序的应用程序。在以下屏幕上, 你将有两个按钮-安装和配置文件。如果这是你首次从该服务器下载文件, 则必须单击” 配置文件” 以将其证书添加到可信来源列表中。然后, 单击同一页面上的” 安装” 按钮, 将出现iOS确认对话框, “ 你确定要在设备上安装*吗?” 通过单击” 是” 进行确认, 你的应用程序将在主屏幕上安装并运行。
iOS与Xcode Server的持续集成说明

文章图片
对于iOS 10.3及更高版本, 其可能因” 无法连接到* .local” 而失败的原因是, 必须在测试设备的” 设置” 中手动信任自签名证书。
跟着这些步骤:
第1步:从iPhone上Xcode服务器的bots页面安装自签名证书。
第2步:转到iPhone的设置> 常规> 关于> 证书信任设置。
第3步:在” 启用对根证书的完全信任” 部分下找到服务器的自签名证书, 然后将开关打开。
步骤4:返回Xcode Server上的bot集成页面, 单击Install。
Xcode服务器自动应用测试 Xcode Server的另一个重要用途是自动应用程序测试, 无论是单元测试还是UI测试。为此, 你需要为项目设置适当的目标。也就是说, 根据你的目标, 你需要有一个可以运行单元或UI测试的目标。
设置过程与上一个过程相同, 但是我们将选择不同的选项。第一个主要区别是在” 配置” 选项卡中。显然, 我们要选中” 分析” 和” 测试” 框, 因为这是我们的主要目标。我也建议你不要使用此漫游器进行存档或导出产品。使用相同的漫游器配置可以实现测试和分发。但是, 这两种方案的输出和时间表不同。分发通常在周期结束时运行。
无论你是在Scrum还是Kanban或其他框架中工作, 都应该有一个预定义的时间驱动或事件驱动的周期, 最后应已导出并使用了产品。另一方面, 你应该在每次提交时都运行测试机器人, 因为这是抵御回归的第一道防线。由于测试机器人的运行频率显然更高, 因此将这两个机器人合并为一个机器人可能会很快耗尽服务器上的磁盘空间。而且, 每个集成都需要更多时间才能完成。
有了这一点, 我们将转到” 时间表” 标签, 我们已经在上一段中解决了这一问题。因此, 下一个感兴趣的主题是代码签名。请注意, 即使你的测试目标可能在项目设置页面中指出不需要配置文件, 也应将其设置为使用与主机应用程序相同的团队和签名证书。如果你想在iOS设备上而不是仅在模拟器上测试应用程序, 则必须执行此操作。如果是这种情况, 你还需要确保用于测试的iOS设备不会由于不活动而被锁定, 因为这可能会导致集成运行无限期挂起而不会通知你。
现在, 我们在” 设备” 标签上, 不需要具体说明。只需选择要用于测试代码的一个, 多个或所有设备(iOS和模拟器)。你还可以检查是否在多个设备上并行或顺序运行测试。要进行此设置, 你应该考虑项目的需求(无论是针对特定的一组设备还是所有受支持的iOS设备), 以及服务器的硬件资源。
在参数选项卡上。无需明确指定任何内容, 因为我们只会使用内置的环境变量。
最后, 在” 触发器” 标签上, 我们将介绍一种集成前脚本和一种集成后脚本。第一个只是为了帮助我们进行调试, 以防遇到一些问题。实际上, 这是我们已经使用的一种:
#!/bin/sh set printenv

第二个是在当前集成中一项或多项测试失败时将通知我们的通知。确保将其设置为仅在测试失败时运行。并输入以下内容:
#!/bin/sh echo "$XCS_TEST_FAILURE_COUNT test(s) failed for $XCS_BOT_NAME bot on build $XCS_INTEGRATION_NUMBER" echo "You can see bot integration at:" echo "https://$HOSTNAME/xcode/bots/$XCS_BOT_TINY_ID/integrations/$XCS_INTEGRATION_TINY_ID"

这里有几件事需要解释。首先, $ HOSTNAME变量存储以下格式的值:computer-name.local。显然, 仅当你可以通过本地网络访问该服务器时, 链接才起作用。另外, 访问此链接时, 你很可能会从浏览器收到安全警告, 因为它是与无法信任的目标的https连接。最后, 这只是” 测试失败” 脚本的起点。你可以向整个开发团队发送电子邮件, 也可以通过API请求或你认为最合适和最有效的其他方式来打开JIRA问题。
本文总结 希望本文鼓励你花时间探索Xcode Server功能, 而不仅仅是构建应用程序。尽管这篇文章可能并没有以你想要的或期望的方式完全为你提供帮助, 但目标是向你介绍一种使用内置环境和Xcode Server变量实现更高自动化水平的开明思路。
有很多第三方服务可以启用更多功能, 并可以为你做更多工作, 包括Fabric, Bluepill和Fastlane。但是, 不可避免地, 依赖第三方会给你的项目带来新的依赖性, 并且有时需要简单, 有时是复杂的设置和配置。这里描述的技术仅需要在每台Mac上已经安装的工具, 因此除了配置运行自动构建程序的机器人外, 它不需要设置时间!

    推荐阅读