深入淺出 Fastlane 一看你就懂

分類:IT技術 時間:2016-10-11

這是《 Fastlane - iOS 和 android 的自動化構建工具 》系列的第二篇。

本篇我想著重介紹 fastlane 本身的基本使用,這裏使用 fastlane v1.98.0 作為演示版本。

系列索引

  1. Fastlane - iOS 和 Android 的自動化構建工具
  2. 深入淺出 Fastlane 一看你就懂

命令行工具

安裝之後默認會安裝一個命令行工具 fastlane ,利用它可以初始化、執行任務、查看任務定義、查看可用的動作和動作的詳細定義,甚至可以用它來創建自定義的動作、插件以及一些輔助功能。想了解的話可以先看看它的幫助:

$ fastlane --help

fastlane

CLI for 'fastlane' - The easiest way to automate building and releasing your iOS and Android apps

Run using `fastlane [platform] [lane_name]`
To pass values to the lanes use `fastlane [platform] [lane_name] key:value key2:value2`

commands:
action Shows more information for a specific command
actions Lists all available fastlane actions
add_plugin Add a new plugin to your fastlane setup
disable_crash_reporting Deprecated: fastlane doesn't use a crash reporter any more
docs Generate a markdown based documentation based on the Fastfile
enable_auto_complete Enable tab auto completion
enable_crash_reporting Deprecated: fastlane doesn't use a crash reporter any more
help Display global or [command] help documentation
init Helps you with your initial fastlane setup
install_plugins Install all plugins for this project
lanes Lists all available lanes and shows their description
list Lists all available lanes without description
new_action Create a new custom action for fastlane.
new_plugin Create a new plugin that can be used with fastlane
run Run a fastlane one-off action without a full lane
search_plugins Search for plugins, search query is optional
trigger Run a sepcific lane. Pass the lane name and optionally the platform first.
update_plugins Update all plugin dependencies

Global Options:
--verbose
-h, --help Display help documentation
-v, --version Display version information

Author:
Felix Krause <[email protected]>

Website:
https://fastlane.tools

GitHub:
https://github.com/fastlane/fastlane

我會隨著下面每個概念的解釋和展開來配合上面的命令一起講解。

生命周期

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

以上的部分大家在上一篇已經見識過了,有些還沒接觸到,不用著急都會一一說明。

任務(lane)

正常情況下你可能只會是用到一種任務方法 lane 但其實它會包含很多中高級用法。在文章的末尾會詳細描述。

任務定義

定義任務的方法類似於 rake 的 task,但使用上缺比前者要好用很多,見下表:

定義 是否必須 說明 備註 desc false 方法描述 可多次使用打到換行的目的 name true 方法名 符號化的方法名 options false 方法參數 返回 Hash 類型 task true 方法主體 參考 ruby 的方法代碼且支持 ruby 代碼
desc '定義一個 build 方法'
desc '參數 adhoc 判斷是否為內測版本, 默認為 false'
desc 'fastlane build'
desc 'fastlane build adhoc:true'
lane :build do |options|
# task to do something
adhoc = options[:adhoc] || false
puts "adhoc: #{adhoc}"

gym(type: adhoc ? 'adhoc' : 'appstore')
end

任務執行

一般情況下它需要配合定義好的 lane 才能使用,剛剛我們定義的一個 build 方法,我們這裏就試著執行一下吧。

# 默認執行
$ fastlane build
# 傳遞參數
$ fastlane build adhoc:true

任務互調

lane 其實可以理解為 def 的別名,因此多個 lane 的話實際上是可以相互調用的,這個其實特別實用,這樣其實我就可以把 cocoapods 的執行放到單獨的 lane 裏面而不是 before_all ,這樣執行非構建的任務就不會執行不相關的任務或動作,因此 fastlane 而產生了一個私有任務用內部使用 private_lane


default_platform :ios

