組件20:組件化-自動(dòng)化

什么是自動(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ī)制:
    1. Action是Fastlane自動(dòng)化流程中的最小執(zhí)行單元,體現(xiàn)在Fastfile腳本中的一個(gè)個(gè)命令

    2. 比如:cocoapods, git_add等等,而這些命令背后都對(duì)應(yīng)一個(gè)用Ruby編寫(xiě)的腳本。

    3. 目前所有的Action:

    4. 常用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í)踐操作

  1. 選一個(gè)組件來(lái)操作LFRemotePlayer
  2. 創(chuàng)建本地庫(kù),pod lib create LFRemotePlayer,拖入代碼
  3. 創(chuàng)建純凈遠(yuǎn)程庫(kù)
  4. 修改LFRemotePlayer的描述文件
  5. 添加遠(yuǎn)程關(guān)聯(lián),cd LFRemotePlayer,git remote add origin https://git.oschina.net/lovell123/LFRemotePlayer.git
  6. 以上只需做一次,以下每次都要做,用fastlane
  7. fastlane init :
    fastlane init 后 LFRemotePlayer文件夾內(nèi)多出兩個(gè)文件夾:fastlane文件夾和LFRemotePlayer同一層級(jí)的build文件夾,如下圖。
fastlane init生成的文件夾.png

以下中括號(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)!】

填入付費(fèi)賬號(hào).png

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

fastlane操作的根目錄.png
  1. 進(jìn)入fastlane文件夾,touch Fastfile,F(xiàn)astfile是類(lèi)似Podfile的一種文件。Fastfile是用于描述航道的。
  2. 編寫(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
  1. cd 回到根目錄,fastlane lanes,檢驗(yàn)是否有語(yǔ)法錯(cuò)誤,如下圖表示沒(méi)錯(cuò),但不代表邏輯沒(méi)錯(cuò)。

    Snip20170712_129.png

  2. 使用fastlane:fastlane ManagerLib tag:0.1.0 target:LFRemotePlayer,
    格式:fastlane ManagerLib tag:標(biāo)簽 target:組件名(podspec文件名)

  3. 檢索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

  4. 宿主工程使用。
    宿主podfile中引入source,pod 'repo name',pod install,隨便導(dǎo)入庫(kù)某一個(gè)頭文件,編譯成功即可。

Fastfile解釋.png
Snip20170712_138.png

遇到的問(wèn)題

  1. 如果在spec文件夾里面用 pod repo add <repo name>,會(huì)添加失敗,退到repos文件夾。
  2. 注意忽略文件加上.DS_Store
  3. spec描述文件驗(yàn)證、推送加上allow_warnings
  4. 剛提交完spec描述文件,pod search 搜索不到,這時(shí)候清緩存pod cache clean --all,刪搜索緩存文件search_index.json,再次搜索即可成功。
  5. fastlane init需要付費(fèi)的賬號(hào)才能成功,有好些功能:打包、測(cè)試、分發(fā)等,若是沒(méi)有,則control+z停止,在fastlane文件夾中touch Fastfile,我們只需要維護(hù)一個(gè)本地私有庫(kù)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容