iOS 持續交付之 Fastlane

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

1、爲何選擇 Fastlane

why fastlane

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

使用場景

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

工具集

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

  • 測試工具
    • 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。

2、準備工做,很重要的喲

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

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

    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 updatesxcode

  4. 建立App ID證書,在iTunes connect 建立一個用於測試的 app。ruby

  5. 安裝fastlanebash

  6. 建立一個測試demo。app

    1. 並將其scheme設置爲shared,否則fastlane init的時候會失敗。curl

    2. 設置好籤名配置文件。

    3. 爲app添加icon

    4. 修改devicesiPad或者iPhone

3、實踐

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

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

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

  4. 若是最後出現fastlane release,就表示init成功了。

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

    若是Deliverfilescreenshotsmetadata目錄沒被建立,能夠運行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 IDbundle ID等信息。

Deliverfile

交付文件。在這個文件裏面能夠設置iTunes connect的全部配置項,例如:

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

請在設置release_noressupport_urlprivate_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進行打包的話,咱們可使用環境變量,來進行配置。假如咱們如今有兩個targettargetAtargetB,則咱們須要建立兩個.env文件,例如.env.targetA,.env.targetB,放在Fastfile文件同級目錄下

.env文件裏面咱們能夠配置一些不一樣的內容(非公共),好比app_identifierrelease_notes等等。截圖以下:

AppfileDeliverfileFastfile等文件,咱們均可以直接使用.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

轉載請註明出處!

相關文章
相關標籤/搜索