iOS 持續交付之 Fastlane

轉載自作者:LaiYoung_
鏈接:https://juejin.im/post/5a7b10bb6fb9a0636263bfd5

小目標:使用Jenkins一鍵構建,并自動上傳到App Store

一、為什么選擇 Fastlane?

fastlane是為iOSAndroid應用程序自動化測試部署和發布的最簡單方法。??它處理所有繁瑣的任務,如生成屏幕截圖,處理代碼簽名以及發布應用程序。

使用場景

  • 提交時執行測試(包括單元測試和集成測試)。
  • 構建并分發內部測試,公開測試版本。
  • 構建生產版本并上傳至 ITC(包括更新配置文件,創建新的屏幕截圖,上傳應用并提交審核)。

工具集

fastlane 將如下的工具套件有機地結合起來,從管理證書到單元測試,從編譯打包到上傳發布,都能通過命令行輕松完成.該套件支持與 JenkinsCocoaPods,xctools 等其他第三方工具的集成,并且能夠定義多個通道(lanes)以支持不同的部署目標。

  • 測試工具
    • scan:自動運行測試工具,可以生成漂亮的HTML報告。
  • 生成證書、配置工具
    • cert:自動創建iOS代碼簽名證書(.cert文件)。
    • sigh: 創建、更新、下載和修復 provisioning profiles,支持App Store, Ad Hoc, Development和企業profiles。
    • pem:自動生成、更新推送配置文件。
  • 截圖、上傳、描設備邊框
    • deliver: 上傳截圖、元數據、App到iTunesConnect。
    • snapshot: 依靠 UI Test 完成截圖。
    • frameit: 快速地把應用截圖放入設備框里。
  • 自動化編譯工具
    • gym: 編譯、打包iOS app,生成簽名的ipa文件 。
  • App 公測工具
    • pilot:管理TestFlight測試用戶,上傳二進制文件。
    • firim:管理firim。

二、準備工作,很重要的喲

  1. 配置當前設備環境,最新的fastlane(2.75.1)需要2.1以上的ruby版本,正常的版本低點的,也是要求2.0以上的。因為fastlane工具是使用ruby寫的。版本過低的建議安裝rvm來升級ruby。

    curl -L get.rvm.io | bash -s stable  
    
    source ~/.bashrc  
    source ~/.bash_profile 
    
    # 檢測是否安裝成功
    rvm -v
    
  2. 設置環境變量,fastlane需要設置一些環境變量才能正確運行,如果當前的語言環境沒有設置為UTF-8,會導致構建和上傳的時候出現問題。在~/.bashrc, ~/.bash_profile 或者 ~/.zshrc 文件下添加如下內容:

    export LC_ALL=en_US.UTF-8
    export LANG=en_US.UTF-8
    
  3. 安裝Xcode命令行工具 xcode-select --install,如果已經安裝會提示xcode-select: error: command line tools are already installed, use "Software Update" to install updates。

  4. 創建App ID,證書,在iTunes connect 創建一個用于測試的 app。

  5. 安裝fastlane。

  6. 創建一個測試demo,并將其scheme設置為shared,不然fastlane init的時候會失敗。

三、實踐

fastlane init

  1. cd 到項目目錄下,對于ruby安裝程序,使用命令 sudo fastlane init。(swift使用fastlane init swiftSwift安裝仍在測試階段。有關更多信息,請參閱Fastlane.swift文檔。 )

  2. 會問你想使用fastlane做什么?這里我們輸入3,自動發布到Apple Store

    執行過程中會要求你輸入Apple開發證書的Apple ID,如果有多個Team,會讓你選擇team。

  3. 接著會問是否想用fastlane來管理你的app metadata。

    • 輸入y,fastlane則會下載現有的元數據和屏幕截圖。如果我們編輯了download下來的.txt文件,在使用fastlane上傳app到iTunes connect的時候也會將這些內容上傳到iTunes connect。

    • 輸入n,不做任何操作,仍然能使用fastlane上傳app到App Store。

  4. 如果最后出現fastlane release,就表示init成功了。

  5. 此時項目目錄下會多出一個fastlane的文件夾。

    如果Deliverfile,screenshotsmetadata目錄沒被創建,可以運行deliver init來創建。

Deliverfile文件里,添加force true,不然會在上傳到iTunes connect的時候會彈出一個Preview.html網頁。

使用Gemfile

  1. 在項目根目錄下touch一個Gemfile文件,添加以下內容

    source "https://rubygems.org"
    gem "fastlane"
    
  2. 執行如下命令:

    # 安裝bundler
    sudo gem install bundler
    
    # 更新 bundle,成功之后會生成一個版本控制的Gemfile.lock文件
    [sudo] bundle update
    
  3. 執行命令:bundle exec fastlane [lane_name],執行lane_name腳本。這里的lane_name是腳本的名稱,我們可以理解為函數名,如果我們只執行bundle exec fastlane命令,則會有一個讓我們選擇的地方,選擇需要執行的腳本。

    會將項目名,ipa存放的路徑,app_identifier等一系列信息打印出來。

    ipadYSM文件都存放在項目根目錄。

    緊接著會自動上傳metadataipaiTunes Connect。

    最后會輸出每個腳本執行所消耗的時間(s)。

