什么是自動(dòng)化?
通過(guò)簡(jiǎn)單的一條命令, 去自動(dòng)執(zhí)行一組固定操作
自動(dòng)化的使用場(chǎng)景?
測(cè)試
打包上傳審核
分發(fā)
自動(dòng)化方案?
fastlane(快速航道):Fastlane是一個(gè)ruby腳本集合
關(guān)于Fastlane的概念
- lane:航道
- Action機(jī)制:
Action是Fastlane自動(dòng)化流程中的最小執(zhí)行單元,體現(xiàn)在Fastfile腳本中的一個(gè)個(gè)命令
比如:cocoapods, git_add等等,而這些命令背后都對(duì)應(yīng)一個(gè)用Ruby編寫(xiě)的腳本。
-
目前所有的Action:
常用action:
- produce 創(chuàng)建可用于 iTunes Connect 和 Apple Developer Portal 的 iOS app。
- cert 自動(dòng)創(chuàng)建和維護(hù) iOS 代碼簽名證書(shū)。
- sigh 創(chuàng)建、更新、下載和修復(fù) provisioning profiles。
- snapshot 自動(dòng)將 App 屏幕截圖本地化到每種設(shè)備上。
- frameit 將屏幕截圖適配到適當(dāng)?shù)脑O(shè)備屏幕大小。
- gym 創(chuàng)建和打包 iOS app。
- deliver 上傳屏幕截圖、元數(shù)據(jù)和 App 到 App 商店。
- PEM 自動(dòng)創(chuàng)建和更新 Push 通知的 profile。
fastlane安裝(有近200M)
// 安裝命令
sudo gem install -n /usr/local/bin fastlane
// 注意:-n /usr/local/bin 不能少,
// 否則會(huì)報(bào)文件夾權(quán)限錯(cuò)誤:` While executing gem ... (Gem::FilePermissionError)
You don't have write permissions for the /usr/bin directory` .
如果要求Ruby版本最新:brew update
fastlane使用
1.進(jìn)入根目錄
2.fastlane init:如果不需要上傳等操作,
3.在Fastfile文件中, 描述不同的"航道"
4.在項(xiàng)目根目錄下, 執(zhí)行某個(gè)"航道"
實(shí)踐操作
- 選一個(gè)組件來(lái)操作LFRemotePlayer
- 創(chuàng)建本地庫(kù),pod lib create LFRemotePlayer,拖入代碼
- 創(chuàng)建純凈遠(yuǎn)程庫(kù)
- 修改LFRemotePlayer的描述文件
- 添加遠(yuǎn)程關(guān)聯(lián),cd LFRemotePlayer,git remote add origin https://git.oschina.net/lovell123/LFRemotePlayer.git
- 以上只需做一次,以下每次都要做,用fastlane
- fastlane init :
fastlane init 后 LFRemotePlayer文件夾內(nèi)多出兩個(gè)文件夾:fastlane文件夾和LFRemotePlayer同一層級(jí)的build文件夾,如下圖。

以下中括號(hào)內(nèi)的暫不需要:
【然后要填入付費(fèi)的蘋(píng)果開(kāi)發(fā)者賬號(hào)和密碼,會(huì)在賬號(hào)對(duì)應(yīng)的Dev Center和iTunes connect創(chuàng)建一個(gè)新的APP,最后會(huì)在本地生成截屏信息、各種文件夾,這是后期做打包、測(cè)試、分發(fā)時(shí)候要用到的東西。但目前我們要做的是維護(hù)一個(gè)本地的私有庫(kù),還不需要那些東西,最重要的是我沒(méi)有付費(fèi)的開(kāi)發(fā)者賬號(hào)!】

所以fastlane init 無(wú)法最終完成,control + z,終止。手動(dòng)操作一波:刪掉build文件夾,刪掉fastlane文件夾里面的Appfile。

