企业持续交付YOOX NET-A-PORTER GROUP移动框架

在移动应用程序开发中,可靠的架构模式在更快地构建应用程序中起着重要作用。

因此,为了确保多个应用程序中现有代码的质量和可重复使用性,公司开始构建可重复使用的软件开发工具包(通常称为SDK)来开发移动应用程序。

对于iOS,Apple已经创建了无数SDK,供应用程序开发人员构建应用程序,但公司仍需要构建自己的自定义iOS SDK,以在其应用程序中共享产品特定的通用代码。

为了加快YOOX NET-A-PORTER GROUP(YNAP)的iOS应用开发速度,我们构建了通用的iOS库,这些库可以在NET-A-PORTER,MR PORTER,YOOX,THE OUTNET和30+以上的多个iOS应用之间共享我们为其经营数字商店的品牌。

主要的iOS SDK之一是我们的客户端应用程序与后端API之间的一层,在本文中,我们将其称为“ iOS-SDK”。

什么是iOS-SDK

YNAP在App Store上提供了许多iOS应用程序以及为我们的同事服务的许多其他企业应用程序。

我们希望为同事们反映客户的经验,同时减少重复编码。

为此,我们决定构建一个通用的iOS-SDK,以方便在我们的客户和企业应用程序之间共享。

这也使我们可以通过在方法和返回类型方面定义一组行为来简化构建过程。 然后,使用SDK的人只需为每个应用实现适配器。

这意味着iOS-SDK是iOS库的集合,可使用CocoaPods或Carthage轻松分发。

我们仅用Swift编写了该库,并且它具有一个内置的示例应用程序,可让我们测试特定于客户端的功能。

为什么我们需要iOS-SDK的持续集成和持续交付

由于iOS-SDK代码可能会影响多个客户端应用程序,因此必须确保iOS-SDK的代码质量满足所有受支持的应用程序的要求。

为此,定期运行可靠的自动化测试非常重要,以确保一个客户端的代码更改不会对其他客户端产生负面影响。

为此,我们需要持续集成(CI)来获取对iOS-SDK代码库所做的任何更改的即时反馈,并需要持续交付(CD)来相应地更新客户端应用程序。

通过将CI / CD添加到iOS-SDK,我们可以获得有关Swift代码更新的早期反馈,并定期在客户端应用中测试新功能。 为SDK实施CI / CD实践与对普通iOS应用同样重要。

我们开始通过构建自动化,自定义脚本和使用Travis CI功能在iOS-SDK库上实现CI / CD。 我们的iOS-SDK CI / CD火箭现已准备好发射。

iOS-SDK部署自动化

我们的iOS-SDK是一个Swift库,我们使用CocoaPods或Carthage分发它。 手动部署iOS-SDK库是一个耗时,重复(而且很无聊!)的过程。

以前,每当我们要发布新版本的iOS-SDK时,开发人员都需要经历手动过程。

我们需要克服这一点,并开始寻找可以执行以下操作的自动发布过程:

  • 当源代码在Master分支中合并后,会自动构建该库的新版本,运行所有自动化测试并自动使用PodfileCartfile提到的版本创建标签
  • 使用Github Changelog.md发行说明自动制作该库的Github版本
  • 将库的新版本推送到YNAP的专用Cocoapods存储库,以便我们可以从专用存储库下载规范
  • 在Slack频道上自动宣布该库的新版本

我们通过结合使用自定义脚本,Fastlane工具和Travis CI来实现这一目标。 在此过程中,几乎没有引入任何更改来帮助自动部署iOS-SDK。 iOS开发人员必须在每个.podspec文件中维护Changelog.md文件以获取发行说明和凹凸版本,以便部署脚本将读取此信息以实现发行自动化。

我们可以从.podspec文件中读取版本,并使用Fastlane在Github上创建一个自动标记。

  $ version_from_podspec = version_get_podspec(路径:“ iOS-SDK.podspec”) 
