和重複勞動說再見-使用fastlane進行iOS打包

寰宇發表於2018-02-09

fastlane00

背景

初識fastlane

fastlane是一個通過簡單命令來完成諸如截圖、獲取證書、編譯、匯出安裝包、提交iTunesConnect等一系列操作的工具,它同時支援iOS和Android。 你能夠通過簡單的方式配置流程進行的順序,並通過非常簡單的命令執行其中的一個流程。當然它的簡單並不代表功能也簡陋,有開源社群的支援,更新迅速且有很多功能能夠滿足你的需求。

fastlane01

為什麼使用它

之前我們使用的是jenkins內的Xcode integration進行編譯工作,但是其更新比較慢(至2017.12.20還未支援Xcode9),Xcode大版本更新後出現無法繼續使用的問題。 後改用fastlane,發現其使用和配置還算簡單,有開源社群支援,更新迅速功能強大。且相比jenkins裡的外掛,fastlane可以單獨使用,也可以被多種CI接入

配置使用環境

fastlane使用的是ruby環境且對ruby有版本要求(官網要求是ruby2.0以上),所以如果需要的話更新一波ruby,然後通過gem安裝fastlane。

更新ruby

更新ruby使用的是RVM工具,在命令列進行如下操作,安裝時可能出現進度不動,多半可能是因為被牆了。

#安裝RVM工具
RVMcurl -L get.rvm.io | bash -s stable

#列出可安裝的ruby版本(有原始的ruby也有其他版本的版本)
rvm list known

#根據剛才列出的ruby版本,安裝一個ruby版本
rvm install ruby-xxxxx(xxx為版本號) 
複製程式碼

列出來ruby的版本,選擇#MRI Rubies這一大類下面的,我裝的是2.4的版本

fastlane02

因為我之前已經安裝過了,所以提示是已經安裝成功

fastlane03

安裝fastlane

如果ruby版本滿足要求,可以直接在命令列執行以下命令安裝fastlane,這個安裝比較順利沒出現報錯,如果有報錯可以根據原因搜尋一下解決辦法。

#安裝fastlane
sudo gem install -n /usr/local/bin fastlane
複製程式碼

配置fastlane

使用的環境搭建好了,就可以進行這一步來配置fastlane了。

初始化

執行預設的初始化

cd 專案目錄
fastlane init
複製程式碼

根據提示輸入資訊,這一步我沒有按照提示處理,因為在有多個BundleID多個target的工程上使用,實際上生成的配置還是要修改的。

如果你的專案只有一個bundle id也只有一個開發者賬號的話,可以直接遵循官方的步驟配置。

fastlane06

初始化完成後可以看到專案目錄裡多出了一個fastlane資料夾,內有兩個比較重要的檔案AppfileFastfile

fastlane07
fastlane08

大致流程

通過在命令列執行fastlane [lane-name]以執行fastlane/Fastfile中的一個lane。 這個操作會依次從.env檔案Appfile檔案Deliverfile檔案讀取配置資訊,最後由Fastfile中的邏輯來進行工作。

配置和使用

fastlane可以通過配置 .env檔案、Appfile、Deliverfile、Fastfile 來完成各種工作。

其中Fastfile是最核心的用來控制流程走向的配置檔案,.env和Appfile可以輔助Fastfile來設定一些引數,Deliverfile可用於配置提交iTunesConnect的一些引數。

需要檢視,樣例配置可直接前往下載樣例配置

Appfile

Appfile是用來配置一些類似於AppleID、BundleID引數(引數是fastlane已經定義好的,新增的並沒有用,如果想新增變數需要使用.env方式),可以在Fastfile中使用,AppleID、BundleID等其實會被一些actions直接呼叫,並不需要寫出來傳遞。

普通配置方式

直接在Appfile裡填寫app_identifier、apple_id、team_id等,然後根據lane的不同可以設定成不同。

# 預設配置
app_identifier    "com.devhy.test"
apple_id    "devhy1@xxxx.com"
team_id    "xxxxxxxxx1"

# 如果lane是ent換成Dev的配置
for_lane :ent do
  app_identifier    "com.devhy.testDev"
  apple_id    "devhy2@xxxx.com"
  team_id    "xxxxxxxxx2"
end
複製程式碼