進階

如果只是很簡單的上傳到iTunes connect,上面的操作就可以滿足。

如果我們是多個target或者需要配置一些ITC上面的內容,則需要進一步的深入。

metadata

metadata是包含應用在ITC上面的各種信息,可以使用它配置我們的ITC,建議使用Deliverfile。

screenshots

屏幕截圖數據。

Appfile

存儲App信息,比如Apple ID,bundle ID等信息。

Deliverfile

交付文件。在這個文件里面可以設置iTunes connect的所有配置項,例如:

  • release_notes,此版本新增內容。
  • copyright,版權信息。
  • submit_for_review,上傳完成后是否直接提交新版本進行審查。
  • force,跳過HTML報告文件驗證。
  • ...

請在設置release_nores、support_url、private_url等配置的時候,采用hash的方式寫,國家代碼,例如:

release_notes(
    # 中國
    'zh-Hans' => ENV['RELEASE_NOTES'],
    # 澳大利亞
    'en-au' => ENV['RELEASE_NOTES_AU'],
    # 美國
    'en-us' => ENV['RELEASE_NOTES_US']
)
復制代碼

Fastfile

自動化腳本配置文件。 是我們腳本的入口,所有的事件驅動都是在這個文件來調度的。

default_platform(:ios)

platform :ios do

    desc "demo upload_to_app_store"
    lane : Archive_TargetA do |options|
        scheme = options[:scheme]
        date = Time.new.strftime("%Y%m%d-%h%M")

        # export_method 支持 app-store, ad-hoc, package, enterprise, development
        gym(
            scheme: "#{scheme}",
            output_name: "#{scheme}-#{date}.ipa",
            clean: true,
            export_method: 'app-store',
        )

        # upload_to_app_store
        deliver # 當deliverfile為空的時候,同 upload_to_app_store 作用一樣
    end
end

復制代碼

cd到項目根目錄執行命令:bundle exec fastlane Archive_TargetA scheme:"CDDemo",后面的scheme是帶的參數。

Multi-Target

如果我們需要配置多個target進行打包的話,我們可以使用環境變量,來進行配置。假如我們現在有兩個target,targetAtargetB,則我們需要創建兩個.env文件,例如.env.targetA,.env.targetB,放在Fastfile文件同級目錄下

.env文件里面我們可以配置一些不同的內容(非公共),比如app_identifier,release_notes等等。截圖如下:

Appfile,Deliverfile,Fastfile等文件,我們都可以直接使用.env文件里面的內容。

Appfile

# Appfile

#The bundle identifier of your app
app_identifier ENV['APP_IDENTIFIER']

# Your Apple email address
apple_id ENV['APPLE_ID'] 

# Developer Portal Team ID
team_id ENV['TEAM_ID']

復制代碼

Deliverfile,請在設置release_nores、support_url、private_url等配置的時候,采用hash的方式寫。

# app_identifier
app_identifier ENV['APP_IDENTIFIER']

# 用戶名,Apple ID電子郵件地址
username ENV['APPLE_ID']

# 團隊ID
team_id ENV['TEAM_ID']

# 團隊name
team_name ENV['TEAM_NAME']

# copyright
copyright ENV['COPYRIGHT']

# 關鍵字
keywords(
    'zh-Hans' => ENV['KEYWORDS'],
)

# 新版本修改記錄
release_notes(
    # 中國
    'zh-Hans' => ENV['RELEASE_NOTES'],
    # 澳大利亞
    'en-au' => ENV['RELEASE_NOTES_AU'],
    # 美國
    'en-us' => ENV['RELEASE_NOTES_US']
)

# 支持網址
support_url(
    # 中國
    'zh-Hans' => ENV['SUPPORT_URL'],
    # 澳大利亞
    'en-au' => ENV['SUPPORT_URL_AU'],
    # 美國
    'en-us' => ENV['SUPPORT_URL_US']
)

# 隱私政策網址 國家代碼 https://www.cnblogs.com/Mien/archive/2008/08/22/1273950.html
privacy_url(
    # 中國
    'zh-Hans' => ENV['PRIVACY_URL'],
    # 澳大利亞
    'en-au' => ENV['PRIVACY_URL_AU'],
    # 美國
    'en-us' => ENV['PRIVACY_URL_US']
)

# 上傳完成后提交新版本進行審查
submit_for_review false

# 跳過HTML報告文件驗證
force true

# 啟用iTC的分階段發布功能 灰度發布
phased_release true