UI.message(“在github上使用#{$ version_from_podspec}创建标签!”)
add_git_tag(
标签:$ version_from_podspec

sh“ git push origin#{$ version_from_podspec}“

这将在Github上使用.podspec文件中提到的版本创建一个自动标记。 自动部署脚本会在Github上发布发行版。

  UI.message(“在Github上创建新版本”) 
set_github_release(
repository_name:“ YTech / iOS-SDK”,
api_token:ENV [“ GITHUB_TOKEN”],
名称:“ iOS-SDK” + $ version_from_podspec +“发行版”,
tag_name:$ version_from_podspec,
承诺:“主人”,
说明:release_notes,
is_prerelease:否

该脚本将在Github上发布发行版本,并附带发行说明。 一旦该版本在Github上发布,我们的客户端应用程序就可以通过将它们指向客户端应用程序的Cartfile中的特定版本,通过Carthage访问新的代码版本

但是,对于使用CocoaPods的客户,我们需要使用以下代码将库推送到YNAP的私有Cocoapods存储库:

  UI.message(“将Pod推送到YNAP CocoaPods Spec Repo”) 
all_pods.each做| uploading_pod |
pod_push(路径:“#{uploading_pod} .podspec”,存储库:“ YNAP-CocoaPods”)
结束

我们有一系列Pod,需要将其上载到私人CocoaPods存储库中。 该过程完成后,它将在我们的Slack频道上触发一条自动消息,如下所示:

客户端应用程序的自动企业分​​发

在我们的iOS-SDK的自动发布过程之后,下一步是启用客户端应用程序的CD,以确保新的功能可用于我们的质量检查工程师或产品所有者进行测试。

为了从Travis CI获得客户端iOS应用的CD,我们使用企业分发方法。 企业分发允许任何人只要信任企业帐户中的设置,就可以下载客户端iOS应用。

从Travis CI设置自动分发的过程需要大量的脚本和安全性配置。

Travis CI为每个构建创建新的VM,并在构建完成后销毁VM。 这可以为每个版本创建很多设置,包括加密和解密证书,创建密钥链,在密钥链中导入证书,下载预配置文件,然后列表继续……

幸运的是,Apple有一个安全的命令行工具,它使我们可以轻松处理所有这些任务,并且可以使用Fastlane工具轻松包装这些任务。

Travis CI的主要挑战是处理证书。 为了安全起见,我们已使用强大的加密密钥对证书进行了加密,并在Travis before_all步骤中将证书解密回p12格式。

  before_install: 
— chmod a + x ./fastlane/*.sh
— openssl aes-256-cbc -k $ ENCRYPTION_PASSWORD -in path_to / certificate.enc -d -a -out cerificate.p12

现在,我们在Travis VM上拥有了证书,我们可以使用Fastlane操作创建证书链并导入证书,将其添加到证书链中。

在钥匙串中获得证书后,我们可以执行进一步的代码签名活动,例如下载配置文件并对应用程序进行代码签名。

接下来,我们必须使用企业分发方法将应用程序存档,创建一个   .ipa文件,将其上传到Fabric进行Beta测试,最后向团队发送一条Slack消息,通知该应用程序的新版本已准备好进行测试。

我们从GitHub的最近10次提交中收集测试笔记,并将构建发送到特定的Crashlytics组。

  健身房( 
export_method:“企业”,
方案:“ iOS-SDK-Client”,
skip_profile_detection:是的,
配置:“发布”,
include_bitcode:否

crashlytics(
crashlytics_path:“ ./ Pods / Crashlytics /”,
api_token:ENV [“ CRASHLYTICS_API_KEY”],
build_secret:ENV [“ CRASHLYTICS_BUILD_SECRET”],
群组:“ iossdk测试人员”,
注意:get_crashlytics_release_notes(),
通知:true

这会将iOS-SDK客户端应用程序上载到Fabric,然后质量检查工程师和产品所有者将收到企业版本,以在其iOS设备上下载。

下载企业版本的过程与临时版本有所不同。 逐步指南可在此处找到。

定制Travis CI

因此,我们现在拥有iOS-SDK的完全自动化版本,以及iOS-SDK客户端应用程序的持续企业发行版。

最后一步是自定义Travis CI设置,这样我们就可以在不复制CocoaPods版本和企业应用程序分发的情况下获得构建矩阵功能的好处。

为此,我们需要在构建矩阵中设置一些环境变量,并编写一个自定义脚本来有条件地触发构建。

  矩阵: 
包括:
—环保:CI_IOS = '10 .2'CI_DEVICE ='iPhone 7'ARCHIVE = 1 POD_RELEASE = 1
—信封:CI_IOS = '11 .2'CI_DEVICE ='iPhone 6s'
—信封:CI_IOS = '11 .2'CI_DEVICE ='iPhone 8'

设置环境变量后,我们可以有条件地检查需要执行哪些脚本。

  如果[[“ $ BRANCH” ==“ master” &&“ $ POD_RELEASE” =“ 1” &&“ $ ARCHIVE” =“ 1”]];  然后 
echo“ ====为SDK制作Pod版本====”
捆绑执行Fastlane pod_release
捆绑exec fastlane destribute_enterprise_app
其他
回声“ =====执行正常构建=====”
捆绑exec fastlane ios默认
科幻

使用这种方法,我们可以避免创建iOS-SDK客户端应用程序的重复发行版和多个发行版。

如上面的构建矩阵所示,随着Travis创建发行并分发应用程序,第一次构建花费的时间最长。 后续构建花费的时间要少得多,因为它们是普通的iOS构建,并且复杂度也较低。

答对了! 我们已经发射了iOS-SDK CI / CD火箭。

下一步是什么?

尽管我们完全实现了发布和分发过程的自动化,但我们始终可以进行改进。 下一步:

  • 自动化其余部分,以实现Mobile SDK的一键式部署。 例如根据拉取请求标题自动创建发行说明
  • 自动向更广泛的业务交付SDK发行说明,突出显示已交付的主要功能
  • 在内部或在云上评估CI服务,具体取决于哪种更适合我们的移动开发流程

结论

CI / CD做法在iOS应用程序开发中可能被认为很重要,但是它们对于构建和维护iOS SDK至关重要。

SDK的代码质量要求更高,并且需要满足所有客户端iOS应用规范。

通过自定义脚本,Fastlane工具和Travis CI的组合,我们实现了iOS-SDK库的企业持续交付。

您的移动SDK是否具有CI / CD? 在下面的评论中分享您在移动SDK的CI / CD上的经验。 。

PS:非常感谢Luca D’Antona(移动工程经理)对本文的审阅,并在为移动框架设置CI / CD期间为我提供了支持。