fastlane与持续集成
fastlane init
如果Xcode升级到了最新版本,请执行sudo gem install fastlane
,确保安装最新版本的fastlane。
安装完成后,于项目根路径下执行fastlane init
以初始化项目的fastlane配置,按照提示输入Apple ID。
如果你开启了Two Factor Authentication,fastlane会要求你输入一串6位数字的验证码。看下你的iPhone,它会提示“您的Apple ID正用于在XX市,XX省附近的设备上登陆。“点击允许就会显示验证码。
fastlane会执行一些xcodebuild命令,有可能因超时而失败,默认的timeout是10秒,retry times是4次,一般只需要把timeout延长就好了,方法是添加环境变量FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT
,如export FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT=100
。
Appfile and Fastfile
执行fastlane init后,当前路径下会出现一个fastlane/,下面有两个配置文件,Appfile和Fastfile。
Appfile用于配置全局的App ID,Apple ID和Team ID。
使用fastlane最主要的工作在于配置Fastfile,它负责定义称为lane的fastlane任务。fastlane init为我们创建了一个已经可以使用的Fastfile模版。
before_all do # ENV["SLACK_URL"] = "https://hooks.slack.com/services/..." cocoapods # carthage end
before_all就是先于所有lane执行的任务,cocoapods默认是开启的,也就是每次执行fastlane任务都会先执行pod install。一般来说这并不是我们想要的,建议读者删除或注释掉这一行。
lane :test do scan end
test任务通过调用scan执行自动化测试。scan是fastlane工具箱中的一个工具,专门用于执行自动化测试。
lane :beta do # match(type: "appstore") # more information: https://codesigning.guide gym # Build your app - more options available pilot # sh "your_script.sh" # You can also use other beta testing services here (run `fastlane actions`) end
beta任务执行App的beta提测。gym和pilot是fastlane工具箱中的两个工具,分别执行打包和上传testflight。对于有不止一个scheme的项目,要为gym提供参数。
gym( scheme: "SegmentFault", export_method: "app-store", export_options: { provisioningProfiles: { "com.segmentfault.appid" => "ProvisioningProfileName", } } )
提测TestFlight就变成了敲一个fastlane beta
命令这么简单——其实也没那么简单,iTunes Connect会要求你登陆,可能还要做Two Factor Auth——下文会聊到如何连这个登陆的步骤都省略。
一般来说testflight测试是App上架App Store前最后阶段的测试,公司里还会有日常提测,多采用adhoc或enterprise方式。以enterprise为例。
lane :enterprise do gym(scheme: "SegmentFault", export_method: "enterprise") end
上面这个lane是Fastfile模版里没有的,需要我们自己添加。提测enterprise就是敲个fastlane enterprise
命令。
这里要注意的是,在执行fastlane enterprise
或fastlane beta
之前,要确保项目的code signing配置无误,enterprise和testflight的配置不一样,因而在二者间切换时要注意修改配置。
Fastfile模版还为我们提供了一个release任务,这个便是上传app store了。
More about Fastfile
Fastfile是个ruby脚本。
——也就是说你可以把它当成一个ruby脚本来写。你不需要把自己局限于只做一些“规定动作”,你尽可以在lane中做一些“自选动作”。发邮件啊,或是发slack消息啊,具体做什么就随您方便了。以slack为例。
before_all do ENV["SLACK_URL"] = "https://hooks.slack.com/services/...." end desc "Runs all the tests" lane :test do scan(scheme: "SegmentFault") slack end lane :enterprise do slack( message: "SegmentFault started enterprise archiving." ) gym(scheme: "SegmentFault", export_method: "enterprise") slack( message: "SegmentFault finished enterprise archiving. Uploading...." ) end
Continuous Integration
到此为止我们已经看到了fastlane可以为我们节约多少时间精力。如果把它跟其他工具比如jenkins结合,搭建持续集成服务,还可以节省更多时间精力——还可以更酷。
本文以介绍fastlane为主,关于持续集成和jenkins请读者自己去了解。
上文提到提测testflight需要登陆iTunes Connect,但是在持续集成的“全自动化”环境中,这种需要管理员敲键盘的操作是不存在的。
这就需要我们预先维护一个login session。具体操作如下
- 在appleid.apple.com/account/manage上生成一个application specific password。
- 通过环境变量
FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD
提供这个application specific password。 - 执行
fastlane spaceauth -u [email protected]
,生成session cookie。 - 通过环境变量
FASTLANE_SESSION
提供session cookies。
Common problems
这里简述fastlane使用中的常见问题及解决方法——重要之处在于你要通过阅读log找出问题是什么。
Problem 1
xcodebuild命令执行超时。
上文提到过这个问题。
Solution
添加环境变量FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT
,如export FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT=100
。
Problem 2
错误的provisioning profile。
比如你要打testflight包,却提供了enterprise的provisioning profile。
Error Domain=IDEProfileQualificationErrorDomain Code=3 "Provisioning profile "SegmentFault" is not an "iOS App Store" profile."
Solution
这是一个常规的code signing问题,通过Xcode很容易解决,把错误的provisioning profile替换成正确的就好了。有时也可能provisioning profile是正确的,而其他配置与其不匹配,那么修改其他配置使之匹配就好了。
Problem 3
session cookie过期。
Login to iTunes Connect ([email protected]) Two Factor Authentication for account '[email protected]' is enabled Your session cookie has been expired.
Solution
- 执行
fastlane spaceauth -u [email protected]
,生成session cookie。 - 通过环境变量
FASTLANE_SESSION
提供session cookie。
Problem 4
重复/过低的版本号。
ERROR ITMS-90189: "Redundant Binary Upload. There already exists a binary upload with build '4' for version '2.0.9'" ERROR ITMS-90186: "Invalid Pre-Release Train. The train version '2.0.9' is closed for new build submissions" ERROR ITMS-90062: "This bundle is invalid. The value for key CFBundleShortVersionString [2.0.9] in the Info.plist file must contain a higher version than that of the previously approved version [2.1.0]."
上面这段error log反馈了两个问题,一是version 2.0.9已经有build 4了,不要重复提交version与build相同的binary;二是2.1.0版本已经提交过了,不要提交比它低的版本。
Solution
修改版本号。