使用fastlane實現react-native項目一鍵打包部署

前言

文章內容:html

  • 使用fastlane實現react-native自動化打包android和ios應用,並自動上傳到蒲公英(ios/android)或TestFlight(ios)
  • 自定義一個fastlane action

系統環境:react

  • MacOS

因爲ios只能使用Mac系統打包,因此本教程只針對Mac os用戶,window用戶能夠去fastlane官方文檔查看android的相關教程android

前置知識:ios

  • fastlane的配置文件是使用ruby編寫的,因此須要會ruby

適合閱讀人羣:git

  • 已有react-native項目,並進行過android和ios的原生打包上傳工做,想要使用fastlane進行打包部署流程優化

什麼是fastlane?

引用官網的一句話:fastlane是自動化iOS和Android應用程序Beta部署和發佈的最簡單方法。 🚀它能夠處理全部繁瑣的任務,例如生成屏幕截圖,處理代碼簽名以及發佈應用程序。github

實戰教程

步驟1:環境配置

安裝Xcode command line tools

xcode-select --install
複製代碼

安裝ruby

安裝web

brew install ruby
複製代碼

查看ruby是否安裝成功shell

ruby --version
複製代碼

安裝fastlane

使用RubyGems安裝fastlanejson

sudo gem install fastlane -NV
複製代碼

步驟2:初始化fastlane

進入你react-native項目的ios目錄react-native

cd path/to/your/react-native/project/ios
複製代碼

運行初始化命令

fastlane init
複製代碼

接着fastlane會須要你輸入選擇相關配置:

選擇2

選擇不含tvOS的那個,即2

輸入你開發使用的Apple ID,第一次配置還會須要密碼等信息,按照提示填寫便可

接下來fastlane會自動生成一些文件,而後顯示一些提示信息,可直接按回車跳過,提示內容大概以下:

  • 提示你將配置文件上傳到git
  • 告訴你文件名爲Fastfile是用來編寫配置的
  • 一些教程地址

自動生成的文件以下:

- fastlane/
   - Appfile
   - Fastfile
 - Gemfile
 - Gemfile.lock
複製代碼

步驟3:配置fastlane

打開FastFile

先解釋下自動生成配置的含義

default_platform(:ios) #默認平臺

platform :ios do
  desc "Push a new beta build to TestFlight" # 描述文字
  lane :beta do #lane的名稱,運行命令`fastlane 便可執行下面的代碼`
    increment_build_number(xcodeproj: "schema.xcodeproj") # 更新build版本號
    build_app(workspace: "schema.xcworkspace", scheme: "schema") # 打包
    upload_to_testflight # 上傳到testflight
  end
end
複製代碼

接下來,咱們把fastlane文件夾,Gemfile文件,Gemfile.lock移動到項目根目錄,由於後面會在同一個FastFile編寫ios和android的打包配置,固然你也能夠在android目錄運行fastlane,生成一個獨立的配置文件。

有人在這裏可能會問,爲何不直接在項目根目錄運行fastlane init

由於faslane在項目根目錄會提示找不到ios項目,因此必定要在項目的ios目錄或androi目錄下運行fastlane init才行

修改配置文件

將FastFile使用以下代碼替換

pyger_api_key = "your_pyger_api_key" # 替換成你蒲公英帳號的api_key
pyger_user_key = "your_pyger_user_key" # 替換成你蒲公英帳號的user_key

before_all do
  # 在lane執行前運行
end


# 打包ios
platform :ios do
  desc "打包ios並上傳"
  lane :publish do
    FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD = "xxxx"

    # 選擇上傳地址
    export_method = "ad-hoc"
    upload = UI.select("選擇上傳地址:", ["pgyer", "TestFlight"])
    if upload == "TestFlight"
      export_method = "app-store" # 上傳到testFlight,導出方式使用app-store
    else
      export_method = "ad-hoc" # 上傳到pyger,導出方式使用ad-hoc
    end

    scheme_name = "scheme_name" # 替換成你的ios項目要打包的scheme名稱

    project = "./ios/scheme_name.xcodeproj"
  
    # build加1
    increment_build_number(xcodeproj: project)
		# 獲取最新的build號碼
    build_number = get_build_number(xcodeproj: project)
		# 獲取應用版本號
    versoin_number = get_version_number(
      xcodeproj: project,
      target: scheme_name
    )
		# 拼接打包文件名稱
    output_name = "#{scheme_name}_#{versoin_number}_#{build_number}_#{Time.now.strftime('%Y%m%d%H%M%S')}.ipa"

    # 打包
    gym( # build_app的別名
      workspace: "./ios/scheme_name.xcworkspace", 
      scheme: scheme_name, 
      export_method: export_method, 
      output_directory: "./ios/build",
      output_name: output_name,
      clean: true, # 每次打包前清理項目
      suppress_xcode_output: true, # 打包過程當中不顯示xcode的輸出信息
    )

    # 上傳到TestFlight或者蒲公英
    if upload === "TestFlight"
      testflight()
    else
      pgyer(api_key: pyger_api_key, user_key: pyger_user_key)
    end
  end
end

