Fastlane實(shí)戰(zhàn)(五):高級(jí)用法

經(jīng)過(guò)前4篇文章的基礎(chǔ)知識(shí)和不同的場(chǎng)景介紹后,相信大家已經(jīng)對(duì)Fastlane有了一個(gè)較為完整的認(rèn)識(shí),同樣,今天我還是結(jié)合幾個(gè)實(shí)際的場(chǎng)景,來(lái)講講Fastlane的一些高級(jí)用法。

前言

軟件開(kāi)發(fā)就像是完成一件藝術(shù)品一樣,是一個(gè)循序漸進(jìn),不斷打磨的過(guò)程。剛開(kāi)始的時(shí)候由于我們對(duì)某個(gè)語(yǔ)言或框架了解的不夠充分,所以往往只停留在實(shí)現(xiàn)功能的階段,而不會(huì)過(guò)多的考慮到是否能夠有更好的特性和更高效的方法來(lái)解決問(wèn)題。

隨著編程經(jīng)驗(yàn)的積累和對(duì)語(yǔ)言框架的日益了解,發(fā)現(xiàn)之前寫(xiě)過(guò)的很多代碼其實(shí)都存在不少問(wèn)題,都有不少優(yōu)化和提升的空間,于是出于責(zé)任心和對(duì)編程的熱愛(ài),我們一定會(huì)花時(shí)間不斷的重構(gòu)和優(yōu)化代碼,直到自己滿意為止。

使用Fastlane的過(guò)程也同樣如此,在第一次發(fā)現(xiàn)了這樣一個(gè)新工具時(shí),心中莫名的興奮,于是不管三七二十一,立刻就動(dòng)手使用了,然后隨著使用的場(chǎng)景增多,問(wèn)題也逐漸凸顯了出來(lái),于是我們開(kāi)始探尋Fastlane的一些高級(jí)用法,以便更高效,更優(yōu)雅的解決問(wèn)題。

前置和后置Action

一般情況,我們?cè)谔幚韎OS的自動(dòng)化流程時(shí),會(huì)面臨著單元測(cè)試,庫(kù)編譯發(fā)布,APP打包等等多種不同的場(chǎng)景,而APP打包又需要區(qū)分不同的環(huán)境,比如:Test,Adhoc和AppStore,而這些場(chǎng)景和環(huán)境的處理方式是有所不同的,所以針對(duì)每種情況,我們都需要編寫(xiě)對(duì)應(yīng)的Lane,比如我們新建一個(gè)名叫ios_fastfile的文件,內(nèi)容如下:

# 單元測(cè)試的Lane
lane :test do |options|
  git_pull
  cocoapods
  xctest
end

# AdHoc環(huán)境打包的Lane
lane :adhoc do |options|
  git_pull
  cocoapods
  increment_build_number
  gym
  upload_to_fir
end

# AppStore環(huán)境打包的Lane
lane :appstore do |options|
  git_pull
  cocoapods
  increment_build_number
  gym
  deliver
end

當(dāng)然以上的這個(gè)些Lane都是簡(jiǎn)寫(xiě),只是個(gè)示意,實(shí)際情況會(huì)復(fù)雜的多。從這些Lane中我們可以看到,每個(gè)流程其實(shí)都有前置的條件:

  1. git pull最新的代碼
  2. 更新最新的cocoapods依賴

所以,大家肯定會(huì)問(wèn),是否有類(lèi)似Ruby on Rails中controller的前置過(guò)濾器之類(lèi)的機(jī)制,能夠方便的處理這個(gè)情況。答案是肯定的,類(lèi)似這樣,在一個(gè)Fastfile中,每個(gè)Lane共有的前置流程的情況,我們可以借助Fastlane提供的before_all方法來(lái)處理,在ios_fastfile中我們?cè)黾尤缦碌拇a:

before_all do |lane, options|
  git_pull
  cocoapods
end

before_all顧名思義,就是在在執(zhí)行每個(gè)方法之前首先執(zhí)行的代碼,使用before_all我們可以將ios_fastfile的代碼就可以簡(jiǎn)化為:

before_all do |lane, options|
  git_pull
  cocoapods
end

# 單元測(cè)試的Lane
lane :test do |options|
  xctest
end

# AdHoc環(huán)境打包的Lane
lane :adhoc do |options|
  increment_build_number
  gym
  upload_to_fir
end

# AppStore環(huán)境打包的Lane
lane :appstore do |options|
  increment_build_number
  gym
  deliver
end

嗯,看上去代碼簡(jiǎn)化不少,而且以后要添加公用的前置代碼,都可以放在before_all中進(jìn)行處理,維護(hù)起來(lái)非常方便。

