自動(dòng)化打包3 Fastlane
除了Jenkins可以自動(dòng)打包厘熟,還有另一個(gè)方式:Fastlane浦马,下面來(lái)了解下黔漂。
Fastlane是一個(gè)完全開源的項(xiàng)目蹦骑,是一款為iOS和Android開發(fā)者提供的自動(dòng)化構(gòu)建工具曼库。它可以幫助開發(fā)者將App打包区岗、簽名、測(cè)試毁枯、發(fā)布等流程串聯(lián)起來(lái)慈缔,實(shí)現(xiàn)完全自動(dòng)化的工作流。其官網(wǎng)地址為:https://fastlane.tools/
Fastlane安裝
參考配置文檔种玛,安裝步驟如下:
- 檢查ruby版本藐鹤,需要2.0及以上,并且將gem的source改為gems.ruby-china.com/
// 查看 Ruby 版本
ruby -v
// 查看 gem 的source
gem sources
- 檢查Xcode命令行工具是否安裝赂韵,如果沒有安裝則會(huì)自動(dòng)開始安裝
xcode-select --install
- 安裝Fastlane
sudo gem install fastlane --verbose
//如果安裝出錯(cuò)娱节,則使用以下命令
sudo gem install -n /usr/local/bin fastlane
//查看版本驗(yàn)證是否安裝成功
fastlane --version
Fastlane相關(guān)block、lanes右锨、actions
在完善打包邏輯之前括堤,首先介紹Fastlane中提供的常用的blocks、lanes和actions
blocks:fastlane中除了lane的其他模塊
lanes:Lanes的相關(guān)用法介紹
actions:fastlane內(nèi)置好的常用操作
Blocks
block主要分為三類:
before_all & before_each
after_all & after_each
error
其中before_all會(huì)先于before_each執(zhí)行绍移,且僅執(zhí)行一次悄窃,
所以許多通用操作流入git代碼拉取等,可以放在before_all或者befoe_each中
- before_all:在lane執(zhí)行前執(zhí)行一次
before_all do |lane|
# ...
end
<!--舉例-->
before_all do |lane|
cocoapods #這里會(huì)執(zhí)行pod install
end
- before_each:會(huì)在任意lane執(zhí)行前執(zhí)行蹂窖,與before_all只執(zhí)行一次不同轧抗,如果在一個(gè) lane 中多次調(diào)用了其他的 lane,則其他的 lane 執(zhí)行前都會(huì)執(zhí)行 before_each瞬测。
before_each do |lane, options|
# ...
end
- before_each:會(huì)在任意lane執(zhí)行前執(zhí)行横媚,與before_all只執(zhí)行一次不同纠炮,如果在一個(gè) lane 中多次調(diào)用了其他的 lane,則其他的 lane 執(zhí)行前都會(huì)執(zhí)行 before_each灯蝴。
before_each do |lane, options|
# ...
end
after_all & after_each
after_all 會(huì)在 after_each 執(zhí)行完后執(zhí)行恢口,且僅執(zhí)行一次。
許多通用操作例如發(fā)送打包成功的通知等穷躁,可以放在 after_all 或 after_each 中耕肩。
- after_all:會(huì)在lane執(zhí)行完后執(zhí)行一次
after_all do |lane|
# ...
end
<!--舉例-->
after_all do |lane|
say("Successfully finished release (#{lane})!")
slack(
message: "Successfully submitted new App Update"
)
sh("./send_screenshots_to_team.sh") # Example
end
- after_each:會(huì)在任意lane執(zhí)行完后執(zhí)行,如果在一個(gè)lane中多次調(diào)用了其他的lane问潭,則其他的lane執(zhí)行完后都會(huì)執(zhí)行after_each
after_each do |lane, options|
# ...
end
例如下面的例子猿诸,before_each將after_each被調(diào)用 4 次
- before_each:調(diào)用deploy之前、切換到archive之前狡忙、切換到sign之前梳虽、切換到upload之前
- after_each:執(zhí)行deploy之后、切換到archive執(zhí)行之后灾茁、切換到sign執(zhí)行之后窜觉、切換到upload執(zhí)行之后
before_each do |lane, options|
# ...
end
lane :deploy do
archive
sign
upload
end
lane :archive do
# ...
end
lane :sign do
# ...
end
lane :upload do
# ...
end
after_each do |lane, options|
# ...
end
error
在任何流程中發(fā)生錯(cuò)誤時(shí),都會(huì)退出并執(zhí)行error删顶,錯(cuò)誤后的after_all和after_each將不會(huì)執(zhí)行
error do |lane, exception|
slack(
message: "Something went wrong with the release.",
success: false,
payload: { "Error Info" => exception.error_info.to_s }
)
end
Actions
一個(gè)命名的lane代表一個(gè)持續(xù)集成的任務(wù)竖螃,每個(gè)任務(wù)由多個(gè)步驟組成淑廊,步驟組成是已經(jīng)定義好的action工具逗余。在終端可以通過fastlane action actionName查看某個(gè)具體的action,也可以通過fastlane action查看fastlane中定義好的action及說(shuō)明季惩。
除了使用ruby代碼在lane中實(shí)現(xiàn)的各種功能录粱,fastlane也內(nèi)置了許多寫好的獨(dú)立方法庫(kù)即action
,每一個(gè)action都是一個(gè)獨(dú)立Ruby腳本
画拾,是fastlane的最小執(zhí)行單位
啥繁,下面介紹幾個(gè)常用的action
1、cocoapods:執(zhí)行pod install
2青抛、gym:項(xiàng)目編譯旗闽、打包等
3、increment_build_number:build號(hào)自增
4蜜另、match:管理證書和配置文件
5适室、app_store_connect_api_key:為其他 action 生成 App Store Connect API token
1、cocoapods
調(diào)用cocoapods action會(huì)執(zhí)行pod install举瑰,如果工程中使用了cocoapods管理三方庫(kù)捣辆,需要在Gemfile中添加以下命令
gem "cocoapods"
在lane中使用直接調(diào)用即可
lane :debug do
cocoapods # 執(zhí)行 pod install
end
- 2、gym
gym是fastlane提供的用于構(gòu)建此迅、打包的action汽畴,是build_app的別名旧巾。可以根據(jù)配置參數(shù)編譯iOS應(yīng)用忍些,并生成ipa包鲁猩。以下是常用的參數(shù)
workspace:workspace 文件路徑,使用 cocoapods 后需要使用
project:project 文件路徑罢坝,若有 workspace 此項(xiàng)可忽略
scheme: schema名
clean:是否在編譯前清理工程
configuration:編譯環(huán)境設(shè)置绳匀,Relese、Debug炸客、自定義
export_method:包輸出類型疾棵,app-store、ad-hoc痹仙、package是尔、enterprise、development
archive_path : 讀取xarchive的路徑
output_directory:ipa包輸出路徑
output_name:ipa包名稱
include_symbols:是否集成調(diào)試符號(hào)开仰,若為 false 則會(huì)單獨(dú)生成符號(hào)文件
include_bitcode: 是否開啟bitcode
其他參數(shù)如下:
export_options: 可以指定更詳細(xì)的打包配置拟枚,可以是配置文件路徑
skip_build_archive: 跳過構(gòu)建,打包階段众弓,直接簽名恩溅;使用archive_path 作為輸入
skip_archive:僅構(gòu)建
skip_codesigning: 僅構(gòu)建,打包谓娃,不簽名
以下是CI中具體的例子
lane :release do
# ...
gym(
workspace: "app.xcworkspace",
scheme: "app",
# 打包前clean
clean: true,
# Release脚乡、Debug、自定義
configuration: "Release",
# app-store, ad-hoc, package, enterprise, development
export_method: "ad-hoc",
# 文件輸出路徑
output_directory: "/Users/user/Desktop/",
# ipa名稱
output_name: "app.ipa",
# 是否包含調(diào)試符號(hào)
include_symbols: true,
# 是否開啟bitcode
include_bitcode: false,
)
# ...
end
3滨达、increment_build_number
- 通過app_store_build_number獲取最新版本的build_number
currentBuildNumber = app_store_build_number(
api_key: api_key, # 使用app_store_connect_api_key認(rèn)證
live: false, # live 為 true 查詢已發(fā)售的版本奶稠,false 查詢測(cè)試的版本
app_identifier: "com.zm.ZLGithubClient"
)
- 通過increment_build_number設(shè)置項(xiàng)目的build_number
increment_build_number(
build_number: currentBuildNumber + 1
)
4、match
match配置步驟
在gitLab上創(chuàng)建一個(gè)倉(cāng)庫(kù)用于保存證書
在項(xiàng)目根目錄下執(zhí)行 fastlane match init,輸入倉(cāng)庫(kù)的git地址画株,會(huì)在fastlane目錄下生成Matchfile文件辆飘,包含match的配置信息
match參數(shù)說(shuō)明
type: 同步的配置文件類型: appstore,adhoc,development,enterprise,默認(rèn) development
readonly: 默認(rèn)false,如果是true,不會(huì)生成新的證書和描述配置文件
app_identifier: 指定描述配置文件的bundle id谓传;如果不指定則使用 AppFile 中的 app_identifier
git_url: 證書保存的git地址
keychain_name : 保存證書的keychain蜈项,默認(rèn)login.keychain
以下是在CI中使用match的例子
# match 中需要配置參數(shù)
# 證書類型 appstore , adhoc 還是 development
# app id
# kaychain 證書保存的keychain
# git_url 證書保存的github遠(yuǎn)端庫(kù)
lane :github_action_testFlight do
match(type: "appstore",
readonly: true,
app_identifier: "com.used.id",
keychain_name: ENV['MATCH_KEYCHAIN_NAME'],
keychain_password: ENV['MATCH_PASSWORD'],
git_url: ENV['MATCH_GIT_URL'])
end
# ENV['MATCH_GIT_URL'] 是加密保存的參數(shù)
match說(shuō)明
執(zhí)行這些命令fastlane match development, fastlane match adhoc, fastlane match enterprise良拼,fastlane match appstore战得,
首次執(zhí)行自動(dòng)在apple store connect中創(chuàng)建provisioning file
,證書并下載加密保存在git倉(cāng)庫(kù)庸推,并上傳.其他開發(fā)者就可以使用fastlane match命令共享github中的證書和配置文件常侦。
5浇冰、App Store Connect API
在早先訪問App Store Connect信息時(shí)需要雙因素認(rèn)證。而在持續(xù)集成的過程中一般無(wú)法人機(jī)交互(例如github-action)聋亡,會(huì)導(dǎo)致持續(xù)集成無(wú)法完成肘习。在WWDC18中,蘋果提出了App Store Connect API坡倔,提供另外的認(rèn)證方式漂佩。Fastlane也對(duì)App Store Connect API提供了支持棚菊,具體查看Using App Store Connect API文檔
Using App Store Connect API是一個(gè)官方公共API
催跪,用于管理應(yīng)用元數(shù)據(jù)、定價(jià)心剥、配置等征堪。但是在使用之前瘩缆,需要獲取AppStore Connect的訪問權(quán)限
,即獲取issuer ID和apiKey
佃蚜。
app_store_connect_api_key
是用來(lái)為其他 action
生成 App Store Connect API token
的 action; match,pilot以及 deliver等 action 都可以使用 App Store Connect API token庸娱,有如下參數(shù):
-
key_id
:密鑰ID,需要在AppStore Connect -> 用戶和訪問 -> 密鑰中創(chuàng)建并獲取 -
issuer_id
:標(biāo)識(shí)創(chuàng)建認(rèn)證令牌的發(fā)放者谐算。也是在AppStore Connect -> 用戶和訪問 -> 密鑰中獲取 -
key_filePath
: p8文件的路徑 -
key_content
: p8文件的內(nèi)容熟尉,未編碼直接提供需要將回車替換為\n -
is_key_content_base64
: 是否key的內(nèi)容經(jīng)過base64編碼 -
in_house
: 是app store還是 enterprise
以下是在CI中的使用例子
lane :release do
api_key = app_store_connect_api_key(
key_id: "xxxxxxxxx",
issuer_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
key_filepath: "./private_keys/AuthKey_xxxxxxxxxx.p8",
duration: 1200, # optional
in_house: false, # optional but may be required if using match/sigh
)
# 在piolt中使用app_store_connect_api_key
pilot(api_key: api_key)
end
Lanes
lanes的使用方式請(qǐng)參考lanes文檔,可以分為以下幾種:
命令行參數(shù)傳遞
lane之間的調(diào)用
返回值
如何停止執(zhí)行中的lane
lane的上下文通信
如何訪問lane的屬性
私有l(wèi)ane
如何配置多個(gè)lane的環(huán)境變量
命令行參數(shù)傳遞
- 1洲脂、傳遞:如果需要將參數(shù)從命令行傳遞到lane斤儿,語(yǔ)法如下
//格式
fastlane [lane] key:value key2:value2
//舉例
fastlane deploy submit:false build_number:24
- 2、使用:在lanes中接收傳入的值腮考,是通過options實(shí)現(xiàn)的雇毫,格式為:options[:參數(shù)名]
lane :deploy do |options|
# 獲取傳入的submit
if options[:submit]
# Only when submit is true
end
# build號(hào)增加,獲取傳入的build_number
increment_build_number(build_number: options[:build_number])
end
lane之間的調(diào)用
lane之間的調(diào)用踩蔚,有點(diǎn)類似于函數(shù)的調(diào)用,通過lane的名字來(lái)調(diào)用
lane :deploy do |options|
# deploy調(diào)用名為build的lanes
build(release: true) # 傳入打包的方式
end
lane :staging do |options|
# deploy調(diào)用名為build的lanes
build # 不傳參也可以工作
end
lane :build do |options|
build_config = (options[:release] ? "Release" : "Staging")
build_ios_app(configuration: build_config)
end
返回值
除此之外枚粘,lane還可以檢索返回值馅闽,在Ruby中,lane定義的最后一行是返回值馍迄,在其他lane中通過options進(jìn)行使用
lane :deploy do |options|
value = calculate(value: 3)
puts value # => 5
end
lane :calculate do |options|
# 返回值
2 + options[:value] # the last line will always be the return value
end
如何停止執(zhí)行中的lane
在lane中可以通過next關(guān)鍵字來(lái)停止執(zhí)行中的lane福也,如下所示
lane :build do |options|
if cached_build_available?
UI.important 'Skipping build because a cached build is available!'
next # skip doing the rest of this lane
end
match
gym
end
private_lane :cached_build_available? do |options|
# ...
true
end
當(dāng)next作用在切換lane時(shí),會(huì)控制流程返回到前l(fā)ane正在執(zhí)行的位置攀圈,即當(dāng)前l(fā)ane的next以后的代碼將不會(huì)執(zhí)行
lane :first_lane do |options|
puts "If you run: `fastlane first_lane`"
puts "You'll see this!"
second_lane
puts "As well as this!"
end
private_lane :second_lane do |options|
next
puts "This won't be shown"
end
lane的上下文通信
lane的上下文通信暴凑,簡(jiǎn)單來(lái)說(shuō)就是如何在不同的action間通信。不同的action可以通過分享哈希來(lái)進(jìn)行通信赘来,如下所示
lane_context[SharedValues::VARIABLE_NAME_HERE]
//舉例
lane_context[SharedValues::BUILD_NUMBER] # Generated by `increment_build_number`
lane_context[SharedValues::VERSION_NUMBER] # Generated by `increment_version_number`
lane_context[SharedValues::SNAPSHOT_SCREENSHOTS_PATH] # Generated by _snapshot_
lane_context[SharedValues::PRODUCE_APPLE_ID] # The Apple ID of the newly created app
lane_context[SharedValues::IPA_OUTPUT_PATH] # Generated by _gym_
lane_context[SharedValues::DSYM_OUTPUT_PATH] # Generated by _gym_
lane_context[SharedValues::SIGH_PROFILE_PATH] # Generated by _sigh_
lane_context[SharedValues::SIGH_UDID] # The UDID of the generated provisioning profile
lane_context[SharedValues::HOCKEY_DOWNLOAD_LINK] # Generated by `hockey`
lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] # Generated by `gradle`
lane_context[SharedValues::GRADLE_ALL_APK_OUTPUT_PATHS] # Generated by `gradle`
lane_context[SharedValues::GRADLE_FLAVOR] # Generated by `gradle`
lane_context[SharedValues::GRADLE_BUILD_TYPE] # Generated by `gradle`
如果訪問lane的屬性
我們也可以通過lane_context動(dòng)態(tài)訪問當(dāng)前l(fā)ane的屬性现喳,如下所示
lane_context[SharedValues::PLATFORM_NAME] # Platform name, e.g. `:ios`, `:android` or empty (for root level lanes)
lane_context[SharedValues::LANE_NAME] # The name of the current lane preceded by the platform name (stays the same when switching lanes)
lane_context[SharedValues::DEFAULT_PLATFORM] # Default platform
同時(shí)這些屬性也可用作.env文件的環(huán)境變量
ENV["FASTLANE_PLATFORM_NAME"]
ENV["FASTLANE_LANE_NAME"]
私有l(wèi)ane
當(dāng)我們有不同lane調(diào)用同一個(gè)lane時(shí)凯傲,可以將這個(gè)lane定義為私有的lane,防止在外部通過fastlane laneName進(jìn)行調(diào)用嗦篱,如下所示冰单,我們不能通過fastlane build來(lái)訪問私有的lane
lane :production do
# ...
build(release: true)
appstore # Deploy to the AppStore
# ...
end
lane :beta do
# ...
build(release: false)
crashlytics # Distribute to testers
# ...
end
lane :build do |options|
# ...
ipa
# ...
end
<!--更改為-->
lane :production do
# ...
build(release: true)
appstore # Deploy to the AppStore
# ...
end
lane :beta do
# ...
build(release: false)
crashlytics # Distribute to testers
# ...
end
private_lane :build do |options|
# ...
ipa
# ...
end
如何配置多個(gè)lane的環(huán)境變量
通常Appfile只會(huì)使用配置項(xiàng)的第一個(gè)值,如下所示灸促,app_identifier配置了兩個(gè)值诫欠,我們一般只會(huì)取第一個(gè)com.used.id,而com.ignored.id將被忽略浴栽。
app_identifier "com.used.id"
app_identifier "com.ignored.id"
為了避免以上情況荒叼,fastlane提供了for_lane和for_platform來(lái)解決多個(gè)配置的情況,所有的配置文件中都可使用
- for_lane:當(dāng)調(diào)用的lane和指定的lane名稱匹配時(shí)典鸡,會(huì)調(diào)用對(duì)應(yīng)的block
locales ['en-US', 'fr-FR', 'ja-JP']
for_lane :screenshots_english_only do
locales ['en-US']
end
for_lane :screenshots_french_only do
locales ['fr-FR']
end
- for_platform:根據(jù)當(dāng)前的platform決定執(zhí)行的block
app_identifier "com.default.id"
for_lane :enterprise do
app_identifier "com.forlane.enterprise"
end
for_platform :Mac do
app_identifier "com.forplatform.mac"
for_lane :release do
app_identifier "com.forplatform.mac.forlane.release"
end
end
Fastlane配置
Fastlane的配置主要分為三步:
- fastlane初始化
- 創(chuàng)建.env配置全局變量甩挫,并修改Appfile
- fastfile完善打包邏輯
【第一步】fastlane的初始化配置
主要執(zhí)行以下命令
cd [項(xiàng)目根目錄,xcodeproj的同級(jí)目錄]
fastlane init
init操作主要完成以下操作:
1、會(huì)要求輸入開發(fā)者賬戶和密碼椿每,會(huì)存儲(chǔ)在鑰匙串中伊者,后續(xù)使用無(wú)需再輸入密碼
2、會(huì)檢測(cè)當(dāng)前項(xiàng)目的App Identifier是否已經(jīng)存在Developer中
3间护、會(huì)檢測(cè)App是否已經(jīng)在AppStore Connect中亦渗,如果都滿足,過程是比較順利的
4汁尺、會(huì)在項(xiàng)目工程的目錄下生成一個(gè)fastlane文件夾法精,里面是Fastlane的一些配置文件。fastlane可以通過配置Appfile痴突、Deliverfile搂蜓、Fastfile 來(lái)完成各種工作。
下面分別介紹下fastlane文件夾中常用的文件:
Appfile:存放 App 的基本信息包括 App_Identifier 辽装、AppID 帮碰、Team_ID 等。這個(gè)文件的參數(shù)是已經(jīng)定義好的拾积,新增并沒有用
Fastfile:最核心的用來(lái)控制流程走向的配置文件殉挽,是最重要的一個(gè)文件,在這個(gè)文件里面可以編寫和定制我們打包腳本的一個(gè)文件拓巧,所有自定義的功能都寫在這里
Deliverfile:可用于配置提交AppStore Connect的一些參數(shù)斯碌。(注:這個(gè)文件只有在選擇由fastlane管理metadata為YES時(shí),才會(huì)生成肛度,如下所示)
- .env或.env.default:為了更靈活的使用Appfile的內(nèi)容傻唾,可以使用.env文件來(lái)進(jìn)行環(huán)境配置,新增其他的變量在fastfile中使用
除此之外承耿,還需要關(guān)注fastlane同級(jí)的Gemfile和Gemfile.lock文件
- Gemfile:私用bundler來(lái)安裝和引入該App所需的gem冠骄,類似于cocoapods中的podfile
- Gemfile.lock:gem的版本控制文件伪煤,類似于cocoapods的podfile.lock文件
【第二步】創(chuàng)建.env配置全局變量,并修改Appfile
注:因?yàn)槭?env文件是.開頭文件猴抹,默認(rèn)是在finder中隱藏的带族,可以通過快捷鍵來(lái)顯示隱藏文件:CMD + Shift + .
- 為了更加靈活的使用Appfile的內(nèi)容,可以引入.env文件來(lái)進(jìn)行環(huán)境配置蟀给,具體的請(qǐng)參考.env環(huán)境配置文檔蝙砌。這樣在執(zhí)行命令時(shí),可以在氣候加上環(huán)境變量跋理,以達(dá)到使用不同配置的目的择克。
其命名規(guī)則為:.env.<environment>,例如:.env.development前普、.env.release肚邢。
- 在命令中如下使用
fastlane <lane-name> --env development
- Appfile中使用.env,直接讀取變量即可
//.env內(nèi)容
WORKSPACE=YourApp.xcworkspace
HOCKEYAPP_API_TOKEN=your-hockey-api-token
//Fastfile中使用.env文件
xcworkspace ENV['WORKSPACE']
hockey-api-token ENV['HOCKEYAPP_API_TOKEN']
【第三步】Fastfile完善打包邏輯
編輯fastlane的邏輯可參考fastlane自動(dòng)部署iOS AppStore文檔拭卿,構(gòu)建步驟如下:
更新pod骡湖,清理緩存
版本號(hào)修改
編譯并打包
上傳AppStore
以下是具體的編譯、打包代碼
# 因?yàn)閒astlane存在新老版本兼容問題峻厚,所以一般會(huì)指定fastlane版本
fastlane_version "2.205.1"
# 設(shè)置默認(rèn)的平臺(tái)
default_platform(:iOS)
# ======================== .env文件配置獲取相關(guān)參數(shù) ========================
# 定義兩個(gè)方便使用和修改的常量
scheme = ENV['Scheme'] #scheme名稱
xcodeproj = ENV['Xcodeproj']
workspace = ENV['Workspace']
info_plist = ENV['Info_Plist']
# 定義指定平臺(tái)的操作
platform :iOS do
# ======================== 執(zhí)行l(wèi)ane前的操作 ========================
# 所有l(wèi)ane執(zhí)行之前响蕴,可以做如執(zhí)行cocoapods的pod install
before_all do |lane, options|
# 更新pod
cocoapods(use_bundle_exec: FALSE)
# 清理緩存
xcclean(scheme: scheme)
end
# 將正式應(yīng)用打包并上傳到App Store,release是自己取的名字惠桃,因?yàn)槭前l(fā)布正式版浦夷,所以取名叫 release
desc "Push a new release build to the App Store"
lane :release do
# 打包之前,先將build號(hào)遞增
increment_build_number(xcodeproj: "#{xcodeproj}")
# 對(duì)應(yīng)用進(jìn)行打包
build_app(
workspace: "#{workspace}",
scheme: "#{scheme}",
export_method: "app-store",
clean: true,
xcargs: "-allowProvisioningUpdates"
)
# 將打包完的應(yīng)用上傳到AppStore
upload_to_app_store(
skip_metadata: true,
skip_screenshots: true
)
end
# ======================== 執(zhí)行l(wèi)ane成功后的操作 ========================
# 所有l(wèi)ane完成之后辜王,可以使用參數(shù)lane來(lái)區(qū)分
after_all do |lane, options|
puts "所有l(wèi)ane執(zhí)行完畢"
end
# ======================== 執(zhí)行l(wèi)ane失敗后的操作 ========================
# 所有l(wèi)ane失敗之后劈狐,可以使用參數(shù)lane來(lái)區(qū)分
error do |lane, options|
puts "lane執(zhí)行失敗"
end
end
到此,fastlane就配置完成了
Fastlane使用
- 跳轉(zhuǎn)到項(xiàng)目的根目錄:cd [項(xiàng)目根目錄]
- 自動(dòng)打包并上傳到AppStore Connect呐馆,在終端執(zhí)行l(wèi)ane:fastlane lanename
除了可以在本地終端執(zhí)行肥缔,還可以在Jenkins構(gòu)建打包服務(wù),具體步驟參考文檔:Jenkins集成fastlane
最終摹恰,F(xiàn)astlane整體流程匯總?cè)缦?/p>
iOS中打包方式匯總?cè)缦?/p>
Fastlane 不錯(cuò)的案例
Fastlane一鍵自動(dòng)化打包發(fā)布 iOS 項(xiàng)目
使用fastlane進(jìn)行iOS打包
iOS 使用fastlane實(shí)現(xiàn)自動(dòng)化打包