platform :ios do
desc '構建前的準備工作'
desc '這是一個私有任務,僅供 Fastfile 內部 lane 調用使用'
lane :prepare do
cocoapods
match
end

desc '通用的構建任務'
desc 'fastlane build'
desc 'fastlane build type:adhoc'
lane :build do |options|
# 調用上面 prepare 私有任務
prepare

case options[:type]
when 'adhoc'
# 調用 下面 adhoc 任務
adhoc
else
# 調用下面 appstore 任務
appstore
end
end

desc '構建 adhoc 任務'
desc 'fastlane adhoc'
lane :adhoc do
gym(type: 'adhoc')
end

desc '構建 appstore 任務'
desc 'fastlane appstore'
lane :appstore do
gym(type: 'appstore')
end
end

上面的任務中, build / adhoc / appstore 都可以執行,只有 prepare 是無法通過命令行外部執行,如果執行會直接報錯:

$ fastlane prepare
[19:17:42]: You can't call the private lane 'prepare' directly

任務返回值

和 ruby 的方法一致,每個 lane 最後一行會默認作為返回值(無需 return )。


lane :sum do |options|
options[:a] + optiona[:b]
end

lane :calculate do
value = http://ju.outofmemory.cn/entry/sum(a: 3, b: 5)
puts value #=> 8
end

引入外部任務文件

Fastfile 除了自身以外還能夠引入外部其他的 Fastfile 並調用任務,只需要導入外部文件並使用特殊的方法標識即可:

1. import - 導入本地文件

# 導入 lanes 目錄的 AndroidFastfile
import "lanes/AndroidFastfile"

2. import_from_git - 導入 git 倉庫文件

可以直接引入 git 倉庫的 Fastfile 文件是一個非常贊的功能,通過使用發現其實現原理是先把 git 倉庫克隆下來後在引入相對於的文件,因此建議國內在沒有網絡加速(翻墻)的情況下盡量不用引入比較大的 git 倉庫,否則使用會需要漫長的等待…

# 導入 mozilla/Firefox-ios 項目下 fastlane 下面 Fastfile 文件
import_from_git(url: 'https://github.com/mozilla/firefox-ios')
# 或者
import_from_git(url: '[email protected]:mozilla/firefox-ios.git',
path: 'fastlane/Fastfile')

假若外部引入的 Fastfile 有個方法是 build ,在命令行工具直接執行即可,如果外部和內部都有相同的任務名,執行會直接報錯:

$ fastlane ios build

[!] Lane 'gradle' was defined multiple times!

如果發生這樣的事情且你希望在主體 Fastfile 也調用的話需要使用特殊的方法定義: override_lane

註意:此方法只會覆蓋外部的相同方法名的代碼執行,目前暫時無法使用類似 ruby 的 super 繼承原由方法!

override_lane :build do
...
end

任務查看

只需執行下面這行命令就可以看到非私有任務的可用列表信息

$ fastlane lanes

--------- ios---------
----- fastlane ios build
通用的構建任務
fastlane build
fastlane build type:adhoc

----- fastlane ios adhoc
構建 adhoc 任務

----- fastlane ios appstore
構建 appstore 任務

Execute using `fastlane [lane_name]`

擴展(Action)

擴展是 fastlane 的殺手鐧,重在集成了眾多非常優秀好用的方法供 lane 內部使用,截至 fastlane v 1.98.0 版本以包含 175 個擴展,這個數量還在陸續增加中。擴展初期是由發起人一個人完成,後續的大部分都是社區共享,如果你發現沒有你想要的擴展,可以先去 issues 搜索下沒有要麽自己動手提交要麽只有等待了.

擴展列表

$ fastlane actions
+--------------------+-------------------------------------------------------------+------------------+
| Available fastlane actions |
+--------------------+-------------------------------------------------------------+------------------+
| Action | Description | Author |
+--------------------+-------------------------------------------------------------+------------------+
| adb | Run ADB Actions | hjanuschka |
| adb_devices | Get an Array of Connected android device serials | hjanuschka |
| add_git_tag | This will add an annotated git tag to the current branch | Multiple |
...
+--------------------+-------------------------------------------------------------+------------------+
Total of 175 actions

