自动化工具Fastlane入门实践

1,328 阅读3分钟

什么是自动化

自动化是通过简单的一条命令, 去自动执行一组固定操作。 自动化使用场景包括:

  • 测试
  • 打包上传审核
  • 分发

Fastlane工具介绍

Fastlane是一个ruby脚本集合

Fastlane的基本概念

lane(航道) 为完成某一特定任务所做的一系列脚本操作的集合。表示为一个完整的执行流程。

Action机制 Action是Fastlane自动化流程中的最小执行单元,体现在Fastfile脚本中的一个个命令。比如:cocoapods, git_add等等,而这些命令背后都对应一个用Ruby编写的脚本。源码链接

常用action

  • produce 创建可用于 iTunes Connect 和 Apple Developer Portal 的 iOS app。
  • cert 自动创建和维护 iOS 代码签名证书。
  • sigh 创建、更新、下载和修复 provisioning profiles。
  • snapshot 自动将 App 屏幕截图本地化到每种设备上。
  • frameit 将屏幕截图适配到适当的设备屏幕大小。
  • gym 创建和打包 iOS app。
  • deliver 上传屏幕截图、元数据和 App 到 App 商店。
  • PEM 自动创建和更新 Push 通知的 profile。

Fastlane的安装

升级brew brew update

安装ruby brew install ruby

安装fastlane sudo gem install fastlane

fastlane的基本用法

  1. 进入项目根目录

  2. 生成Fastfile文件 fastlane init

  3. 编辑Fastfile文件

执行步骤 执行语句 action语句
安装pod pod install cocoapods
提交代码到远程代码仓库 git add .``git commit -m 'xx' git push origin git_add git_commit push_to_git_remote
打标签, 并提交 git tag -a xx -m 'xxx' git push --tags add_git_tag push_git_tags
对spec文件进行验证&提交 pod lib lint pod repo push XXXSpecs XXX.spec pod_lib_lint pod_push
desc 'ManagerLib 使用这个航道, 可以快速的对自己的私有库, 进行升级维护'
lane :ManagerLib do |options|

tagName = options[:tag]
targetName = options[:target]

# 具体这个航道上面执行哪些行为

# 1. pod install
cocoapods(
clean: true,
podfile: "./Example/Podfile"
)

# 2. git add .
git_add(path: ".")
#    git commit -m 'xxx'
git_commit(path: ".", message: "版本升级维护")
#    git push origin master
push_to_git_remote

# 3. git tag 标签名称
add_git_tag(
tag: tagName
)
#    git push --tags
push_git_tags

# 4. pod spec lint
pod_lib_lint(allow_warnings: true)
#    pod repo push XXXX xxx.podspec
pod_push(path: "#{targetName}.podspec", repo: "XMGFMSpecs", allow_warnings: true)
end

自定义action

有些action, 并没有人提供; 那么我们可以自己自定来满足我们的需求

module Fastlane
  module Actions
    module SharedValues
      REMOVE_TAG_CUSTOM_VALUE = :REMOVE_TAG_CUSTOM_VALUE
    end

    class RemoveTagAction < Action
      def self.run(params)
      
      tagName = params[:tag]
      isRemoveLocalTag = params[:rL]
      isRemoveRemoteTag = params[:rR]
      
      # 1. 先定义一个数组, 用来存储所有需要执行的命令
      
      cmds = []
      
      # 2. 往数组里面, 添加相应的命令
      # 删除本地标签
      # git tag -d 标签名称
      if isRemoveLocalTag
        cmds << "git tag -d #{tagName} "
      end
    
      # 删除远程标签
      # git push origin :标签名称
      if isRemoveRemoteTag
        cmds << " git push origin :#{tagName}"
      end

      #3. 执行数组里面的所有命令
     
      result = Actions.sh(cmds.join('&'));
      return result
      end


      def self.description
        "移除git中本地或远程仓库的tag值"
      end

      def self.details
        # Optional:
        # this is your chance to provide a more detailed description of this action
        "我们可以使用这个action ,来删除本地或者远程标签"
      end

      def self.available_options
        # Define all options your action supports. 
        
        # Below a few examples
        [

                FastlaneCore::ConfigItem.new(key: :tag,
                                             description: "需要被删除的标签名称",
                                             optional: false,
                                             is_string: true),
                FastlaneCore::ConfigItem.new(key: :rL,
                                             description: "是否需要删除本地标签",
                                             optional: true,
                                             is_string: false,
                                             default_value: true),
                FastlaneCore::ConfigItem.new(key: :rR,
                                             description: "是否需要删除远程标签",
                                             optional: true,
                                             is_string: false,
                                             default_value: true)
        ]
      end

      def self.output

      end

      def self.return_value
        nil
      end

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

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

        platform == :ios
      end
    end
  end
end