另外,Lane本身和使用到的Options參數(shù)們也可以很方便的傳遞給before_all方法,這樣可以更加方便的處理各種特殊情況,比如:有的Lane沒(méi)有處理git_pull的流程,那么我們只需要在方法中加一個(gè)判斷即可。

當(dāng)然,除了before_all之外,F(xiàn)astlane還提供after_all來(lái)處理共有的后置邏輯,比如:我們?cè)谒械膌ane之后,要通過(guò)Slack或Hipchat通知到相關(guān)的工程師們,那么我們就可以把這些action寫(xiě)在after_all方法中。

after_all do |lane,options|
    slack(message: "fastlane was successful", success: true)
end

對(duì)于每個(gè)Lane在執(zhí)行過(guò)程中,如果遇到錯(cuò)誤,我們也需要通過(guò)Slack或Hipchat等工具通知到大家,此時(shí),我們可以在Fastfile中添加一個(gè)全局的error方法:

error do |lane, exception|
  slack(message: exception.message, success: false)
end

引用機(jī)制

當(dāng)一項(xiàng)新的技術(shù)在團(tuán)隊(duì)內(nèi)部引入的時(shí)候,往往會(huì)從一個(gè)非主業(yè)務(wù)的項(xiàng)目中進(jìn)行灰度嘗試。我們也不例外,所以我們首先將Fastlane引入到我們的醫(yī)生版的iOS客戶端中,使用一段時(shí)間感覺(jué)不錯(cuò)之后,就推廣到了Android平臺(tái)和用戶版客戶端中,最后引入到各種私有庫(kù)項(xiàng)目的管理中。目前大約涉及到了30多個(gè)項(xiàng)目,在這個(gè)過(guò)程中,我們發(fā)現(xiàn)了兩個(gè)問(wèn)題:

  1. 由于我們自定義了很多action,那么這些action都需要拷貝到各個(gè)項(xiàng)目的fastlane目錄中,這樣就導(dǎo)致了一個(gè)維護(hù)的問(wèn)題,即:添加或修改任意的自定義action,都需要去各個(gè)項(xiàng)目中處理一遍。
  2. 我們目前的項(xiàng)目按類(lèi)型分為4種:iOS App,iOS Pod庫(kù),Android App,Android AAR庫(kù),對(duì)于同樣的項(xiàng)目類(lèi)型,lane的處理流程基本上是一樣的,所以每個(gè)相同類(lèi)型的項(xiàng)目的Fastfile基本上都是一致的,這就帶來(lái)了和1一樣的問(wèn)題:如果要修改任意一個(gè)項(xiàng)目的Fastfile,那么就意味著同樣也得修改其它同類(lèi)型項(xiàng)目中Fastfile,因?yàn)檫@些Fastfile都是放在各自項(xiàng)目目錄下的fastlane文件夾中的。

剛開(kāi)始項(xiàng)目比較少的時(shí)候,手工還可以處理,當(dāng)項(xiàng)目逐漸增多的時(shí)候,問(wèn)題就愈發(fā)嚴(yán)重了,不但要改的地方多,而且還容易出錯(cuò),于是我們思考是否有能夠由一種引用的機(jī)制存在,能夠在頂層維護(hù)一份公用的action和fastfile,這樣在項(xiàng)目中只需要引入這些頂層的文件們就能解決上面的問(wèn)題。

經(jīng)過(guò)仔細(xì)研究Fastlane的特性之后,我們發(fā)現(xiàn)這個(gè)問(wèn)題早就在其作者的考慮之中了。Fastlane不但提供了引用機(jī)制import,還提供了遠(yuǎn)程引用模式,即:import_from_git。

有了這個(gè)機(jī)制之后,我們不但可以在將自定義action們和Fastfile們統(tǒng)一管理,而且還可以放在git上進(jìn)行遠(yuǎn)程分布式管理,其帶來(lái)的好處就是:各個(gè)項(xiàng)目只需要在自己的Fastfile的頂部進(jìn)行引用聲明即可:

# 遠(yuǎn)程Git引用:
import_from_git(url: 'https://github.com/GengmeiRD/Fastfiles', branch: 'master')

lane :appstore do |options|
  # ...
end

這樣,每次執(zhí)行fastlane的命令時(shí),首先會(huì)從git上將需要的文件clone這個(gè)項(xiàng)目到本地的臨時(shí)文件夾中,然后再執(zhí)行相關(guān)命令。當(dāng)然,如果某個(gè)項(xiàng)目中,你不想使用遠(yuǎn)端上的某個(gè)lane,而是需要自定義一份,那么只需要在項(xiàng)目中的Fastfile中復(fù)寫(xiě)這個(gè)lane即可:

