更新节点:2018-09-26因为fastlane更新频繁,已更新到 2.105.2html
更新内容:fastlane新变化、fastlane新问题、fastlane遗留问题解决ios
fastlane是用Ruby语言编写的一套自动化工具集和框架,每个工具实际都对应一个Ruby脚本,用来执行某一个特定的任务,而fastlane核心框架则容许使用者经过相似配置文件的形式,将不一样的工具备机而灵活的结合在一块儿,从而造成一个个完整的自动化流程。好比我须要完成一套发布流程:git
#发布到AppStore lane :release do #增长build版本号,须要先配置build setting increment_build_number #pod资源更新 cocoapods #打包 gym #发布到AppStore deliver(force: true) #发布testflight测试 testflight end
fastlane版本:2.53.1 已更新到 2.105.2github
Docshell
[sudo] gem install fastlaneswift
若是用的是mac自带的ruby,须要 sudo权限 使用: sudo gem install fastlane 若是报错:ERROR: While executing gem ... (Errno::EPERM) Operation not permitted - /usr/bin/commander 使用: sudo gem install -n /usr/local/bin fastlane
在项目根目录下,初始化Fastlane:api
fastlane init 新版本安装的时候出现了下面的分支选择,按要求选择就行 1. 📸 Automate screenshots 2. 👩✈️ Automate beta distribution to TestFlight (自动testfilght型配置) 3. 🚀 Automate App Store distribution (自动发布型配置) 4. 🛠 Manual setup - manually setup your project to automate your (须要手动配置内容)
fastlane操做改变后咱们再了解一下有哪些配置文件:xcode
Appfile: 存储有关开发者帐号相关信息 Fastfile: 核心文件,主要用于 命令行调用和处理具体的流程,lane相对于一个方法或者函数 Deliverfile: deliver工具的配置文件 metadata: 元数据文件夹 Matchfile: Match操做对应的配置文件 screenshots: 截图文件夹
除开手动配置项,fastlane 会要求填写Apple ID,选择你的Team(若是有多个) 而后fastlane会自动检测当前目录下项目的App Name和App Identifier、Project。而后自行确认并按流程执行。ruby
执行顺序 | 方法名 | 说明 |
---|---|---|
1 | before_all | 在执行 lane 以前只执行一次 |
2 | before_each | 每次执行 lane 以前都会执行一次 |
3 | lane | 自定义的任务 |
4 | after_each | 每次执行 lane 以后都会执行一次 |
5 | after_all | 在执行 lane 成功结束以后执行一次 |
6 | error | 在执行上述状况任意环境报错都会停止并执行一次 |
1.若是Deliverfile、screenshots和metadata没有自动生成,经过deliver init 能够从新初始化bash
2.fastlane的配置会要求输入开发者帐号密码,经过spaceship与Apple交互,并会产生一份有效期一个月的cookies文件:文件地址: ~/.fastlane/spaceship/[email]/cookie (两步验证问题)
3.Matchfile: match 这个action的配置文件,fastlane match init 自动生成,存放git地址等
lane是fastfile中的方法定义标签,能够理解为swift中定义一个函数,前面的 func。fastlane 都是基于ruby,因此fastfile中也是使用ruby语法的。
定义一个简单的无参lane
lane :package puts "这是一个lane" end
定义一个带参的lane,在fastfile中option相似于一个字典集。咱们能够经过 option[:configuration] 取其中value
lane :package do |option| configuration = option[:configuration] puts configuration end //lane的调用 package(configuration: 'Release', export_method: 'ad-hoc')
除开咱们自定义fastfile中的方法,fastlane还提供了不少已经写好的独立的方法库,也就是Actions。
Action是Fastlane自动化流程中的最小执行单元,直观上来说就是Fastfile脚本中的一个个命令,而这些命令背后都对应一个用Ruby编写的脚本。
到目前为止,Fastlane的工具集大约包含180多个Action,基本上涵盖了打包,签名,测试,部署,发布,库管理等等移动开发中涉及到的内容。
fastlane actions : 查看action列表 fastlane action action_name:查看具体action 描述
Action列表文档: Actions
咱们经常使用的主要包括下面几部分,其余action的使用能够参考官方文档:
scan
release状况下没法正常运行scan,须要手动去Build Setting中更改enable Testability 在release 下的状态,改成 yes才能够运行。可是官方不建议作release下开启,Test通常在development configuration 下执行。
match
一个新的证书和配置文件管理工具。它会把全部须要用到的证书传到git私有库上,任何须要配置的机器直接用match同步回来就不用管证书问题了。保证你们用的都是同一份。不过咱们通常都是一台机器须要用到distribution证书,因此意义不大。 1.match只认识经过match方式建立的pp文件 证书,其余方式建立的不予理会。 2.使用match 须要先撤销如今的证书。 3.若是苹果端的证书,pp文件已删除,那么远端git上的文件也会失效,而且在从新match的时候会失败,好像就只能删光 git端内容,从新match一遍。 经常使用参数: git_url : 指定对应git地址 git_branch : 指定对应branch type :请求文件类型, appstore, adhoc, development, enterprise app_identifier : app_bundle_identify clone_branch_directly : 只更新对应branch,只有在存在这个branch时才生效 force_for_new_devices : 若是设备devices列表更新了,就强制更新配置概要文件 verbose :打印出额外的信息和全部的命令
gym
经常使用参数: scheme :指定打的哪一个scheme project :指定project (未使用cocopods) workspace :指定workspace (使用cocopods) clean :打包前clean xcargs : 附加一些参数传递给xcodebuild 如: xcargs: 'DEBUG_INFORMATION_FORMAT="dwarf-with-dsym"', export_method :出包方法 app-store, ad-hoc, package, enterprise, development configuration : 指定构建App的配置 Release、Debug、自定义 output_directory : 输出目录 output_name :输出名称 include_symbols :是否包含调试符号 include_bitcode :是否开启bitcode 纯swift工程打包,在非appstore证书下签出来的包都缺乏一个swiftsupport文件夹,里面放的是swift的支持库。
deliver
用于直接发包到appstore,能够选择跳过图片和元数据上传,只提包,后面再配图和数据:以下 skip_screenshots 和 skip_metadata 参数 deliver( ipa: "#{OUTPUT_DIRECTORY}" + "/" + "#{IPA_NAME}", skip_screenshots: true, skip_metadata: true )
pilot
用于发布testflight内部测试,属于testflight action的别名 经常使用参数: ipa :要提交的包地址 team_name、team_id :若是有多个team 用于区分team skip_waiting_for_build_processing : 在提交完成后的等待是否跳过,通常跳过 changelog testflight( ipa : '../xx.ipa' )
spaceship [常见问题官方解释]
spaceship其实通常fastfile中不会使用到,可是因为涉及到与ADC的通讯,会出现一些奇奇怪怪的问题,因此对它也要有一点了解。 当第一次使用fastlane安装的时候,会要求输入帐号密码核实你的身份来链接ADC,这个时候你提供的登陆验证会处理为会话存到 spaceship 的 cookie,会话大概一个月有效期,一个月后失效,一般咱们只有在打包失败后才会发现这个问题。
上面提到的这些action都是经常使用的,正常打包流程必不可少的部分,还有一些经常使用于辅助做用的Action
resign :从新签名
fastlane sigh resign dev.ipa --signing_identity "证书ID" -p “dev.mobileprovision"
以上两个都须要先配置好xcode, 配置文档
因为开发需求各自不一样,已有的action不知足的状况下,Fastlane支持定义本身的Action。Fastlane为咱们提供了现成的模板,即便你对Ruby的语法不熟悉,也没有关系,Fastlane是开源的嘛,能够直接下载源码看看别人的Action是怎么写的就知道了,咱们能够在这个目录下找到全部的Action文件:
假设,咱们针对pod的执行建立一个action来针对下面三种状况的执行
pod install --no-repo-update (避免master repo的每次更新耗时) pod update --no-repo-update (避免master repo的每次更新耗时) pod repo update XXX (私有repo的更新)
自定义Action的流程大约以下,首先,咱们在终端中执行命令:
fastlane new_action
而后根据提示,在命令行中敲入action的名字pod,而后Fastlane会在当前目录的actions文件夹中帮咱们建立了一个pod.rb的Ruby文件 (此处只有部分代码)
module Fastlane module Actions module SharedValues POD_CUSTOM_VALUE = :POD_CUSTOM_VALUE end class PodAction < Action def self.run(params) UI.message "Parameter API Token: #{params[:api_token]}" end ...... def self.available_options # Define all options your action supports. end ......
能够看到,自定义的Action都是隶属于Fastlane/Actions这个module,而且继承自Action这个父类。虽然模板中的内容还挺多,不过不用担忧,大部份内容都是一些简单的文本描述,对于咱们来讲只须要重点关注这两个方法就行:
最终写完结果以下:
module Fastlane module Actions module SharedValues POD_INSTALL_CUSTOM_VALUE = :POD_INSTALL_CUSTOM_VALUE end class PodInstallAction < Action def self.run(params) repo = "-no-repo-update" command = [] command << "pod install" if params[:repo_update] repo = "--repo-update" end command << repo if params[:verbose] command << "--verbose" end result = Actions.sh(command.join(' ')) UI.success(command.join(' ') + " Successfully ") return result end def self.description "pod install action" end def self.details "verbose / repo-update" end def self.available_options [ FastlaneCore::ConfigItem.new(key: :verbose, description: "Allow output detail in console", optional: true, is_string: false, default_value: false), FastlaneCore::ConfigItem.new(key: :repo_update, description: "Allow output detail in console", optional: true, is_string: false, default_value: false) ] end def self.output end def self.return_value end def self.authors ["yang"] end def self.is_supported?(platform) platform == :ios end end end end
远程引用
# 远程Git引用: import_from_git(url: 'https://github.com/xilankong/ruby', branch: 'master') # 复写发布项目的lane lane :do_deliver_app do |options| # ... end
本地引用
import "../GeneralFastfile" actions_path '../custom_actions_folder/' lane :appstore do |options| # ... end
咱们在使用Fastlane的时候经常会遇到这样的场景:
此时,拷贝粘贴虽然能够解决问题,但并非一个聪明的方案。将Action发布到Fastlane的官方仓库却是一个不错的选择,可是官方仓库自己对Action的要求比较高,并不会接收非通用性的Action,即便接收了,整个发布周期也会比较长,并且之后不管是升级仍是Bug修复,都依赖Fastlane自己的发版,大大下降了灵活性。
因此从1.93开始,Fastlane提供了一种Plugin的机制来解决这种问题。你们能够理解为:Plugin就是在Action的基础上作了一层包装,这个包装巧妙的利用了RubyGems这个至关成熟的Ruby库管理系统,因此其能够独立于Fastlane主仓库进行查找,安装,发布和删除。
咱们甚至能够简单的认为:Plugin就是RubyGem封装的Action,咱们能够像管理RubyGems同样来管理Fastlane的Plugin。
可是,若是为了多项目共享任务,或者共享fastfile,能够经过Action的远程引用机制。因此Plugin不过多介绍。
1.monkey
2.ftp 提交远程服务器 (已解决)
3.测试日志解析
4.jira提交bug
5.自动打framework (已解决)
gem ruby源已更新为 https://gems.ruby-china.com,本机版本2.7.7
$ gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/ $ gem sources -l https://gems.ruby-china.com # 确保只有 gems.ruby-china.com
如下是以前2.3.1正常安装的时候的操做:
rvm安装 curl -L get.rvm.io | bash -s stable 安装成功后、启用rvm source ~/.bashrc source ~/.bash_profile 测试安装结果 rvm -v 升级ruby rvm install 2.3.1 查看安装的全部ruby rvm list 切换ruby rvm use 2.3.1 设置rvm默认版本 rvm --default 2.3.1 fastlane 安装: sudo gem install -n /usr/local/bin fastlane
在10.13上安装ruby 2.4.0的时候出现一个问题,因为ssl3的无问题,ruby镜像一直没法下载
No binary rubies available for: osx/10.13/x86_64/ruby-2.4.0. ruby curl: (35) error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
初步怀疑ssl问题,但具体解决方案没找到
选择离线安装的办法
好比Mac自带的Ruby版本不符合你的需求,通常会使用RVM从新装一个Ruby版本,可是这样致使
Jenkins中获取不到在目标服务器安装的最新RVM 和 ruby、fastlane、cocoapods等
解决方案 :
~/.bashrc 、~/.zshrc 、~/.zlogin 内容
PATH=$PATH:$HOME/.rvm/bin [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM
在jenkins执行脚本内 启用RVM:
source $HOME/.rvm/scripts/rvm 或者 source ~/.bashrc
解决办法二:
新版本的Jenkins能够安装 RVM 插件,具体能够百度,而后配置里填写上你打包机当前用户配置的RVM版本便可
开启两步验证后,提交testfilght或者appstore会出现以下提示,要求手动确认并 输入6位code
Two Factor Authentication for account 'xxxxx@xx.com' is enabled If you're running this in a non-interactive session (e.g. server or CI) check out https://github.com/fastlane/fastlane/tree/master/spaceship#2-step-verification Please enter the 6 digit code:
这样明显影响全自动化提交操做。
解决方案:
fastlane提供的两步验证解决方案:
1.访问 https://appleid.apple.com/account/manage 2.生成一个 APP-SPECIFIC PASSWORDS,保留生成的特殊密码 3.使用环境变量提供这个密码给fastlane: FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD 4.执行fastlane spaceauth -u user@email.com,生成session cookie。 5.经过环境变量FASTLANE_SESSION 提供session cookies。 配置地方: 打包机:~/.bash_profile 中,配置 FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD 和 FASTLANE_SESSION 例如: export FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD=特殊密码 export FASTLANE_SESSION=session cookie 本机使用的是Item2 /bin/zsh 因此配置在 ~/.bash_profile Jenkins:配置对应环境变量便可 还有一个小伙伴告知另外一个配置方式 ENV["FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD"] = "xxxxxx" 这个和环境变量配置是一个意思,可是涉及密码写在配置文件里面 可是,本文测试一个月后发现依然失效,最后选择的方案是开设一个未开启两步验证的帐号做为开发帐号的子帐号专门用来打包。 若有不过时方式,欢迎补充
在执行gym的时候出现如上问题,或者跑fastlane action gym的时候出现 解决办法:终端命令 rvm @global do gem uninstall fastlane rvm all do gem uninstall fastlane gem uninstall fastlane gem install fastlane sudo gem install fastlane (jenkins权限问题) 例子: rvm @global do gem uninstall fastlane Select gem to uninstall: 1. fastlane-2.47.0 2. fastlane-2.49.0 3. fastlane-2.51.0 4. fastlane-2.53.1 5. fastlane-2.55.0 6. fastlane-2.57.2 7. fastlane-2.58.0 8. fastlane-2.62.1 9. fastlane-2.85.0 10. fastlane-2.86.2 11. All versions > 11 Successfully uninstalled fastlane-2.47.0 Successfully uninstalled fastlane-2.49.0 Successfully uninstalled fastlane-2.51.0 Successfully uninstalled fastlane-2.53.1 Successfully uninstalled fastlane-2.55.0 Successfully uninstalled fastlane-2.57.2 Successfully uninstalled fastlane-2.58.0 Successfully uninstalled fastlane-2.62.1 Successfully uninstalled fastlane-2.85.0 Remove executables: bin-proxy, fastlane in addition to the gem? [Yn] y Removing bin-proxy Removing fastlane Successfully uninstalled fastlane-2.86.2 [10:42:40] young:~ $ rvm all do gem uninstall fastlane Select gem to uninstall: 1. fastlane-2.80.0 2. fastlane-2.85.0 3. All versions > 3 Successfully uninstalled fastlane-2.80.0 Remove executables: bin-proxy, fastlane in addition to the gem? [Yn] y Removing bin-proxy Removing fastlane Successfully uninstalled fastlane-2.85.0 [10:42:55] young:~ $ gem uninstall fastlane [10:43:01] young:~ $ gem install fastlane Fetching: fastlane-2.86.2.gem (100%) Successfully installed fastlane-2.86.2 Parsing documentation for fastlane-2.86.2 Installing ri documentation for fastlane-2.86.2 Done installing documentation for fastlane after 23 seconds 1 gem installed
fastfile 部分
#声明 APP_NAME = “XXX” WORKSPACE = “XXX.xcworkspace" SCHEME = “XXX” IPA_TIME = Time.now.strftime("%Y%m%d_%H%M") OUTPUT_DIRECTORY = "packages" APP_INFO_PLIST_PATH = ‘./XXX/Info.plist' ENV_PREFIX="" IPA_NAME = "" platform :ios do # before_all do xcode_select "/Applications/Xcode.app" FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT = "40" end #debug包 lane :iosDebug do ENV_PREFIX="debug_" EXPORT_METHOD = "development" package(configuration: "Debug") end #release包 lane :iosRelease do ENV_PREFIX="adhoc_" EXPORT_METHOD = "ad-hoc" package(configuration: "Release") end #发布包 lane :iosAppStore do ENV_PREFIX="appstore_" EXPORT_METHOD = "app-store" package(configuration: "Release") end #打包函数 lane :package do |option| cocoapods PLIST_INFO_VERSION = get_version_number(target: "#{SCHEME}") PLIST_BUILD_VERSION = get_info_plist_value(path: "#{APP_INFO_PLIST_PATH}", key: 'CFBundleVersion') IPA_NAME = "#{ENV_PREFIX}" + "#{APP_NAME}_" + "#{IPA_TIME}_" + "#{PLIST_INFO_VERSION}" +"_#{PLIST_BUILD_VERSION}"+ ".ipa" #打包 gym( scheme: "#{SCHEME}", export_method: "#{EXPORT_METHOD}", configuration: option[:configuration], output_directory: "#{OUTPUT_DIRECTORY}", include_symbols: true, include_bitcode: false, xcargs: 'DEBUG_INFORMATION_FORMAT="dwarf-with-dsym"', output_name: "#{IPA_NAME}", export_xcargs: "-allowProvisioningUpdates" ) xcclean( workspace: "#{WORKSPACE}", scheme: "#{SCHEME}" ) end
Jenkins部分脚本
#!/bin/bash -l sh ./script/fastlane.sh "Debug"
fastlane.sh部分脚本
#解决ArgumentError - invalid byte sequence in US-ASCII错误 #修改终端语言、地区等国际化环境变量 export LANG=en_US.UTF-8 export LANGUAGE=en_US.UTF-8 export LC_ALL=en_US.UTF-8 export PATH=$PATH:/usr/local/bin #更换ruby环境,对应的修改有 打包机下面的 .bashrc .zshrc .zlogin source $HOME/.rvm/scripts/rvm #source ~/.bashrc #解锁keychain,是其它工具能够访问证书,解锁后设置keychain关闭时间为1小时, xxx为用户名 security -v unlock-keychain -p "xxx" "/Users/xxx/Library/Keychains/login.keychain" security set-keychain-settings -t 3600 -l "/Users/xxx/Library/Keychains/login.keychain" /usr/local/bin/pod update --verbose --no-repo-update # fastlane profile if [[ $1 == "Debug" ]]; then fastlane iosDebug elif [[ $1 == "Release" ]]; then fastlane iosRelease elif [[ $1 == "TestFlight" ]]; then fastlane iosTestFlight elif [[ $1 == "AppStore" ]]; then fastlane iosAppStore fi