使用.env配置方式

.env這個檔案的作用是作為環境變數的配置檔案,在fastlane init進行初始化後並不會自動生成,如果需要可以自己建立。

執行時預設會讀取.env.env.default檔案裡的配置。通過執行fastlane [lane-name] --env [envName]來指定使用配置檔案.env.[envName],讀取順序是.env -> .env.default -> .env.<envName>,相同的變數名會被後面的覆蓋。

如我建了檔案.env.myDev,裡面寫了一些引數,那在執行的時候使用fastlane [lane-name] --env myDev即可,想在Appfile、Deliverfile、Fastfile等呼叫,直接使用ENV['keyName']即可

# .env.myDev檔案
# bundle id
App_Identifier = "com.devhy.testDev"
# 開發者賬號
Apple_Id = "xx2@xxxx.com"
# 開發者TeamId
Team_Id  = "xxxxxxxxx2"
# project的target scheme名稱
Scheme   = "HYTestDev"
複製程式碼
# Appfile使用.env方式直接讀取變數即可
app_identifier	 ENV['App_Identifier']
apple_id 		 ENV['Apple_Id']
team_id			 ENV['Team_Id']
複製程式碼

注意:因為是.env檔案是.開標頭檔案,預設是在finder中隱藏的,需要通過執行一下命令來顯示

# 設定隱藏檔案可見
defaults write com.apple.finder AppleShowAllFiles TRUE
# 重啟finder服務以生效
killall Finder
複製程式碼

配置方式對比

普通配置方式:簡單易懂,但不能自定義變數,且每個lane想不一樣都要寫一個for_lane .env配置方式:功能性強,但配置起來稍微麻煩一點

Deliverfile

Deliverfile是用來配置上傳到iTunesConnect所需資訊的,由於我們主要用fastlane來打包,釋出是手動將ipa包提交稽核,由於沒有進行過嘗試所以該檔案配置方式就不敘述了。

Fastfile

Fastfile是對流程進行控制的核心檔案,需要設定支援的平臺和在一些環節裡需要做的事情。

基本結構

Fastfile主要是根據設定的平臺,可以在before_all、after_all、error中做一些操作 以及 建立一些lane作為關鍵的執行邏輯,可以在其中使用fastlane內建的action,也可以呼叫自建action,還可以呼叫別的lane

# 因為fastlane存在新老版本相容問題,所以一般會指定fastlane版本
fastlane_version "2.62.0"
default_platform :ios

platform :ios do
  # 所有lane執行之前,可以做如執行cocoapods的pod install
  before_all do
    cocoapods
  end
  
  # 名字叫ent的lane,命令列裡執行fastlane ent
  lane :ent do
    # 執行一些action,如cert下載證書,sigh下載pp檔案,gym進行編譯和匯出包
  end

  # 執行fastlane store即可
  lane :store do
    # 呼叫一些action
    
    # 呼叫別的lane,比如send_msg
    send_msg
  end
  
  lane :send_msg do
    # 呼叫一些action
  end
  
  # 所有lane完成之後,可以適用引數lane來區分
  after_all do |lane|
  end
	
  # 所有lane失敗之後,可以適用引數lane來區分
  error do |lane, exception|
  end
end
複製程式碼

Fastfile樣例

下面的Fastfile樣例是配置了.env+Appfile後進行編寫,因為這樣在配置action時,可以省去一些入參。 因為使用了Appfile,cert的username、team_id 以及 sigh的app_identifier、username、team_id 可以不用傳入了,fastlane在執行時會自己去從Appfile裡取。以及之前在.env環境配置中設定了一個Scheme的欄位,那麼gym的scheme我們可以使用ENV['Scheme']來呼叫。

fastlane_version "2.62.0"
default_platform :ios