# 遠(yuǎn)程Git引用:
import_from_git(url: 'https://github.com/thierryxing/Fastfiles', branch: 'master')

# 復(fù)寫(xiě)發(fā)布項(xiàng)目的lane
lane :do_deliver_app do |options|
  # ...
end

當(dāng)然,如果你覺(jué)得遠(yuǎn)程管理這些action和fastfile們比較麻煩的話,同樣可以使用本地引用進(jìn)行管理,fastlane提供了兩個(gè)命令,分別用來(lái)引入本地的Fastfile和action目錄:

import "../GeneralFastfile"
actions_path '../custom_actions_folder/'

lane :appstore do |options|
  # ...
end

我們將團(tuán)隊(duì)內(nèi)部使用到的遠(yuǎn)程action和Fastfile管理已經(jīng)發(fā)布到了github上,有興趣的同學(xué)可以參考:
https://github.com/thierryxing/Fastfiles

上下文常量

在使用Fastlane的過(guò)程中,我們往往需要一些和上下文相關(guān)的常量,比如:AppStore的賬號(hào)和密碼,ipa和dsym文件的輸出的地址,模擬器或設(shè)備的UDID等等。這些常量如果直接寫(xiě)死在Fastfile中顯然是不利于維護(hù)的。所以我們可以考慮使用以下的方式來(lái)處理:

使用dotenv

首先使用gem安裝dotenv,然后新增一個(gè).env文件,然后將所有用到的常量定義在里面,比如:

WORKSPACE=YourApp.xcworkspace
ITUNESCONNECT_ACCOUNT=your-itunesconnect-account

然后在fastfile中使用ENV進(jìn)行調(diào)用:

lane :appstore do |options|
  increment_build_number
  gym(workspace: ENV['WORKSPACE'])
  deliver(username: ENV['ITUNESCONNECT_ACCOUNT'],)
end

最后將這個(gè).env文件拷貝到和Fastfile的同級(jí)目錄即可。當(dāng)然如果有常量需要在多個(gè)項(xiàng)目中公用的話(比如:iTunesConnect的賬號(hào)),可以建立一個(gè)軟連接指向同一個(gè).env文件,然后在目錄中創(chuàng)建一個(gè).env.default文件,放置本項(xiàng)目下專(zhuān)屬的常量。

使用export命令

如果你使用的是Mac或linux操作系統(tǒng),可以在系統(tǒng)的環(huán)境的變量中使用export命令直接定義系統(tǒng)級(jí)別的常量,當(dāng)然為了不和其它常量沖突,建議增加一個(gè)FASTLANE前綴,比如:

#set env vars
export FASTLANE_WORKSPACE="<YourApp.xcworkspace>"
export FASTLANE_ITUNESCONNECT_ACCOUNT="<your-itunesconnect-account>"

調(diào)用方法和使用.env一樣。

lane :appstore do |options|
  increment_build_number
  gym(workspace: ENV['FASTLANE_WORKSPACE'])
  deliver(username: ENV['FASTLANE_ITUNESCONNECT_ACCOUNT'],)
end

結(jié)語(yǔ)

以上的幾個(gè)高級(jí)用法只是筆者在使用過(guò)程中遇到的一隅,更多的驚喜還等待大家自己去探索去發(fā)現(xiàn),官方文檔中有全面的介紹:https://docs.fastlane.tools/advanced/

Fastlane是一個(gè)持續(xù)維護(hù),快速發(fā)展的工具,從筆者的第一篇文章到現(xiàn)在,短短兩個(gè)月的時(shí)間,F(xiàn)astlane已經(jīng)發(fā)布了20多個(gè)版本,在Github上新增了2000多個(gè)star,同時(shí)又多了100多位工程師加入到了Contributors的大家庭中。事實(shí)再次證明優(yōu)秀的開(kāi)源項(xiàng)目總能得到大家的認(rèn)可,關(guān)注和參與。

本文是Fastlane實(shí)戰(zhàn)系列的第五篇文章也是最后一篇,希望這個(gè)系列的文章能夠真正幫助大家了解Fastlane,也希望看完這個(gè)系列的文章后,有更多的同學(xué)借助Fastlane和各種自動(dòng)化工具來(lái)提升自己的效率,畢竟重復(fù)性的勞動(dòng)和流程化的工作就交給機(jī)器們?nèi)プ霭伞?/p>

最后祝大家使用Fastlane愉快。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容