项目每次进入上线前期的测试阶段,都要反复地利用 Xcode 打包,上传测试发布平台,再分发给测试人员,无论从哪个角度看,这都是一个毫无技术含量并且及其耗时的事情,那么能不能通过自动化部署来解放这部分的时间消耗呢?
正文 无论如何,测试打包对于 iOS 开发者而言都是件繁琐枯燥的事情,项目规模小还好,几分钟不过是去喝杯咖啡的时间。但是对于稍微大一点的项目而言,少则十几分钟,多则半小时,在这么长的时间里,你得一直等待Xcode完成 Archive 任务,在此期间还需要你点击几个选项,既费时,又费心。尤其是遇到个别 UI 测试上的小问题,一个像素的调整、一处文案的修改,反复的执行打包操作,脾气再好的工程师都会感到一阵抓狂。
自从去年第一次使用过 Fastlane 之后,打包这项繁琐的工作,就再也不是一项负担。我只需要在 iTerm 里敲一行命令,就完成了从打包到测试平台发布整套流程,比手动发布时间更快,并且这个过程不会影响你当前的任何操作,你仍然可以继续使用 Xcode,或者做任何你想做的事。
本文以目前主流的两大分发平台 Pgyer ( 蒲公英 ) 和 Bugly ( 腾讯 Bugly ) 为例,从头搭建一个全自动化分发环境,以及 Fastlane 脚本的示范编写。
本文以下内容的运行环境(2019-12-19 更新):
Xcode: 11.1
macOS: Catalina 10.15.1
Fastlane: 2.137.0
Ruby: 2.6.3
需要注意,如果你是第一次使用 Fastlane ,macOS 的系统版本最好保持在 10.15 以上,因为低版本系统所自带的 Ruby 版本过低,在安装过程中会出现问题,如果你不想升级 macOS 版本,必须使 Ruby 保持在 2.4.0 以上
Fastlane 是 Google 的大神 Felix Krause 基于 Ruby 写的一套自动化工具集,能够帮助iOS 和 Android 开发者实现自动化部署,持续集成等工作。Fastlane 的组件包括:
名称
作用
deliver
自动上传截图,APP 的元数据,二进制( ipa )文件到 iTunes Connect
snapshot
自动截图(基于 Xcode 的 UI test)
frameit
可以把截图自动加上边框
pem
自动生成、更新推送配置文件
sigh
用来创建、更新、下载、修复 Provisioning Profile 的工具
produce
自动在 iTunes Connect 或 Apple Developer Center 中建立你的产品
cert
自动创建管理 iOS 代码签名证书
pilot
管理 TestFlight 的测试用户,上传二进制文件
boarding
建立一个添加测试用户界面,发给测试者,可自行添加邮件地址,并同步到 iTunes Connect
gym
自动化编译打包工具
match
证书和配置文件管理工具
scan
自动运行测试工具,并生成 HTML 报告
安装 & 初始化 由于 Fastlane 对 Ruby 的环境有版本要求,如果本机的 Ruby 版本在 2.4.0
以下,建议升级更新 Ruby。
1 2 # 查看本机 Ruby 版本 $ ruby --v
更新 Ruby 你可以使用 RVM 或者 Homebrew 来进行 Ruby 的升级更新。
1 2 3 4 5 6 7 8 9 10 # RVM # 安装 RVM $ RVMcurl -L get .rvm.io | bash -s stable # 查看当前所有可安装的 Ruby 版本 $ rvm list known # 选择其中一个版本进行安装 $ rvm install ruby -版本号
1 2 3 4 5 6 7 # Homebrew # 安装 Homebrew (如果下面的安装链接失效,可以直接访问官网查看 https: //brew.sh /) $ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" # 升级 Ruby 的最新版本 $ brew upgrade ruby
安装 Fastlane 1 2 # 使用 gem 进行安装 $ sudo gem install -n /usr/local/bin fastlane
初始化 Fastlane cd 到项目目录,执行初始化命令:
首先会询问你使用 Fastlane 的目的,这里我们由于只需要搭建自动分发,所以,选择 4
:
然后根据提示进行操作即可:
初始化完成后提示如下:
安装完成后,你的工程目录下会出现一个名为 fastlane
的文件夹,一个名为 Gemfile
和 Gemfile.lock
的文件。进入 fastlane
文件夹,打开 Appfile
,填入你的 应用标识名
和 开发者账号名
Fastfile 脚本的编写 初始化完成后,Fastlane 就可以投入使用了。Fastlane 整个自动化的核心就是 fastfile 这个脚本执行文件和控制自动化链条的 Action,所以,如果想要完成自动化测试发布,就需要对这个文件进行自定义编写,并处理其相应的 Action。
我们先将自动化测试发布的步骤,按照一个个 Action 进行独立拆分,最后在合并成为完整的一键自动化流程。
我们想要达到的效果是,在终端执行一行 lane 指令后,可以自由选择是否对上传到 Pgyer / Bugly 的测试包展示内容进行自定义修改,如果需要,则允许使用者在终端中输入自定义内容并保存到最终的上传参数中,不需要则直接自动执行打包 + 上传的操作,每次打包完成后,对应 Target 的 Build 版本号自动加一,上传完成后,自动打开浏览器并进入对应平台的测试包分发页面。
基于这些诉求,我们拆分后的步骤大致如下:
lane 指令的配置
gym Action 的自动打包脚本编写
increment_build_number 累加 Build 版本号
自动上传 ipa 到 Pgyer / Bugly 的脚本编写
手动设置参数任务的编写,用于自定义 Pgyer / Bugly 上传参数
浏览器页面打开脚本编写
合并编写好的脚本到统一的lane指令
lane指令的配置 打开 Fastlane 文件夹下的 fastfile,注意,一定不能直接使用文本编辑器打开,会引起自动引号等报错,这里推荐使用 Visual Studio Code 选择 Ruby 文本样式来打开编写。
lane指令的配置非常简单,直接用以下内容覆盖 fastfile 默认的模板:
1 2 3 4 5 6 7 8 9 default_platform(:ios ) platform :ios do lane :ad do end end
自动化打包 我们使用 Fastlane 提供的 gym, 这个专门的打包 Action 来对脚本进行编写:
在上一步设置好的lane指令作用域内(也就是lane :ad do - end 中间这部分区域),输入如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 scheme = "Your project scheme" currentTime = Time.new.strftime("%Y-%m-%d %H-%M-%S" ) output_path = "../ipa_name #{currentTime} " ipa_name = "Your ipa name" gym( workspace: "xxxx.xcworkspace" , scheme: "#{scheme} " , output_name: "#{ipa_name} " , clean: true , configuration: "Release" , export_method: "ad-hoc" , output_directory: "#{output_path} " , )
写好之后,你的 fastfile
应该是这个样子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 default_platform(:ios ) platform :ios do lane :ad do scheme = "Your project scheme" currentTime = Time.new.strftime("%Y-%m-%d %H-%M-%S" ) output_path = "../ipa_name #{currentTime} " ipa_name = "Your ipa name" gym( workspace: "xxxx.xcworkspace" , scheme: "#{scheme} " , output_name: "#{ipa_name} " , clean: true , configuration: "Release" , export_method: "ad-hoc" , output_directory: "#{output_path} " , ) end end
到这里,一个基本的 gym Action 自动打包脚本就编写完毕了。但是仅仅依靠上面这些内容还不足以完成我们想要的打包全自动化流程,现在,我们在执行 fastlane ad
打包之前,还需要手动对每个 Target 中的 Build 版本号进行更改,这非常麻烦,而且如果在某次打包之前忘记了更改,还得打断任务重新执行。
不过不用担心,Fastlane 早已替我们考虑周到。我们只需要在 gym Action 执行之前,也就是在它的前一行加上一行代码即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 default_platform(:ios ) platform :ios do lane :ad do scheme = "Your project scheme" currentTime = Time.new.strftime("%Y-%m-%d %H-%M-%S" ) output_path = "../ipa_name #{currentTime} " ipa_name = "Your ipa name" increment_build_number gym( workspace: "xxxx.xcworkspace" , scheme: "#{scheme} " , output_name: "#{ipa_name} " , clean: true , configuration: "Release" , export_method: "ad-hoc" , output_directory: "#{output_path} " , ) end end
Xcode 工程配置 increment_build_number 是 Fastlane 自带的脚本命令,作用是在当前 build version 的基础上自动 +1,省去了每次打测试包都要手动修改 Build 的工作。
其原理是代替我们调用了 Xcode 自带的自动增加版本号的命令行工具 agvtool
。有对 agvtool
感兴趣的可以了解一下具体如何使用 。
在 fastfile 脚本文件中添加了 increment_build_number 之后,还需要对 Xcode 进行额外的工程配置:
注意:如果有多个 Target,需要对每个Target 都进行下面的设置
设置 Current Project Version & Versioning System
TARGETS -> Build Settings
Current Project Version 填写当前版本号,最好从1开始
Versioning System 选择 Apple Generic ( Xcode 11 以上版本忽略 )
设置 Bundle version & Bundle versions string, short
TARGETS -> Info
Bundle version 和 第1步设置的 Current Project Version 保持一致即可,可以直接使用 $(CURRENT_PROJECT_VERSION)
Bundle versions string, short 是当前应用的 Version 版本号,如果需要自增 Version 再设置 $(MARKETING_VERSION)
,其对应的脚本参数是 increment_version_number ,仅自增 Build 无需设置
将 ipa 包自动上传至 Pgyer/Bugly 由于 Pgyer 和 Bugly 采用的是两套不同的上传策略,所以我们需要分开编写两套上传脚本
Pgyer 安装蒲公英的 Fastlane 插件
1 $ fastlane add_plugin pgyer
期间会询问一次,选择 y
即可,出现下面提示表示安装成功
安装成功后,在 gym 下面加入蒲公英插件的配置信息:
1 2 3 4 5 6 7 8 9 pgyer( api_key: "xxx" , user_key: "xxx" , update_description: "xxx" )
api_key
和 user_key
,在自己账号下的 应用管理
- App概述
- API
中可以找到,替换到对应的位置即可。蒲公英插件不支持修改测试包名,仅支持更新描述的修改。
此时,你的 fastfile 应该是这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 default_platform(:ios ) platform :ios do lane :ad do scheme = "Your project scheme" currentTime = Time.new.strftime("%Y-%m-%d %H-%M-%S" ) output_path = "../ipa_name #{currentTime} " ipa_name = "Your ipa name" increment_build_number gym( workspace: "xxxx.xcworkspace" , scheme: "#{scheme} " , output_name: "#{ipa_name} " , clean: true , configuration: "Release" , export_method: "ad-hoc" , output_directory: "#{output_path} " , ) pgyer( api_key: "xxx" , user_key: "xxx" , update_description: "xxx" ) end end
Bugly Bugly 官方为我们提供了两个 Fastlane 的扩展插件:上传文件和更新文件,由于目前腾讯已经关闭了 Bugly 官网的文档入口,可以直接查看他们的 Github repo 的使用文档
首先点击下载插件,下载完成后,本地会多出两个 ruby 文件,更新文件插件update_app_to_bugly
和 上传文件插件upload_app_to_bugly
。然后将下载好的上传文件插件的文件名 upload_app_to_bugly
复制下来,在下一步中会用到。
这时,就需要我们开始编写 upload_app_to_bugly Action 了。
首先,自定义一个 Action,在 cd 到工程根目录(有 fastlane 文件夹的那个)终端中执行如下命令
输入完之后,Fastlane 会让你输入自定义的 Action 名字,直接粘贴刚才复制好的名字即可。
随后,Fastlane 就会在 fastelane 文件目录下创建一个名为 actions 的文件夹,而文件夹下也会默认有一个名为 upload_app_to_bugly.rb
的 ruby 文件。然后我们把刚才下载好的同名文件直接进行替换就可以了。
upload_app_to_bugly Action 创建成功后,我们需要回到 fastfile 里面对其 Action 内容进行编写,因为 fastfile 的 Action 执行优先级是自上而下的,所以我们需要将 upload_app_to_bugly Action 的内容写在 gym Action 下面:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ipa_path = "#{output_path} /#{ipa_name} .ipa" upload_app_to_bugly( file_path: "#{ipa_path} " , app_key: "xxxxx" , app_id: "xxxx" , pid: "2" , title: "xxxxx" , desc: "xxxxx" , secret: "1" , users: "" , password: "" , download_limit: 999 )
这里只列举了必填参数和部分可选参数,腾讯在去年将插件的API文档入口也一并从 Bugly 移除了,如果你想了解更多相关参数的含义,可以在我前搭档写的这篇文章 里找到其文档的网页快照。
此时你的 fastfile 应该是这个样子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 default_platform(:ios ) platform :ios do lane :ad do scheme = "Your project scheme" currentTime = Time.new.strftime("%Y-%m-%d %H-%M-%S" ) output_path = "../ipa_name #{currentTime} " ipa_name = "Your ipa name" ipa_path = "#{output_path} /#{ipa_name} .ipa" increment_build_number gym( workspace: "xxxx.xcworkspace" , scheme: "#{scheme} " , output_name: "#{ipa_name} " , clean: true , configuration: "Release" , export_method: "ad-hoc" , output_directory: "#{output_path} " , ) upload_app_to_bugly( file_path: "#{ipa_path} " , app_key: "xxxxx" , app_id: "xxxx" , pid: "2" , title: "xxxxx" , desc: "xxxxx" , secret: "1" , users: "" , password: "" , download_limit: 999 ) end end
通过控制脚本管理上传参数 每次发布测试包后,都需要在 Pgyer/Bugly 测试分发平台上手动修改,测试包名称和本次更新内容,也就是上一步中,pgyer
Action 中的 update_description 参数 和 upload_app_to_bugly
Action 中的 title、desc 参数。
如果你完全没有修改的需求,这个 fastfile 实际就可以直接投入使用了。但是我们为了更好的把控测试分发和规范流程,还是需要在每次测试包更新后,对所更新的内容进行一个简要的说明。
下面我们就开始第4个步骤,对手动设置参数任务的编写,在 gym Action 之前,添加 Ruby 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 version_title = "xxx" version_desc = "xxxxxx" begin puts "Do you want to manually set the title of the test package & description? (y/n)" res = STDIN.gets.chomp if res != "n" print Input title: " version_title = STDIN.gets.chomp puts " ---Title set successfully!---" # 用于 Pgyer/Bugly 显示的测试包更新描述 print " Input description: " version_desc = STDIN.gets.chomp puts " ---Description set successfully!---" end end
上面这段代码是一段选择任务,会在自动打包执行之前进行一次询问,是否需要手动设置测试包的标题和描述,如果选择 y
,则会要求使用者输入测试包的标题和更新描述,如果选择 n
则自动跳过这一步,直接开始打包。
这就避免了在分发新的测试包的时候,还需要修改 update_description
Action 或 upload_app_to_bugly
Action 脚本参数 或者 打开平台网页 -> 点击内测分发 -> 选择上传的测试包 -> 点击修改,这样繁琐的步骤。
最后,你的 fastfile 应该是这个样子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 default_platform(:ios ) platform :ios do lane :ad do scheme = "Your project scheme" currentTime = Time.new.strftime("%Y-%m-%d %H-%M-%S" ) output_path = "../ipa_name #{currentTime} " ipa_name = "Your ipa name" ipa_path = "#{output_path} /#{ipa_name} .ipa" version_title = "xxx" version_desc = "xxxxxx" begin puts "Do you want to manually set the title of the test package & description? (y/n)" res = STDIN.gets.chomp if res != "n" print "Input title: " version_title = STDIN.gets.chomp puts "---Title set successfully!---" print "Input description: " version_desc = STDIN.gets.chomp puts "---Description set successfully!---" end end increment_build_number gym( workspace: "xxxx.xcworkspace" , scheme: "#{scheme} " , output_name: "#{ipa_name} " , clean: true , configuration: "Release" , export_method: "ad-hoc" , output_directory: "#{output_path} " , ) pgyer( api_key: "xxx" , user_key: "xxx" , update_description: "#{version_desc} " ) upload_app_to_bugly( file_path: "#{ipa_path} " , app_key: "xxxxx" , app_id: "xxxx" , pid: "2" , title: "#{version_title} " ,", desc:" {version_desc}", secret:" 1 ", users:" ", password:" ", download_limit:999 ) end end
完善脚本 最后一步,我们需要将这个 “裸奔” 的脚本进行一些必要的点缀,在关键步骤上做一些处理:
添加输出 log 我们在一些关键步骤上,比如更新 build_number 之后、打包完成开始上传到 Pgyer/Bugly 的执行节点上,加上一些提示性的 log, 对查看打包上传进度是很有帮助的:
你可以选择使用 puts 进行打印,它会在打印后自动切换光标到下一行,如:
1 puts "---Build number updated successfully !---"
也可以使用 print 进行打印,它在打印后会将光标停留在当前这行,如:
让关键 log 以颜色进行区分 如果不进行颜色区分,脚本在执行中密密麻麻的 log 全部都是同一个颜色,让人眼花缭乱,那么我们添加的输出 log 就是白费功夫了,所以我们需要对关键 log 加以颜色进行渲染,如:
1 2 3 4 5 6 7 8 9 10 11 def colorize (text, color_code) "\e[#{color_code} m#{text} \e[0m" end def green (text) ; colorize(text, 32 ); end def magenta (text) ; colorize(text, 35 ); end def cyan (text) ; colorize(text, 36 ); end
这些都是 Ruby 当中常用的颜色值设置方法,更多颜色的设置方法可以参考 这里
使用方法,以上面的 log 为例:
1 puts "" + green("---Build number updated successfully !---" ) +""
最终这行 log 在终端中就会以绿色的文本进行显示了。
通过这些简单的点缀,我们来最后完善一下这个自动化打包发布脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 default_platform(:ios ) platform :ios do lane :ad do scheme = "Your project scheme" currentTime = Time.new.strftime("%Y-%m-%d %H-%M-%S" ) output_path = "../ipa_name #{currentTime} " ipa_name = "Your ipa name" ipa_path = "#{output_path} /#{ipa_name} .ipa" version_title = "xxx" version_desc = "xxxxxx" def colorize (text, color_code) "\e[#{color_code} m#{text} \e[0m" end def green (text) ; colorize(text, 32 ); end def magenta (text) ; colorize(text, 35 ); end def cyan (text) ; colorize(text, 36 ); end begin puts "" + magenta("Do you want to manually set the title of the test package & description? (y/n)" ) +"" res = STDIN.gets.chomp if res != "n" print "" + magenta("Input title: " ) +"" version_title = STDIN.gets.chomp puts "" + green("---Title set successfully!---" ) +"" print "" + magenta("Input description: " ) +"" version_desc = STDIN.gets.chomp puts "" + green("---Description set successfully!---" ) +"" end end increment_build_number puts "" + green("---Build number updated successfully !---" ) +"" gym( workspace: "xxxx.xcworkspace" , scheme: "#{scheme} " , output_name: "#{ipa_name} " , clean: true , configuration: "Release" , export_method: "ad-hoc" , output_directory: "#{output_path} " , ) puts "" + cyan("---Start uploading ipa to Pgyer---" ) +"" pgyer( api_key: "xxx" , user_key: "xxx" , update_description: "#{version_desc} " ) puts "" + cyan("---Start uploading ipa to Bugly---" ) +"" upload_app_to_bugly( file_path: "#{ipa_path} " , app_key: "xxxxx" , app_id: "xxxx" , pid: "2" , title: "#{version_title} " ,", desc:" {version_desc}", secret:" 1 ", users:" ", password:" ", download_limit:999 ) end end
完成后打开浏览器 我们需要在上传完成后,自动打开蒲公英 / Bugly下载页,只需要在脚本的最后插入下面的脚本内容,即可自动打开默认浏览器,并跳转到对应平台的下载页
1 2 3 puts "" + cyan("--- Open Pgyer/Bugly download page ---" ) +"" system("open" , "xxxx" )
最终的脚本内容 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 default_platform(:ios ) platform :ios do lane :ad do scheme = "Your project scheme" currentTime = Time.new.strftime("%Y-%m-%d %H-%M-%S" ) output_path = "../ipa_name #{currentTime} " ipa_name = "Your ipa name" ipa_path = "#{output_path} /#{ipa_name} .ipa" version_title = "xxx" version_desc = "xxxxxx" def colorize (text, color_code) "\e[#{color_code} m#{text} \e[0m" end def green (text) ; colorize(text, 32 ); end def magenta (text) ; colorize(text, 35 ); end def cyan (text) ; colorize(text, 36 ); end begin puts "" + magenta("Do you want to manually set the title of the test package & description? (y/n)" ) +"" res = STDIN.gets.chomp if res != "n" print "" + magenta("Input title: " ) +"" version_title = STDIN.gets.chomp puts "" + green("---Title set successfully!---" ) +"" print "" + magenta("Input description: " ) +"" version_desc = STDIN.gets.chomp puts "" + green("---Description set successfully!---" ) +"" end end increment_build_number puts "" + green("---Build number updated successfully !---" ) +"" gym( workspace: "xxxx.xcworkspace" , scheme: "#{scheme} " , output_name: "#{ipa_name} " , clean: true , configuration: "Release" , export_method: "ad-hoc" , output_directory: "#{output_path} " , ) puts "" + cyan("---Start uploading ipa to Pgyer---" ) +"" pgyer( api_key: "xxx" , user_key: "xxx" , update_description: "#{version_desc} " ) puts "" + cyan("---Start uploading ipa to Bugly---" ) +"" upload_app_to_bugly( file_path: "#{ipa_path} " , app_key: "xxxxx" , app_id: "xxxx" , pid: "2" , title: "#{version_title} " ,", desc:" {version_desc}", secret:" 1 ", users:" ", password:" ", download_limit:999 ) puts " "+ green(" ---ipa to upload successfully !---") +" " # 打开蒲公英 / Bugly下载页 puts " "+ cyan(" --- Open Pgyer/Bugly download page ---") +" " system(" open", " xxxx") # xxxx 为下载页 url end end
现在,这个 fastfile 才算正式宣告完成了,让我们来看看使用效果。
使用 首先在终端中 cd 到你项目目录,也就是有 fastlane 文件的那一层,执行:
当 Fastlane 的小火箭开始出现,就表明 lane 指令开始执行了,以上传到 Pgyer 为例:
首先会询问是否需要修改更新描述,这里示范输入 “Fastlane测试”
输入完成后回车,继续执行,递增 Build 版本号
随后开始执行 gym 配置命令,打包开始
Archive 完成时,会显示当前打包的类型
打包完成后,导出 ipa、dSYM 等文件到指定输出路径,随后开始上传到 Pgyer
上传完成后,会自动打开默认浏览器并跳转到下载页面,并显示当前耗时
进入测试分发的下载页面,你就可以看到已经上传好的测试包了,直接复制链接地址或者 QRCode 给测试人员就可以了。
打包完成后的输出文件会在你指定的输出路径出现,这个文件在上传成功后直接删除就可以了。
当然最后的分发以及删除操作你也可以写在脚本中一起帮你执行。
至此,Fastlane + 指定平台的全自动化部署测试发布就全部搭建完毕了。同理,上传至 AppStore 一样可以使用 Fastlane 完成自动化部署,有了上面这些经验,就可以很轻松的配置完成了,亲手去尝试和体验 Fastlane 的便捷吧。
后记 除了 gym ,也可以直接通过 shell 脚本来执行 Fastlane,想了解更多使用上的配置,可以参考 官方文档
希望 Fastlane 能够帮助更多的工程师解放双手和时间。
参考: fastlane docs
和重复劳动说再见-使用fastlane进行iOS打包
使用 Fastlane 上传 App 到蒲公英
iOS中fastlane的使用