Fastlane简介
FastLane是一种配置iOS和Android自动化Beta部署和发布的最简单的方法之一。它可以简化一些乏味、单调、重复的工作,像截图、代码签名以及发布App。只需一条命令就可实现从 Xcode 项目到 编译\打包\构建\提交审核。
本文做以下事情:
- fastlane 环境搭建
- 导入ios的xcode项目
- 对xcode项目进行fastlane初始化
- FastLane目录下的主要文件说明
- 安装fastlane插件
- 使用fastlane测试部署
- Fastlane文件格式的具体解析
- 配置发布流程
说明:本文将 Apple Dev Center 简称为 ADC; iTunes Connect 简称为 ITC
一、Fastlane 环境搭建
1) 检查ruby是否安装,低于2.0最好升级
rvm -v #检查ruby是否安装正常
rvm list known #列出已知ruby版本
rvm install ruby-xxxxx #安装一个最新ruby版本
#如果报错的话
brew install opensslreinstall|
install ruby-xxxxx #注意修改xxxxxx
|
---|
2) 检查 Xcode是否安装
$ xcode-select --install |
---|
如果未安装,终端会开始安装,如果报错误:command line tools are already installed, use "Software Update" to install updates.代表已经安装。
3) 安装 fastlane
$ sudo gem install -n /usr/local/bin Fastlane $ fastlane -v #检查版本 Fastlane fastlane installation at path: /Users/iwm/.rvm/gems/ruby-2.3.4@global/gems/fastlane-2.64.1/bin/fastlane fastlane 2.64.1 OK,安装完成 |
---|
4) 配置环境变量
找到shell profile,一般在 ~/.bashrc, ~/.bash_profile or ~/.zshrc文件里,取决于你的系统,文件的末尾处添加:
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
|
---|
二、导入ios的xcode项目 ,需找rd要 @陈卓
三、对xcode项目进行fastlane初始化
1) fastlane init
终端,cd到你的工程目录,然后执行fastlane init:
如果期间报错 Connection reset by peer - SSL_Connect,就需要执行:
$ brew update && brew install ruby # 重装 $ sudo gem install -n /usr/local/bin Fastlane # 然后重新执行 $ fastlane init |
---|
2) 初始化执行的过程
a.期间会遇到:在 "Your Apple ID" 这一步输入苹果开发者账号,会让输入 Apple ID 账号密码(这个信息会存在钥匙串中,后续使用无需再输入密码
b.在“Please confirm the above values”这一步,是问该app是否需要在iTC和ADC中创建,输入 y会自动检测是否需要创建,然后,fastlane 会进行一系列的初始化操作,包括下载 App Store 上的元数据和截屏文件。
3) 初始化执行的结果:
$ fastlane produce init |
---|
b.若上一步输入y,则在 ADC 和 ITC 中创建了相应信息,初始化完成后的fastlane目录,如下:
四、FastLane目录下的主要文件说明
五、安装fastlane插件
3)安装上面的插件
$fastlane add_plugin [name] # 安装方法
$fastlane add_plugin versioning
$fastlane add_plugin firim
|
---|
六、使用fastlane测试部署
构建测试应用,编辑fastfile:
lane :beta do gym(scheme: "MyApp", workspace: "MyApp.xcworkspace", include_bitcode: true) end |
---|
测试运行lane(任务):
$ fastlane beta |
---|
如果顺利执行的话,将会在当前文件目录看到一个 MyApp.ipa 文件和对应 MyApp.app.dSYM 文件测试成功。
七、Fastlane文件格式的具体解析
1) Appfile格式:
备注:选择sublime打开,把当前显示样式设置为Ruby
Appfile可以为每个lane提供不同的 app_identifier, apple_id 和 team_id,例如:这里就是为Fastfile中定义的:inhouse设置单独的信息。
app_identifier "com.xxx.xxx" # app的bundle identifier apple_id "xxx@xxx.com" # 你的Apple ID team_id "XXXXXXXXXX" # Team ID for_lane :inhouse do app_identifier "com.bbb.bbb" apple_id "bbb@bbb.com" team_id "AAAAAAAAAA" end |
---|
2) Deliverfile格式:
app_identifier "com.xxxx.xxxx" # The bundle identifier of your app username "xxxxx@xxxx.com" # your Apple ID user |
---|
3) Fastfile格式:
Fastfile就是我们打包,发布到fir,testFlight,appstore等等操作的具体配置文件,Fastfile管理所创建的 lane,它的格式是这样的:
# 自动更新fastlane 工具 # update_fastlane # fastlane_version => 指定 fastlane的最小版本,在每次执行之后会检查是否有新版本,如果有会在末尾追加新版本提醒 fastlane_version "2.30.1" # default_platform => 默认使用平台是 ios,也就是说文件可以定义多个平台 default_platform :ios platform :ios do before_all do # ENV["SLACK_URL"] =”https://hooks.slack.com/services/...” cocoapods end # desc => 一个lane(任务)的描述,一般说明这个lane是做什么的 desc "Runs all the tests" lane :test do #一个lane就是一个任务,里面是一个个的action组成的工作流。 scan end desc "提交一个新的Beta版本到 Apple TestFlight" desc "This will also make sure the profile is up to date" lane :beta do # match(type: "appstore") # more information: https://codesigning.guide gym(scheme: "Docment") # Build your app - more options available pilot # sh "your_script.sh" # You can also use other beta testing services here (run `fastlane actions`) end desc "部署一个新版本到App Store" lane :release do # match(type: "appstore") # snapshot gym(scheme: "Docment") # Build your app - more options available deliver(force: true) # frameit end # 你可以定义自己的lane #执行lane成功后的回调 after_all do |lane| # slack( # message: "Successfully deployed new App Update." # ) end # 如果流程发生异常会走这里并终止 error do |lane, exception| # slack( # message: exception.message, # success: false # ) end end |
---|
八、配置发布流程
- 发布测试版到Fir.im
- 发布测试版到TestFlight
- 发布到Apple Store
1) 发布到TestFlight
a. 生成证书和 Provisioning Profile
用sublime打开 Fastlane 文件,将内容替换为:
# Minimum version of fastlane
platform
end |
---|
注意:sigh 默认创建的是 App Store 的发布 profile。如果想创建 ad hoc profile,需要使用 sigh(adhoc:true)。如果是开发 profile 则使用 sigh(development:true)。
此时创建了第一个 lane,保存文件,打开终端进入到项目文件夹,输入命令:
fastlane provision |
---|
这会让 fastlane 执行 provision lane。大约一分钟左右,fastlane 会问你 iTunes Connect 密码,它会保存到你的 Mac 的钥匙串里。
注意:如果看到错误,例如 “Creation of apps of this type is not available”, 则请登录 iTunes Connect,看一下是否有某些更新的协议需要你确认。 |
---|
在进行下一步之前,还需要在 Xcode 中进行某些修改。打开 项目的xcode中,切换到 General 页。将 bundle identifier 修改为初始化 fastlane 时输入的 App ID。
在 Build Settings > Code Signing > Provisioning Profile 设为 “ <新的 app ID> AppStore”。然后在 Code Signing Identity 选择和这个 provisioning profile 相对应的 ID:
注意:code signing identity 应该和 provisioning profile 中的 identities 相匹配。这样,当 gym 编译 IPA 文件时会使用新创建的 provisioning profile。 |
---|
登录进 iTunes Connect,此时app 已经创建好了;
b. 简化屏幕截图工作
# A list of devices you want to take the screenshots from devices([ "iPhone 4s", "iPhone 5", "iPhone 6", "iPhone 6 Plus" ]) # A list of supported languages languages([ 'en-US', 'fr-FR' ]) # Where should the resulting screenshots be stored? screenshots_path "./screenshots" # Clears previous screenshots #会清空上次创建的截屏图。 clear_previous_screenshots # Latest version of iOS ios_version '9.1' |
---|
保存、关闭文件。打开 Fastfile 文件,在 error do |lane, exception| 一句上面加入:
|
---|
这里创建了一个新的 lane,名为 screenshot,并使用 snapshot 命令根据在 Snapfile 文件中输入的配置创建截屏图。保存文件,在终端窗口中输入:
fastlane screenshot |
---|
注意:snapshot 为了截取屏幕,需要调用 Snapfile 中列出的设备类型所对应的模拟器。如果缺少了一种或多种模拟器,你要 Xcode 中通过 Window\Devices 菜单来添加相应的模拟器。左下角的 + 号按钮就是用来添加新模拟器的。
此时,项目文件夹下面的 fastlane 目录,会看到多了一个 screenshots 子目录,还会发现一个 screenshots.html 文件。打开这个文件,可以浏览所有的屏幕截图。
c. 创建 IPA
打开 Fastfile,在 screenshot lane 之后添加:
desc "Create ipa" lane :build do gym end |
---|
这里创建了一个 lane 叫做 build,它使用 gym 命令创建签名的 ipa 文件。保存 Fastfile,打开终端窗口,进入 项目文件夹,输入命令:
|
---|
这会执行 build lane,开始编译。一旦编译完成,打开 mZone 项目文件夹。你会看到签好名的 ipa 文件:
d. 无缝上传
要上传屏幕截图、元数据和 IPA 文件到 iTunes Connect,可以使用 deliver 命令,它已经包含在 fastlane 中了。
首先,需要用 deliver 来初始化项目。在终端窗口,进入项目文件夹输入命令:
deliver init |
---|
执行完成,在 summary 栏中,你会看到 deliver 已经自动检测到 ipa 文件和屏幕截图的位置。打开 Fastfile 在 build lane 后面添加:
|
---|
在终端窗口中,输入命令:
|
---|
通过这个命令,fastlane 会创建一个 html 文件,它将以 html form 表单的形式上传文件。登录你的 iTunes Connect。所有的屏幕截图、描述、版本 build 1.0 都应当上传就绪。
剩下来的事情就是点击 “Submit for Review” 按钮。 deliver 可以自动提交 app 去审核,但你需要修改 upload lane:
desc "Upload to App Store and submit for review" lane :upload do deliver( submit_for_review: true ) end |
---|
2) 发布到App Store
lane :deploy do # 如果你用 pod install cocoapods # 如果你没有申请adhoc证书,sigh会自动帮你申请,并且添加到Xcode里 # 不带adhoc参数,sigh会自动生成App Store证书(公司或个人帐户) sigh # 以下两个action来自fastlane-plugin-versioning, # 第一个递增 Build,第二个设定Version。 # 如果有多个target,就必须指定target的值,否则它会直接找找到的第一个plist修改 #建议每一个打的包的Build都要不一样,这样crash了拿到日志,可以对应到ipa上 increment_build_number_in_plist(target: [target_name]) increment_version_number_in_plist( target: [target_name], version_number: '7.1.3' ) #gym用来编译ipa,指定输出目录 gym( output_directory: './build', ) # 上传所有信息到App Store deliver(force: true) end |
---|
3) 自定义发布到App Store版本
# You can define as many lanes as you want desc "Deploy a new version to the App Store" lane :release do |op| increment_version_number(version_number: op[:version]) #根据入参version获取app版本号 increment_build_number(build_number: op[:build]) #将build号设置与app版本号相同 # 设置app的info.plist文件项 set_info_plist_value(path: "./xxx/Info.plist", #info.plist文件目录 key: "UIFileSharingEnabled", # key,将plist文件以Source Code形式打开可查询对应的key value: false) # value # 设置自定义plist文件项,用于给app配置不同的服务器URL set_info_plist_value(path: "./xxx/hostAddress.plist", key: "host", value: "https:/zhengshiServer:xx/xxx/xxx") # 更新Provisioning Profile # 在项目当前目录下创建provisions文件夹,并将App Store版本的.mobileprovision文件保存在里面,名称随意。 update_project_provisioning(profile: "./provisions/appstore.mobileprovision") # 更新项目团队 update_project_team(path: "xxx.xcodeproj", teamid: "5JC8GZ432G") # 开始打包 gym(use_legacy_build_api: true, output_name: "appstore", # 输出的ipa名称 silent: true, # 隐藏没有必要的信息 clean: true, # 在构建前先clean configuration: "Release", # 配置为Release版本 codesigning_identity: "iPhone Distribution: xxx Co.,Ltd. (5JC8GZ432G)", # 代码签名证书 buildlog_path: "./fastlanelog", # fastlane构建ipa的日志输出目录 output_directory: "/Users/xxx/Desktop") # ipa输出目录 end |
---|
4) 自定义发布到Development
desc "Build a new version use the ceshi" lane :ceshi do |op| increment_version_number(version_number: op[:version]) increment_build_number(build_number: op[:build])
set_info_plist_value(path: "./xxx/Info.plist", key: "UIFileSharingEnabled", value: true)
set_info_plist_value(path: "./xxx/hostAddress.plist", key: "host", value: "https:/ceshiServer:xx/xxx/xxx")
# 将Development版本的.mobileprovision文件保存在里面,名称随意。 update_project_provisioning(profile: "./provisions/development.mobileprovision")
update_project_team(path: "xxx.xcodeproj", teamid: "5JC8GZ432G")
gym(use_legacy_build_api: true, output_name: "ceshi", silent: true, clean: true, configuration: "Debug", buildlog_path: "./fastlanelog", codesigning_identity: "iPhone Developer: xxx (xxxxxxxxxx)", output_directory: "/Users/xxx/Desktop" ) end #批量处理 desc "build all version ipa" lane :all do |op| t = op[:version] ceshi version:t release version:t end |
---|
5) 执行
最后,只需在终端(相关项目目录下)轻轻敲入:
fastlane ceshi version:1.0.0 build:1.0.1 // 打包ceshi环境ipa,app版本号为1.0.0,build为1.0.1 fastlane release version:1.0.0 build:1.0.1 //打包App Store版本ipa,app版本号为1.0.0,build为1.0.1 fastlane all version:1.0.0 build:1.0.1 // 打包ceshi、App Store版本ipa,app版本号为1.0.0,build为1.0.1 |
---|
6) 优化
我们可以在 Fastfile 文件中添加一个函数来设置version号和build号,使得以上AppStore版本与Development版本配置使用同一函数,如下:
default_platform :ios def prepare_version(options) increment_version_number( version_number: options[:version] ) increment_build_number( build_number: options[:build] ) end |
---|
然后可以在一个lane中使用这个函数:
lane :appstore do |options| ··· prepare_version(options) ··· end |
---|
然后执行这个lane
$ fastlane appstore version:2.4.0 build:2.0 |
---|
九、TODO:
- 调研ios-fastlane的安全性
- 调研fastlane在其他公司的使用情况
- ios-fastlane踩坑篇
- ios-fastlane问题篇