更新節點: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