缓存迦太基以加速iOS持续集成

几乎没有任何iOS项目没有任何依赖关系。 几乎每个项目都必须管理内部或第三方的某种依赖性。 每种主要的编程语言都有自己的依赖性管理系统。 Swift具有多种选项来管理依赖项。 苹果很久以来一直在开发自己的Swift Package Manager。 认真地讲,很久以来,iOS开发人员都渴望获得Apple支持的官方依赖项管理器,但事情似乎以乌龟的速度发展着。 Swift Package Manager仍然不支持iOS项目。 CocoaPods是iOS项目中最常用和最传统的依赖管理,因为开发人员没有其他选择。 CocoaPods是一种神奇的,不可思议的,超能力的魔咒,它使您的Xcode项目无法正常工作。 它建立依赖关系,创建工作区,执行一些脚本和其他东西。 CocoaPods运行良好,但是很少有开发人员了解运行pod install命令时发生的实际情况。 如果一切正常,每个人都会感到高兴,但是当pod安装失败时,每个人都会感到恐慌。 没有人知道如何解决该问题,需要花费数小时,数天或数周的时间才能解决由CocoaPods造成的混乱。 爱它还是恨它,无论哪种方式,您都必须使用它。

迦太基的诞生

Somone了解了iOS开发人员对CoacoPods的痛苦,并制作了一个名为Carthage的婴儿作为CocoaPods的替代品。 Carthage仅适用于动态框架,并且使开发人员能够完全控制他们对Xcode项目所做的工作。 它只是构建框架,开发人员必须手动将那些框架链接到目标的各个构建阶段。 迦太基运作良好,但缺点不多

  • 迦太基仅适用于动态框架
  • 迦太基的开发者社区很小,为该项目做出了贡献
  • 使用迦太基时涉及的手动步骤很少
  • 主要缺点是,它是如此缓慢,特别是在CI服务器上。 迦太基检出和构建每个构建的每个框架。 对于CI而言,这绝对不是一个很好的方法,因为构建速度将非常缓慢且冗长。 如果没有任何更改,则没有干净的解决方案来缓存Carthage /目录。 在这篇文章中,我们将看到如何在CI服务器上缓存Carthage目录并加快构建速度。

CI上的迦太基

迦太基最常见的用法是运行迦太基更新或脚本作为CI脚本的一部分,该脚本会修改所有依赖项以使用最新版本的Cartfile.lock文件更改,该更改不正确,并导致签出和构建所有依赖项。 这将使CI的构建速度非常慢。 因此在CI上使用迦太基的理想方法是

  • 检查Cartfile.lock是否存在。 如果该文件不存在,那么我们必须使用Carthage bootstrap引导所有依赖项。
  • 如果Cartfile.lock存在但未更改,则无需执行引导程序或更新操作,并且可以使用先前版本中Carthage目录中的内容。
  • 如果存在Cartfile.lock并更改了某些依赖关系,则我们仅需引导那些过时的依赖关系,而不是全部。

现在,我们知道了如何使用Cartfile.lock状态执行引导或跳过引导的机制。 下一步将是编写一个脚本来做到这一点。 根据CI服务器提供的环境变量,我们可以通过多种方式实现这一目标。 Jenkins使用的脚本如下所示

  [-f Cartfile.resolved]; 然后 
CARTFILE_CHANGED =`git diff --stat $(GIT_PREVIOUS_SUCCESSFUL_COMMIT)$(GIT_COMMIT)| grep'\ |' | awk'{print $$ 1}'| grep Cartfile.resolved`
如果测试“ $(CARTFILE_CHANGED)”; 然后
回声“##步骤:更新迦太基”
迦太基引导程序–平台iOS –无使用二进制文件
其他
回声“ ##迦太基是最新的”
科幻
其他
回声“##步骤:安装迦太基依赖项”
迦太基引导程序–平台iOS –无使用二进制文件
科幻

Jenkins GIT插件会设置该变量以比较Cartfile.lock的状态。 完整说明可以在此博客文章中找到。 有一个开源工具可以比较Cartfile.lock的状态,称为CartfileDiff,如果CI服务器没有特定的环境变量,该工具可用于确定Cartfile.lock中的更改。 我们将在后面的文章中看到如何使用CartfileDiff。

迦太基设置

在自托管的CI服务器上缓存Carthage /目录很容易,但是基于云的CI服务器会为每个构建版本启动新的虚拟机。 这使Carthage目录的缓存变得困难。 适用于iOS的大多数基于云的CI提供程序已经认识到此问题,并提供了缓存机制,例如Travis对大多数服务都有缓存。 可能还有其他CI服务,例如CircleCI可能在做同样的事情。 让我们看看如何在演示项目中使用TravisCI缓存服务。

让我们在Xcode中创建一个名为Carthage-CI的单视图项目,其中包括UI测试目标。 现在,我们将获得XCFit框架,该框架是我使用Carthage在iOS项目中为BDD编写的一个小型库。 创建Cartfile并添加

  github“ Shashikant86 / XCFit” 

