背景
我們都知道將開發好的APP發布到AppStore
的流程大概是:編譯->打包IPA上傳->填寫應用更新數據->等待iTunesConnect編譯->選擇版本發布
,整個過程大概需要30分鐘左右(前提是公司網絡還要好,說多了都是淚啊~), 悲催的是如果某一次Build Version
忘記增加了,那這個流程還得再來一遍,對于經常不斷迭代的產品,這更是痛啊~~
還有一種情況,發布一個Pod遠程私有庫或者是Pod公開庫的流程大概是:
增加Podspec中的版本號->pod install -> Git Commit代碼->打標簽Tag->推送Tag到Origin->執行pod lib lint命令進行庫驗證->執行pod repo push命令發布庫到私有倉庫或者pod trunk push到CocoaPod公開庫中
,整個過程雖然沒有任何技術含量,但是整個過程下來半個小時沒了,如果中間標簽打錯了,或者是標簽忘記推送到遠端了,囧,整個過程還得再來一遍!!!
那么有沒有什么工具或者好的輪子可以解決上述問題呢?肯定是有的,下面我們就來聊聊今天的主角:Fastlane
fastlane 簡介
Fastlane 是一個完全開源的項目,是一款為 iOS
和Android
開發者提供的自動化構建工具,它可以幫助開發者將 App
打包、簽名、測試、發布、信息整理、提交 App Store
等工作完整的連接起來,實現完全自動化的工作流,如果使用得當,可以顯著的提高開發者的開發效率。
下面是fastlane的GitHub
的鏈接和官方地址;
fastlane 的使用
安裝前請確保你已經安裝了最新的 Xcode command line tools
,通過在終端中執行下面的命令你可以進行檢查。
xcode-select --install
安裝 fastlane
sudo gem install -n /usr/local/bin fastlane
查看版本
為項目配置fastlane
$ cd 項目根目錄
$ fastlane init
如果期間報錯 Connection reset by peer - SSL_Connect
,就需要執行:
$ brew update && brew install ruby
// 重裝
$ sudo gem install -n /usr/local/bin fastlane
然后重新執行
$ fastlane init
在這期間會讓你輸入 Apple ID
賬號密碼,這個信息會存儲在鑰匙串中,后續使用無需再輸入密碼
會檢測當前的 app identifier
是否在 Apple Dev Center
中
會檢測當前 app 是否在 iTunes Connect
中
如果已經在 ADC
和 ITC
中創建相應的信息,那么過程會很順利,如下圖:
執行完成之后會在項目目錄中生成如下文件結構:
上面這些文件中,最重要的兩個文件就是Appfile
和Fastfile
。
Appfile
里面存放了App的基本信息包括App_Identifier
、AppID
、Team_ID
。如果在init的時候你輸入了正確的AppID賬號和密碼會在這里生成正確的team_id
信息。如果沒有team
,這里就不會顯示。
Fastfile
是最重要的一個文件,在這個文件里面可以編寫和定制我們打包腳本的一個文件,所有自定義的功能都寫在這里。
但是如果我們沒有在iTunes Connect
中創建APP,那么就不會創建上述metadata
和screenshots
兩個文件夾;當然我們也可以后續創建,執行如下操作即可:
$ fastlane produce init
FastFile文件
接下來我們分析下這個文件:
#指定當前fastlane使用的最小版本。
fastlane_version "2.50.0"
#指定當前平臺,可以選擇iOS,Android,Mac。
default_platform :ios
platform :ios do
#這個指的是在執行每一個lane之前都先執行這個功能。
before_all do
cocoapods
end
#一個lane的描述,一般說明lane的用途。
desc "Runs all the tests"
lane :test do
scan
end
desc "Submit a new Beta Build to Apple TestFlight"
desc "This will also make sure the profile is up to date"
lane :beta do
# match(type: "appstore") # more information: https://codesigning.guide
gym(scheme: "kdzs") # Build your app - more options available
pilot
# sh "your_script.sh"
# You can also use other beta testing services here (run `fastlane actions`)
end
desc "Deploy a new version to the App Store"
lane :release do
# match(type: "appstore")
# snapshot
gym(scheme: "kdzs") # Build your app - more options available
deliver(force: true)
# frameit
end
# You can define as many lanes as you want
#在每個lane執行之后都執行這個功能。
after_all do |lane|
# This block is called, only if the executed lane was successful
# slack(
# message: "Successfully deployed new App Update."
# )
end
#在每個lane執行出錯的時候都執行這個功能。
error do |lane, exception|
# slack(
# message: exception.message,
# success: false
# )
end
end
上傳 ipa 到蒲公英或者Fir.im上
上傳到蒲公英上
上傳 ipa 的命令如下:
$ ipa distribute:pgyer -f path/to/ipa -u USER_KEY -a APP_KEY
其中USER_KEY
和APP_KEY
可以在蒲公英上查到。
上傳到Fir.im上
利用 fir-cli
將打好的包,通過命令,上傳到Fir.im平臺上
FIR.im CLI 使用 ruby
構建,只要安裝相應 ruby gem
即可:
$ gem install fir-cli —verbose
上傳 ipa 的命令如下:
$ fir publish path/to/ipa -T YOUR_FIR_TOKEN
其中 YOUR_FIR_TOKEN
可以在 Fir.im
上查到。
完整 Fastfile 代碼
fastlane_version "2.28.7"
default_platform :ios
def archive(path, name, scheme, method)
gym(
export_method: method,
scheme: scheme,
clean: true,
output_directory: path,
output_name: name,
configuration: 'Release',
include_symbols: false,
include_bitcode: true,
)
end
platform :ios do
desc "打包 type 1: 正式, 0: 測試"
lane :archive do |options|
time = Time.new.strftime("%Y-%m-%d-%H:%M:%S")
path = "./fastlane/" + time
type = options[:type]
# 使用證書創建私鑰及簽名
cert
# 不帶adhoc參數,sigh會自動生成App Store證書(公司或個人帳戶)
sigh(
adhoc: true,
force: true,
)
if type == '1'
name = '正式'
archive(path, name, 'yourTargetName', 'app-store')
elsif type == '0'
name = '測試'
archive(path, name, 'yourTargetName', 'ad-hoc')
# 上傳至蒲公英
system 'ipa distribute:pgyer -f ./' + time + '/' + name + '.ipa -u your_user_key -a your_app_key'
# 上傳至fir
system 'fir publish ./' + time + '/' + name + '.ipa -T your_token'
else
puts "type錯誤, type == '0' : 測試, type== '1' : 正式"
end
end
end
CD 項目根目錄,就可以通過 fastlane archive type:0
來調用打包腳本了,登錄Fir.im
和蒲公英平臺上我們就可以看到剛剛發布上去的APP了:
Sigh
如果你不確定證書目前是否可用,可以用Sigh
自動生成獲取證書。Sigh
會自動根據Appfile
里設置的app_identifier
從ADC(蘋果開發者中心)
生成證書,并下載到項目根目錄下(不是fastlane目錄),下載后自動安裝。你可以通過指定output_path
指定證書下載位置。
PS:建議不要把這個文件夾同步到項目的git中(Fastlane
提供了match
專門管理所有證書)。可以在.gitignore
中忽略這個文件夾。
sigh
的具體用法可以參考GitHub 或者官方文檔
而且上面的兩個鏈接我都是幫你們搜好了的,直接點擊就可以到達你們想要的位置,不用謝我哈~~
Gym
Gym 是 Fastlane
家族的自動化編譯工具,和其他工具配合的非常默契,它可以用來編譯,打包iOS app,生成簽名的ipa文件.下面是GitHub上的描述,我感覺更加貼切些
gym is part of fastlane: The easiest way to automate beta deployments and releases for your iOS and Android apps.
gym builds and packages iOS apps for you. It takes care of all the heavy lifting and makes it super easy to generate a signed ipa or app file ??
gym is a replacement for
shenzhen
.
Deliver
我們可以使用deliver
命令將屏幕截圖、元數據和 IPA
文件上傳到iTunes Connect
中,
其實上傳 ITC 最主要的文件是 Deliverfile
,配置好Deliverfile
后,可以刪除 metadata
文件夾中的文本配置.因為Deliverfile
的優先級比metadata
要高:
Values provided in the Deliverfile or Fastfile will be take priority over values from these files.
將metadata
中的所有文件刪除以后,將1024*1024
的icon圖標放入到該目錄下,然后創建一個分級
的json文件,這里假如叫做:rating.json
,具體內容如下:
{
//#0: None 無
//#1: Infrequent/Mild 偶爾/輕微的
//#2: Frequent/Intense 頻繁的/強烈的
//#卡通或幻想暴力
"CARTOON_FANTASY_VIOLENCE": 0,
//#現實暴力
"REALISTIC_VIOLENCE": 0,
//#大量露骨或殘暴的現實暴力
"PROLONGED_GRAPHIC_SADISTIC_REALISTIC_VIOLENCE": 0,
//#低俗笑話
"PROFANITY_CRUDE_HUMOR": 0,
//#成人/性暗示題材
"MATURE_SUGGESTIVE": 0,
//#恐怖/驚悚題材
"HORROR": 0,
//#醫學/醫療信息
"MEDICAL_TREATMENT_INFO": 0,
//#使用或提及煙、酒或毒品
"ALCOHOL_TOBACCO_DRUGS": 0,
//#模擬賭博
"GAMBLING": 0,
//#色情或裸露內容
"SEXUAL_CONTENT_NUDITY": 0,
//#色情及裸體畫面
"GRAPHIC_SEXUAL_CONTENT_NUDITY": 0,
//#無限制的網站訪問
"UNRESTRICTED_WEB_ACCESS": 0,
//#賭博和競賽
"GAMBLING_CONTESTS": 0
}
具體配置參加官方文檔
Deliverfile
的具體配置可以參考:Deliverfile文檔
發布到App Store
先看下lane
desc "發布到AppStore"
# 任務名稱
lane :Release do
# 創建 ITC 中的 App 信息
produce(
#通常這兩項是通過AppFile加載,因此這里不需要手動指定;
#username: "admin@sutongwang.cn",
#app_identifier: "gzp.fastlane.test",
app_name: "fastlane測試",
language: "zh-Hans",
app_version: "1.0",
sku: "gzp.fstlane.test"
)
# 使用證書創建私鑰及簽名
cert
# 每次運行時創建新的配置文件
sigh(force: true)
# 指定輸出目錄
gym(
output_directory: './build',
configuration: 'Release',
include_symbols: false,
include_bitcode: true,
)
# 上傳所有信息到App Store
deliver(
force: true,
#自動發布,false:手動發布
#submit_for_review: true
)
end
配置完之后執行: fastlane Release
發布成功以后fastlane
會給我一個?? 祝賀一下,哈哈 ,同時會告訴我們幫我們節省了多長時間,如下圖:
發布到CocoaPods公開庫或者是私有庫
desc "編譯\上傳CocoaPods庫"
lane :PushPodsLib do |options|
targetName = options[:targetName] #項目名稱
commitMsg = options[:commitMsg] #commit 日志信息
tagName = options[:tagName] #標簽名稱
path = "#{targetName}.podspec"
# 根據我們制定的自動化流程去寫對應的action
# pod install
cocoapods(
podfile: "./Example/Podfile"
)
# git add .
git_add(path: ".")
# git commit -m "xxx"
git_commit(path: ".", message: commitMsg)
# git push origin master
push_to_git_remote
# 判斷標簽是否已經存在
# 如果存在, 應該刪除標簽(本地標簽, 遠程標簽)
if git_tag_exists(tag: tagName)
UI.message("已經發現存在#{tagName}這個標簽, 此處, 刪除該標簽對應的本地和遠程標簽")
remove_tag(tagName: tagName)
end
# git tag -a '#{tag}'
add_git_tag(
tag: tagName
)
# git push --tags
push_git_tags
# pod lib lint
pod_lib_lint(allow_warnings: true)
#通過trunk push到Cocoapods公開庫中
# pod trunk push "#{targetName}.podspec"
pod_push(path: path,allow_warnings:true)
## You may also push to a private repo instead of Trunk 發布到私有庫中
# pod repo push XMGFMSpecs "#{targetName}.podspec"
# pod_push(path: "#{targetName}.podspec", repo: repoName, allow_warnings:true)
其中git_tag_exists
在fastlane
的Action
中并不存在的,所以需要我們自定義一個這樣判斷tag是否存在的Action,如果tag存在,則刪除本地和遠程的tag,具體是如何自定義的,可以參考我的GitHub
其實長得都差不多,這里我就不再截圖了.....
寫在最后
我只想說碼字真的很傷腦,尤其是想把一個東西講明白就更燒腦
參考:
GitHub