platform :ios do

  before_all do
    cocoapods
  end

  lane :store do
    # action(cert),下載[開發者證書.cer]
    # 下載的檔案會存在專案根目錄的build資料夾下
    # fastlane會讓你在命令列登入開發者賬號,登入成功後,會在你的[鑰匙串]中建立一個 {deliver.[username]} 的登入賬戶
    cert(
      # Appfile設定了這邊就可以不用了
      # username: "devhy2@xxxx.com",
      # team_id: "xxxxxxxxx2",
      
      # 下載.cer檔案的位置
      output_path: "build",
    )

    # action(sigh),下載[安裝app匹配的Provision Profile檔案(pp檔案)]
    # 建議自己去蘋果開發者網站證書中手動處理一波provision_profile
    # 建議用 bundleId_匯出方式 來命名比如: 
    #     企業包pp檔案叫 testDev_InHouse.mobileprovision
    sigh(
      # Appfile設定了這邊就可以不用了
      # app_identifier: "com.devhy.testDev",
      # username: "devhy2@xxxx.com",
      # team_id: "xxxxxxxxx2",

      # 下載pp檔案的位置
      output_path: "build",
      # 自動下載簽名時,adc裡pp名字,不寫也可以會根據你的bundle id、adhoc與否去下載最新的一個
      # provisioning_name: "testDev_InHouse", 
      # 僅下載不建立,預設是false
      readonly: true, 
      # 因為是根據BundleID下載,導致adhoc和appstore會優先appstore,導致最後匯出報錯,如果是adhoc包請設定為true
      adhoc: true, 
    )

    # 編譯配置,編譯的scheme,匯出包方式
    gym(
      # 使用.env配置的環境變數
      scheme: ENV['Scheme'],
      # app-store, ad-hoc, package, enterprise, development, developer-id
      export_method: "enterprise", 
      # 輸出日誌的目錄
      buildlog_path: "fastlanelog",
      # 輸出編譯結果
      output_directory: "build",
      include_bitcode: false
    )
  end
  
  after_all do |lane|
  end

  error do |lane, exception|
  end
end
複製程式碼

actions

在fastlane中使用的諸如cer()、sigh()、gym()都是action,其本質是預先寫好的ruby指令碼(如:sigh.rb),fastlane中有很多已經寫好的actions,當然也可以自己進行編寫。

命令列常用的操作有:

  1. 檢視所有Action fastlane actions
  2. 檢視某個Action的引數說明 fastlane action [action_name]如(fastlane action gym)

配置後的使用

編寫完各種配置後怎麼使用?其實使用方法還是比較簡單的, 不使用.env配置,執行fastlane [lane_name]即可 使用某個.env配置,執行fastlane [lane_name] --env [env_name]即可

比如我在需要執行樣例的Fastfile的store,並使用.env.myDev配置,那我可以執行fastlane store --env myDev

進階使用

options引數傳遞

在執行shell指令碼之類的都是可以傳遞一些引數的,fastlane也是有的,options就是儲存了我們在命令列中執行lane時傳遞的引數的字典,在befor_allafter_all、各種lane裡都可以使用這個options

傳遞引數

# 使用key:value來傳遞一組對應的引數
fastlane ent key:value key2:value2
複製程式碼

接收引數

platform :ios do 
  before_all do |lane, options|
    #options引數
    value  = options[:key]
    value2 = options[:key2]
  end
  
  lane :ent do
  ...
  end
end
複製程式碼

private_lane

私有lane其實就像開發的時候的私有方法一樣,外部是使用不到的,如在命令列中使用fastlane deal_param是執行不了的,但在Fastfile內部可以呼叫到。

platform :ios do 
  # 相當於全域性變數
  build_config = "debug"

  before_all do |lane, options|
    # 呼叫私有lane deal_param 並將options傳遞過去
    deal_param options
  end
  
  lane :ent do
  # ...
  end
  
  # 私有lane,比如把傳入的build引數進行一下處理
  private_lane :deal_param do |options|
    build_config = build_config ? build_config : "debug"
    build_config.capitalize!
  end
end
複製程式碼

自建Action

執行fastlane new_action,命令列提示輸入自建的action名稱,輸入後fastlane會幫助生成一個action編寫的模版ruby檔案,在模版中編寫自己的Action邏輯,具體因為暫時沒有寫過,請檢視官方的文件。

與jenkins搭配使用

因為fastlane可以在命令列中使用,所以只要在jenkins中,構建的一些環節中使用Excute Sell方式,然後輸入fastlane相關的命令即可了。

fastlane-10

附錄

下載樣例配置

AppFile + Fastfile .Env + AppFile + Fastfile + Options傳遞引數

參考資料

fastlane - Github fastlane - 官方文件

相關文章