# 打包android
platform :android do
  desc "打包android並上傳到蒲公英"
  lane :publish do
    project_dir = "./android/"
  
    gradle(task: 'clean', project_dir: project_dir) # 清理
    gradle(task: 'assemble', build_type: 'Release', project_dir: project_dir) # 打包

    pgyer(api_key: pyger_api_key, user_key: pyger_user_key) # 上傳到蒲公英
  end
end

after_all do
  # 在lane執行後運行
end
複製代碼

蒲公英上傳配置

運行命令,安裝蒲公英fastlane插件

fastlane add_plugin pgyer
複製代碼

輸入y

查看蒲公英的API Key和User Key,替換配置文件中的內容

運行

打包ios

fastlane ios publish
複製代碼

打包android

fastlane android publish
複製代碼

也能夠將命令加到到package.json

{
  "scripts": {
    "ios-publish": "fastlane ios publish",
    "android-publish": "fastlane android publish"
  }
}
複製代碼

打包ios

yarn ios-publish
複製代碼

打包android

yarn android-publish
複製代碼

建立一個自定義action

什麼是action?

action就是fastlane 運行時,要執行的動做。例如:前面FastFile中使用gymtestFlight等就是fastlane內置的action,具體可查看:fastlane內置action文

如何建立一個自定義action?

運行命令建立一個action

faslane new_action
複製代碼

輸入你的action名稱,命名規則:小駝峯或下劃線鏈接

這裏咱們輸入hello做爲action的名稱

而後會fastlane文件夾下看到自動生成的以下文件

- actions
	- hello.rb
複製代碼

下面來解釋下hello.rb的內容,打開文件hello.rb

module Fastlane
  module Actions
    module SharedValues
      HELLO_CUSTOM_VALUE = :HELLO_CUSTOM_VALUE # 定義能夠共享的變量
      
    end

    class HelloAction < Action
      def self.run(params)
        # fastlane will take care of reading in the parameter and fetching the environment variable:
        UI.message "Parameter API Token: #{params[:api_token]}"

        # sh "shellcommand ./path"

        # Actions.lane_context[SharedValues::HELLO_CUSTOM_VALUE] = "my_val" 共享變量賦值
      end

      #####################################################
      # @!group Documentation
      #####################################################

      def self.description
        "A short description with <= 80 characters of what this action does"
      end

      def self.details
        # Optional:
        # this is your chance to provide a more detailed description of this action
        "You can use this action to do cool things..."
      end

      def self.available_options
        # Define all options your action supports.

        # Below a few examples
        [
          FastlaneCore::ConfigItem.new(key: :api_token,
                                       env_name: "FL_HELLO_API_TOKEN", # The name of the environment variable
                                       description: "API Token for HelloAction", # a short description of this parameter
                                       verify_block: proc do |value|
                                          UI.user_error!("No API token for HelloAction given, pass using `api_token: 'token'`") unless (value and not value.empty?)
                                          # UI.user_error!("Couldn't find file at path '#{value}'") unless File.exist?(value)
                                       end),
          FastlaneCore::ConfigItem.new(key: :development,
                                       env_name: "FL_HELLO_DEVELOPMENT",
                                       description: "Create a development certificate instead of a distribution one",
                                       is_string: false, # true: verifies the input is a string, false: every kind of value
                                       default_value: false) # the default value if the user didn't provide one
        ]
      end

      def self.output
        # Define the shared values you are going to provide
        # Example
        [
          ['HELLO_CUSTOM_VALUE', 'A description of what this value contains']
        ]
      end

      def self.return_value
        # If your method provides a return value, you can describe here what it does
      end

      def self.authors
        # So no one will ever forget your contribution to fastlane :) You are awesome btw!
        ["Your GitHub/Twitter Name"]
      end

      def self.is_supported?(platform)
        # you can do things like
        #
        # true
        #
        # platform == :ios
        #
        # [:ios, :mac].include?(platform)
        #

        platform == :ios
      end
    end
  end
end
複製代碼
  • self.run:要運行的代碼

  • self.description:action簡單的功能描述

  • self.details:action詳細的功能描述

  • self.available_options:參數定義

  • self.output:當前action能夠共享給外部使用的變量

  • self.return_value:action的返回值

  • self.authors:action做者的信息

  • self.is_supported?(platform):支持的平臺

而後咱們修改一下hello.rb的內容

module Fastlane
  module Actions

    class HelloAction < Action
      def self.run(params)
        UI.message "Hello #{params[:name]}."
      end

      def self.description
        "一個打招呼的action"
      end

      def self.available_options
        [
          FastlaneCore::ConfigItem.new(key: :name,
                                       env_name: "FL_HELLO_NAME", # The name of the environment variable
                                       description: "你的名稱", # a short description of this parameter
                                       verify_block: proc do |value|
                                          UI.user_error!("name必填!") unless (value and not value.empty?)
                                       end),
        ]
      end
    end
  end
end

複製代碼

測試一下

在FastFlie加入測試代碼

lane :testHelloAction do
  hello() # 對應action文件名稱
end
複製代碼

運行

fastlane testHelloAction
複製代碼

結果

成功運行!

參考文章:

docs.fastlane.tools/

thecodingmachine.github.io/react-nativ…

www.pgyer.com/doc/view/fa…

相關文章
相關標籤/搜索