Get more information for one specific action using `fastlane action [name]`

擴展使用幫助

# 查看 adb 擴展的使用幫助
$ fastlane action adb
Loading documentation for adb:

+---------------------------------+
| adb |
+---------------------------------+
| Run ADB Actions |
| |
| see adb --help for more details |
| |
| Created by hjanuschka |
+---------------------------------+

+----------+----------------------------------------------------------------------+-------------------+---------+
| adb Options |
+----------+----------------------------------------------------------------------+-------------------+---------+
| Key | Description | Env Var | Default |
+----------+----------------------------------------------------------------------+-------------------+---------+
| serial | Android serial, which device should be used for this command | FL_ANDROID_SERIAL | |
| command | All commands you want to pass to the adb command, e.g. `kill-server` | FL_ADB_COMMAND | |
| adb_path | The path to your `adb` binary | FL_ADB_PATH | adb |
+----------+----------------------------------------------------------------------+-------------------+---------+

+-------------------------------+
| adb Return Value |
+-------------------------------+
| The output of the adb command |
+-------------------------------+

More information can be found on https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Actions.md

創建自定義擴展

通過內置的命令創建你需要的擴展,擴展名必須是全部小寫且只能使用下劃線分割詞組,生成好的擴展文件會在 fastlane/actions 目錄找到:

$ fastlane new_action
Must be lower case, and use a '_' between words. Do not use '.'
examples: 'testflight', 'upload_to_s3'
Name of your action: hello
[15:33:15]: Created new action file './fastlane/actions/hello.rb'. Edit it to implement your custom action.

這塊會占比較大的篇幅,盡情期待後續的展開。

引入外部擴展

這塊其實也有兩種方法可以引入,文件引入是官方教程提供的方法,第二種是我個人嘗試出來的,第三種是最近版本才官方支持的。

1. 本地文件引入

自定義的擴展其實也算是本地文件引入的一種形式,當然位於其他路徑的通過指定方法也能做到

# 引入項目根目錄 script/share_actions 路徑
actions_path '../script/share_actions'

2. rubygem 引入

不再建議使用本方法,請看第三種插件引入。

我在團隊內部創建了一個自定義的擴展,僅限於團隊內部使用而無法貢獻社區,我只能采取封裝成 ruby gem 包,通過 ruby 的 require 方式引入,最終可以完美支持,目前已在項目中使用大半年之久。最重要的是我是開源的: fastlane-qyer

# 首先安裝需要的 rubygem: gem install fastlane-qyer
require 'fastlane-qyer'

lane :upload do
qyer(api_key: '[token]')
end

註意,使用 rubygem 引入的無法在 fastlane actions 中顯示出來,也無法使用 fastlane action [name] 查看使用幫助。我猜想一是官方沒有這樣提供思路,二是就算你引入了 gem 也不是特別好判斷裏面的文件結構。

3. 插件引入

我註意到 1.93.0 增加了插件機制,很好的解決第二種出現的一些問題。大概看了一下主要是采用 Gemfile 的方式使用 Pluginfile 維護了引入第三方插件列表。實現原理還是屬於第二種方法。

通過 fastlane search_plugins 查看當前支持的插件,並使用 fastlane add_plugins [name] 引入。

$ fastlane search_plugins
[16:04:33]: Listing all available fastlane plugins