- 進(jìn)入fastlane文件夾,touch Fastfile,F(xiàn)astfile是類(lèi)似Podfile的一種文件。Fastfile是用于描述航道的。
- 編寫(xiě)航道:Fastfile里面的路徑都是相對(duì)根目錄來(lái)寫(xiě),比如podfile的路徑,是從Fastfile位置到根目錄再到podfile的位置:
# 1. pod install
cocoapods(
clean: true,
podfile: "./Example/Podfile"
)
Fastfile文件:
# 描述:
desc '使用 ManagerLib 這個(gè)航道, 可以快速的對(duì)自己的私有庫(kù), 進(jìn)行升級(jí)維護(hù)'
# 本航道名:ManagerLib
lane :ManagerLib do |options|
# options:傳進(jìn)來(lái)的參數(shù),后面的tag和target是對(duì)應(yīng)的字段
tagName = options[:tag]
targetName = options[:target]
# 具體這個(gè)巷道上面執(zhí)行哪些行為
# 1. pod install
cocoapods(
clean: true,
podfile: "./Example/Podfile"
)
# 2. git add .
git_add(path: ".")
# git commit -m 'xxx'
git_commit(path: ".", message: "版本升級(jí)維護(hù)")
# git push origin master
push_to_git_remote
# 驗(yàn)證tag是否存在,如果存在, 應(yīng)該刪除本地標(biāo)簽和遠(yuǎn)程標(biāo)簽
#if 判斷標(biāo)簽是否存在
# 執(zhí)行刪除本地/遠(yuǎn)程標(biāo)簽
#end
if git_tag_exists(tag: tagName)
UI.message("發(fā)現(xiàn)tag:#{tagName} 已經(jīng)存在, 即將執(zhí)行, 刪除動(dòng)作 ??")
remove_tag(tag: tagName)
else
UI.message("tag:#{tagName} 不存在, 開(kāi)始提交 ??")
end
# 3. git tag 標(biāo)簽名稱
add_git_tag(
tag: tagName
)
# git push --tags
push_git_tags
# 4. pod spec lint (注意要添加公、私倉(cāng)庫(kù))
pod_lib_lint(allow_warnings: true, sources: ["https://gitee.com/LFCoding/xxxSpecs","https://github.com/CocoaPods/Specs"])
# pod repo push XXXX xxx.podspec (注意要添加公、私倉(cāng)庫(kù))
pod_push(path: "#{targetName}.podspec", repo: "xxxSpec", allow_warnings: true, sources: ["https://gitee.com/LFCoding/xxxSpecs","https://github.com/CocoaPods/Specs"])
remove_tag.rb文件:
module Fastlane
module Actions
module SharedValues
REMOVE_TAG_CUSTOM_VALUE = :REMOVE_TAG_CUSTOM_VALUE
end
class RemoveTagAction < Action
# 1、運(yùn)行action執(zhí)行的動(dòng)作
def self.run(params)
tagName = params[:tag]
isRemoveLocalTag = params[:rL]
isRemoveRemoteTag = params[:rR]
# 1. 先定義一個(gè)數(shù)組, 用來(lái)存儲(chǔ)所有需要執(zhí)行的命令
cmds = []
# 2. 往數(shù)組里面, 添加相應(yīng)的命令
# 刪除本地標(biāo)簽
# git tag -d 標(biāo)簽名稱
if isRemoveLocalTag
cmds << "git tag -d #{tagName} "
end
# 刪除遠(yuǎn)程標(biāo)簽
# git push origin :標(biāo)簽名稱
if isRemoveRemoteTag
cmds << " git push origin :#{tagName}"
end
#3. 執(zhí)行數(shù)組里面的所有命令(用&連接,類(lèi)似git add . & git commit -m這樣執(zhí)行也是可以的)
result = Actions.sh(cmds.join('&'));
return result
end
# 2、描述整個(gè)action有什么用
def self.description
"牛逼的action"
end
# 3、詳細(xì)的描述
def self.details
# Optional:
# this is your chance to provide a more detailed description of this action
"此牛逼action,可以刪除本地和遠(yuǎn)程的某一個(gè)標(biāo)簽"
end
# 4、可用選項(xiàng),傳參數(shù)
def self.available_options
# Define all options your action supports.
# 對(duì)傳進(jìn)來(lái)的三個(gè)參數(shù) tag、rL、rR 進(jìn)行描述。
[
# key:參數(shù)名稱,tag、rL、rR 。
# description:描述key對(duì)應(yīng)的是參數(shù)tag的是干嘛的。
# optional:該tag參數(shù)是否可選,true表示該參數(shù)可以不傳,false表示一定要傳。
# is_string:是指?jìng)鹘okey的值是否字符串。
# default_value:缺省值
FastlaneCore::ConfigItem.new(key: :tag,
description: "需要被刪除的標(biāo)簽名詞",
optional:false,
is_string: true),
FastlaneCore::ConfigItem.new(key: :rL,
description: "是否需要?jiǎng)h除本地標(biāo)簽",
optional:true,
is_string: false,
default_value:true),# 默認(rèn)值,表示沒(méi)值就默認(rèn)rL為true
FastlaneCore::ConfigItem.new(key: :rR,
description: "是否需要?jiǎng)h除遠(yuǎn)程標(biāo)簽",
optional:true,
is_string: false,
default_value:true)# 默認(rèn)值,表示沒(méi)值就默認(rèn)rR為true
]
end
#5、輸出,暫時(shí)清空
def self.output
end
# 返回值,暫時(shí)寫(xiě)nil
def self.return_value
nil
end
# 作者的名字
def self.authors
# So no one will ever forget your contribution to fastlane :) You are awesome btw!
["luo feng"]
end
#平臺(tái)的描述
def self.is_supported?(platform)
# you can do things like
#
# true
#
# platform == :ios
#
# [:ios, :mac].include?(platform)
#
platform == :ios
end
end
end
end
-
cd 回到根目錄,
fastlane lanes,檢驗(yàn)是否有語(yǔ)法錯(cuò)誤,如下圖表示沒(méi)錯(cuò),但不代表邏輯沒(méi)錯(cuò)。
Snip20170712_129.png 使用fastlane:
fastlane ManagerLib tag:0.1.0 target:LFRemotePlayer,
格式:fastlane ManagerLib tag:標(biāo)簽 target:組件名(podspec文件名)-
檢索
pod search LFRemotePlayer,報(bào)錯(cuò)如下。解決:1、pod cache clean --all清緩存,2、刪索引緩存search_index.json(位置:/Users/fengluo/Library/Caches/CocoaPods/search_index.json
),3、再搜索,即可。
Snip20170712_131.png 宿主工程使用。
宿主podfile中引入source,pod 'repo name',pod install,隨便導(dǎo)入庫(kù)某一個(gè)頭文件,編譯成功即可。


遇到的問(wèn)題
- 如果在spec文件夾里面用 pod repo add <repo name>,會(huì)添加失敗,退到repos文件夾。
- 注意忽略文件加上.DS_Store
- spec描述文件驗(yàn)證、推送加上allow_warnings
- 剛提交完spec描述文件,pod search 搜索不到,這時(shí)候清緩存pod cache clean --all,刪搜索緩存文件search_index.json,再次搜索即可成功。
- fastlane init需要付費(fèi)的賬號(hào)才能成功,有好些功能:打包、測(cè)試、分發(fā)等,若是沒(méi)有,則control+z停止,在fastlane文件夾中touch Fastfile,我們只需要維護(hù)一個(gè)本地私有庫(kù)。

