fastlane与持续集成

 阅读约 10 分钟

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 enterprisefastlane 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。具体操作如下

  1. appleid.apple.com/account/manage上生成一个application specific password。
  2. 通过环境变量FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD提供这个application specific password。
  3. 执行fastlane spaceauth -u user@email.com,生成session cookie。
  4. 通过环境变量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 (user@email.com)
Two Factor Authentication for account 'user@email.com' is enabled
Your session cookie has been expired.

Solution

  1. 执行fastlane spaceauth -u user@email.com,生成session cookie。
  2. 通过环境变量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
修改版本号。

阅读 5.5k更新于 2017-10-26
推荐阅读
目录