# 應用審核小組的聯系信息 app 審核信息
app_review_information(
  first_name: "xx",
  last_name: "xx",
  phone_number: "+86 18888888888",
  email_address: "xxxx",
  demo_user: "test1@test.com",
  demo_password: "test123"
)

...
復制代碼

Fastfile文件里面使用環境變量,跟上面略有不同。在Fastfile里面,我們需要告訴lane 要使用那個.env文件,這時候我們需要使用sh腳本命令的形式來調用一個lane 后面跟上--env 環境變量文件名,此時調用的lane 不能聲明為private_lane,調用方式如下:

lane :releaseDemo2 do
    # 無參數
    sh "fastlane Archive_TargetA --env TargetA"

    # 有參數
    sh 'fastlane Archive_TargetA type:\'哈哈哈哈\' --env TargetA'
end

外部直接調用(帶參數)
bundle exec fastlane Archive_TargetA type:"haha" --env TargetA

復制代碼

然后我們在Archive_TargetA lane 里面使用ENV['xx']方式,讀取出來的內容就是從.env.TargetA文件讀取出來的。同理,deliver Action 對應的DeliverFile文件里面的內容也是從.env.TargetA文件讀取出來的。

private_lane : Archive_TargetA do |options|
    scheme = ENV['SCHEME'] # 這時候讀取出來的'scheme'就是'TargetA',從'.env.TargetA'讀取出來的

    # export_method 支持 app-store, ad-hoc, package, enterprise, development
    gym(
        scheme: "#{scheme}",
        output_name: "#{scheme}.ipa",
        clean: true,
        export_method: 'app-store',
    )

    deliver # 這時候deliverfile里面讀取的內容就是從'.env.TargetA'文件讀取的
end
復制代碼

lane之間的調用

跟我們自己寫方法調用一樣,例如:

desc "打包統一入口"
lane :Archive do |options|
    # 如果我們傳入的參數'type'是targetA,那么我們就執行Archive_TargetA 這個lane。。。
    type = options[:type]
    if type == "TargetA"
        Archive_TargetA(options)
    elsif type == "TargetB"
        Archive_TargetB(options)
    else
        Archive_TargetA(options)
    end
end
復制代碼

系統級lane

fastlane 默認有 lane。

  • before_all,就是在執行一次腳本之前首先執行的代碼,我們可以在這里面執行一些公共的東西,比如git_pullcocoapods。

    before_all do
      # 檢出到 Developer 分支
      sh 'git checkout Developer'
      git_pull
      cocoapods(repo_update: true)
    end
    
  • after_all, 成功結束之后,處理共有的后置邏輯。

  • before_each,每次執行 lane 之前都會執行一次。

  • after_each,每次執行 lane 之后都會執行一次。

  • error,在執行上述情況任意環境報錯都會中止并執行一次。

執行順序

執行順序 方法名 說明
1 before_all 在執行 lane 之前只執行一次。
2 before_each 每次執行 lane 之前都會執行一次。
3 lane 自定義的任務。
4 after_each 每次執行 lane 之后都會執行一次。
5 after_all 在執行 lane 成功結束之后執行一次。
6 error 在執行上述情況任意環境報錯都會中止并執行一次。

Error

  • 出現 Command timed out after 10 seconds on try 1 of 4, trying again...,在fastlane文件開頭加上:

    ENV["FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT"] = "180"
    ENV["FASTLANE_XCODE_LIST_TIMEOUT"] = "180"
    

插件

  • versioning,用來修改build版本號和version版本號。Fastlane內嵌的actionincrement_build_number使用的是蘋果提供的agvtool,agvtool在更改Build的時候會改變所有target的版本號。這時如果你在一個工程里有多個產品的話,每次編譯,所有的Build都要加1,最后就不知道高到哪里去了。fversioning不僅可以指定target增加Build,而且可以按照「語義化版本」規范增加Version,當然也可以直接設定Version。
  • firim,直接把AdHoc或者InHouse打包的ipa上傳到fir.im,供測試下載。

自定義插件

插件安裝格式

fastlane add_plugin [name],需要到項目根目錄下執行。

fastlane update_plugins 插件更新,同上,需要cd到項目根目錄下。

注意

  • 保持打包機器的Xcode 和 證書是最新的。
  • 使用腳本命令形式調用的時候不能設置成private_lane。
  • private_lane 表示私有lane,使用bundle exec fastlane命令,聲明為 private_lane的是不是顯示出來的,使用腳本命令形式調用的時候不能設置成private_lane。

其它

可以直接在lane里面執行git命令,例如sh 'git checkout Developer',檢出Developer分支。

由于本人的水平有限,難免會有錯誤和疏漏,歡迎 issue 指正。如果大家在Fastlane的使用上,有更好的案例,也歡迎交流和分享。

參考文章

Example

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容