+--------------------------+---------------------------------------------------+-----------+
| Available fastlane plugins |
+--------------------------+---------------------------------------------------+-----------+
| Name | Description | Downloads |
+--------------------------+---------------------------------------------------+-----------+
| ruby | Useful fastlane actions for Ruby projects | 782 |
| versioning | Allows to work set/get app version directly | 758 |
| | to/from Info.plist | |
| branding | Add some branding to your fastlane output | 716 |
| instrumented_tests | New action to run instrumented tests for android. | 590 |
| | This basically creates and boots an emulator | |
| | before running an gradle commands so that you can | |
| | run instrumented tests against that emulator. | |
| | After the gradle command is executed, the avd | |
| | gets shut down and deleted. This is really | |
| | helpful on CI services, keeping them clean and | |
| | always having a fresh avd for testing. | |
| xamarin_build | Build xamarin android\ios projects | 582 |
| appicon | Generate required icon sizes and iconset from a | 509 |
| | master application icon. | |
...
| download_file | This action downloads a file from an HTTP/HTTPS | 171 |
| | url (e.g. ZIP file) and puts it in a destination | |
| | path | |
+--------------------------+---------------------------------------------------+-----------+

# 添加 sentry 插件
$ fastlane add_plugin sentry
[16:16:23]: Plugin 'fastlane-plugin-sentry' was added to './fastlane/Pluginfile'
[16:16:23]: It looks like fastlane plugins are not yet set up for this project.
[16:16:23]: fastlane will create a new Gemfile at path 'Gemfile'
[16:16:23]: This change is neccessary for fastlane plugins to work
Should fastlane modify the Gemfile at path 'Gemfile' for you? (y/n)
y
[16:16:29]: Successfully modified 'Gemfile'
[16:16:29]: Make sure to commit your Gemfile, Gemfile.lock and Pluginfile to version control
Installing plugin dependencies...
Successfully installed plugins

$ cat fastlane/Pluginfile
# Autogenerated by fastlane
#
# Ensure this file is checked in to source control!

gem 'fastlane-plugin-sentry'

更詳細的繼續期待後續報道,我要挖坑無數。

擴展的命令行調用

社區的力量果然是很強大的,陸續添加了那麽多功能,早期用戶表示不開心!嗯,由於社區的呼聲和貢獻目前可以通過命令調用擴展:

# 使用 notification 擴展發送一個通知消息
$ fastlane run notification message:"Hi macOS" title:"Fastlane Notification"
[15:58:05]: --------------------------
[15:58:05]: --- Step: notification ---
[15:58:05]: --------------------------
[15:58:05]: Result: true

輔助功能

自動更新

fastlane 提供一個方法 update_fastlane 用於對於自身的版本檢查和更新,這個第一篇文章我也有提到過。它其實一個是一個擴展,使用 fastlane action update_fastlane 能夠看到使用幫助。它有一個參數是可以指定檢查特定的 fastlane 工具並進行更新,但其實它是使用 rubygems 進行對 gem 的更新,因此這塊其實可以傳入任何需要檢查並更新的 gem:

update_fastlane(tools:'fastlane,gym,match,cocoapods,rest-client')

環境變量

從 fastlane 的設計體系上在各個地方都加入了環境變量的支持,每個擴展的參數、以及擴展需要共享給其他擴展和任務讀取的數據都是通過環境變量獲取,如下是我收集的比較常用的列表:

環境變量 來源 說明 備註 FASTLANE_USER credentials_manager Apple 開發者賬戶名 驗證通過後會保存 Keychain FASTLANE_PASSWORD credentials_manager Apple 開發者賬戶密碼 驗證通過後會保存 Keychain FASTLANE_TEAM_ID
CERT_TEAM_ID produce
sigh Apple 團隊 ID DELIVER_USER
PRODUCE_USERNAME deliver
produce iTunesConnect 賬戶名 DELIVER_PASSWORD deliver iTunesConnect 賬戶密碼 MATCH_PASSWORD match 證書加/解密密碼 FASTLANE_XCODE_LIST_TIMEOUT fastlane_core 獲取 iOS Scheme 的超時時間 默認 10s

這是《 Fastlane - iOS 和 Android 的自動化構建工具 》系列的第二篇。


Tags: Android available building initial without

文章來源:


ads
ads

相關文章
ads

相關文章

ad