现在运行,迦太基更新-iOS平台下载并构建所有依赖项。 作为构建阶段的一部分,根据Carthage文档,手动将构建的框架添加到UI Test目标中,然后拖放并运行Carthage脚本。 现在,我们在应用程序内部有了框架,是时候编写脚本以在CI上智能地使用Carthage了。 在项目中制作几个可执行文件

  $ mkdir脚本 
$ touch脚本/引导程序
$ touch脚本/智能引导
$ chmod + x脚本/引导程序
$ chmod + x脚本/智能引导

现在,我们已经创建了两个文件,在script / bootstrap脚本中,我们将运行carthage bootstrap,并将依赖项传递给该脚本。 脚本/智能引导脚本将神奇地确定Cartfile.lock状态。 在脚本/引导文件中,插入以下代码

  #!/ bin / bash 
 迦太基靴$ @ --platform iphoneos --no-use-binaries || 退出$? 

在此阶段,您可能需要按照CartfileDiff自述文件来安装CartfileDiff工具。 这将引导传递给该脚本的依赖项数量。 现在,在script / intelligent-bootstrap文件中插入此代码。

  #!/ bin / sh 
 SCRIPT_DIR = $(目录名“ $ 0”) 
BOOTSTRAP =“ $ SCRIPT_DIR / bootstrap”
CACHED_CARTFILE =“迦太基/Cartfile.resolved”
 如果[-e“ $ CACHED_CARTFILE”]; 然后 
OUTDATED_DEPENDENCIES = $(cartfilediff“ $ CACHED_CARTFILE” Cartfile.resolved)
 如果[!  -z“ $ OUTDATED_DEPENDENCIES”] 
然后
回声“引导程序过时的依赖项:$ OUTDATED_DEPENDENCIES”
“ $ BOOTSTRAP”“ $ OUTDATED_DEPENDENCIES”
其他
回声“ Cartfile.resolved匹配缓存,跳过引导程序”
科幻
其他
回声“找不到缓存的Cartfile.resolved,引导所有依赖项”
“ $ BOOTSTRAP”
科幻
  cp Cartfile.resolved迦太基 

该脚本将使用CartfileDiff工具来确定Cartfile.lock是否已更改,并相应地执行引导程序。 如果Cartfile.lock中没有任何更改,则将跳过引导步骤。

在TravisCI上缓存迦太基

到此为止,我们已经完成了用于确定Cartfile.lock文件状态的所有设置。 下一步是配置TravisCI以使用缓存的Carthage目录运行这些步骤。 在项目的根目录下创建一个.travis.yml文件,并插入以下代码。

  { 
“ language”:“ objective-c”,
“ osx_image”:“ xcode9”,
“缓存”:{
“目录”:[
“迦太基”
]
},
“ before_install”:[
“ curl -L -O https://github.com/Carthage/Carthage/releases/download/0.25.0/Carthage.pkg”,
“ sudo安装程序-pkg Carthage.pkg -target /”,
“ curl -L -O https://github.com/YPlan/CartfileDiff/releases/download/0.1/CartfileDiff.pkg”,
“ sudo安装程序-pkg CartfileDiff.pkg -target /”,
“ gem install fastlane --no-ri --no-rdoc --no-document”
],
“安装”:是的,
“脚本”:[
“脚本/智能引导”,
“ fastlane扫描-s迦太基-CI”
],
“ os”:“ osx”
}

注意,我们正在使用来自Carthage /目录的TravisCI的缓存。 我们还必须下载并安装CartfileDiff工具和Fastlane来运行方案Carthage-CI的测试。 现在,我们需要启用Travis上的项目以触发构建。

源代码和TravisCI Job

我已经在Github上创建了存储库,以演示我们之前所说的内容。 仓库是Carthage-CI,您可以在这里看到TravisCI作业。 查看下面的作业历史记录,由于缓存,最新的作业节省了将近3分钟。 由于XCFit是一个很小的库,因此,如果您有更大的库,则此方法将节省时间。

结论

使用CI服务器的缓存功能和智能策略执行Carthage引导程序,我们可以大大减少CI服务器上的构建时间。 您如何在CI上使用Carthage,您的经验是什么,请在下面随意评论。

像XCBlog的 XCTEQ 发布的帖子一样 您可能还喜欢我们的一些服务,例如访客博客或Mobile DevOps(CI / CD)或测试自动化。 Github 搜索我们的 服务 ,开源项目, 或者在 Twitter Facebook Youtube LinkedIn 上关注我们 下载我们的 XCBlog iOS应用程序以离线阅读博客。

X CTEQ 一家专门从事基于Mobile DevOps,CI / CD,Mobile,AI / ML的测试自动化Checkout XCTEQ产品和服务的公司, 网址 http://www.xcteq.co.uk 或写信给我们info@xcteq.co。英国..