Fastlane 一键打包上传Fir

1、什么是Fastlane

The easiest way to build and release mobile apps.
Fastlane是一套使用Ruby写的自动化工具集,用于iOS和Android的自动化打包、发布等工做,能够节省大量的时间。 android

50F602D2-5FDE-4AB5-B865-F67C49247027.png

1608265-f63702702cfa790f.png

fastlaneDemo.gif

Github开源地址 fastlane官网)ios

2、用来作什么

iOS一键脚本完成如下步骤: 1 reset_git_repo 移除git中未提交的内容 2 git pull 只拉取最新tag 3 checkout 切换到最新的tag 4 submodule update 更新子模块 5 Pod install 第三方库管理工具 6 Archive、Sign 打包、签名 7 upload fir 上传Fir 8 notification 钉钉机器人git

Android 能够实现一键多渠道打包: 1 reset_git_repo 移除git中未提交的内容 2 git pull 只拉取最新tag 3 checkout 切换到最新的tag 4 submodule update 更新子模块 5 gradle 打包 6 add_channels_to_apk 拷贝apk,修改文件名为渠道名,渠道名写入META-INFO目录 参考连接:Fastlane实战(三):Fastlane在Android平台的应用github

3、安装

  1. 安装Fastlane sudo gem install fastlane
  2. 切换到工程目录初始化 fastlane init
  3. 运行(lane_name为自定义lane 名字) fastlane lane_name

4、使用

  1. 构建Fastlane 打包上传 fir
# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
# https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
# https://docs.fastlane.tools/plugins/available-plugins
#

# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane

fastlane_version "2.96.1"
default_platform(:ios)

platform :ios do
  desc "Push a new beta build to fir"
  lane :tofir do
	# Deletes the Xcode Derived Data
	clear_derived_data

 	# discarding uncommitted changes
  	reset_git_repo(
      force: true,
      skip_clean: true,
      disregard_gitignore: false
      )


  	# git pull only the tags, no commits
	git_pull(only_tags: true)

	# get recent tag
  	recentTagName = last_git_tag

  	# (fastlane-plugin-git_switch_branch为插件)check out tag
  	git_switch_branch(branch: recentTagName)

    # submodule init and update
    git_submodule_update(
    	init: true,
    	recursive: true
    	)

  	# pod install
  	cocoapods

  	scheme = "ProCloser"
  	ipa_dir  = "./fastlane_build/"+Time.new.strftime('%Y-%m-%d')
  	ipa_name = recentTagName + "_" + Time.new.strftime('%Y%m%d%H%M')

  	# gym用来编译 打包 签名
  	gym(
   	 output_directory: ipa_dir,
   	 output_name: "#{ipa_name}.ipa",
	    clean: true,
	    workspace: scheme + ".xcworkspace",
	    scheme: scheme,
	    export_xcargs: "-allowProvisioningUpdates",
	    export_options: {
	      method: "ad-hoc", # 指定打包方式
	      teamID: "xxxxxxxxxxx",
	      thinning: "<none>",
	    }
    )

  	# (fastlane-plugin-firim为插件)上传ipa到fir.im服务器,在fir.im获取firim_api_token
  	firim(firim_api_token: "xxxxxxxxxxxxxxx")


	desc "Notification 钉钉机器人"
    # 钉钉机器人
  	app_patch   = ipa_dir + "/#{ipa_name}.ipa"
  	app_version = get_ipa_info_plist_value(ipa: app_patch, key: "CFBundleShortVersionString")
  	app_build_version = get_ipa_info_plist_value(ipa: app_patch, key: "CFBundleVersion")
  	app_name    = get_ipa_info_plist_value(ipa: app_patch, key: "CFBundleDisplayName")
  	app_url 	= "xxxxxxxx"
  	app_icon 	= "xxxxxxx"
  	dingTalk_url = "xxxxxxxxx"
  
  	dingMessage = 
  	{
   	 msgtype: "link", 
   	 link: {
        text: "对应git tag为: #{recentTagName}", 
        title: "iOS #{app_name} #{app_version} (#{app_build_version}) 测试版本", 
        picUrl: "#{app_icon}", 
        messageUrl: "#{app_url}"
   	 	}
	}

	uri = URI.parse(dingTalk_url)
	https = Net::HTTP.new(uri.host, uri.port)
	https.use_ssl = true

	request = Net::HTTP::Post.new(uri.request_uri)
	request.add_field('Content-Type', 'application/json')
	request.body = dingMessage.to_json

	response = https.request(request)
	puts "--------------- 钉钉机器人已经通知 ✅ ---------------"
	puts "Response #{response.code} #{response.message}: #{response.body}"

  end
end
复制代码
  1. 增长一键远程打包脚本

客户端:shell

# 远程到打包机,运行打包机中的shell脚本。在打包机中配置了ssh信任因此不须要输入密码
ssh tiejin@tiejinios.local '/Users/tiejin/closerToFir.sh'
复制代码

服务器:json

# 解锁mac中的keychain,fastlane打包命令中的证书签名须要用到keychain中记录的帐户和密码。
security unlock-keychain -p 2018 $KEYCHAIN
# 进入指定目录
cd closer
# 设置环境变量,不然fastlane中涉及到/usr/local/bin/命令部分找不到
export PATH=/usr/local/bin/:$PATH
# 执行fastlane
fastlane tofir
复制代码
  1. 和 Jenkins 结合一块儿使用api

  2. 自定义Actions 0 什么是Action Action 是Fastlane中的最小执行单元,Action中封装了一些shell命令。数组

1 建立自定义Action ,会自动生成xxx.rb文件 fastlane new_actionruby

2 编辑 xxx.rb 文件,修改具体逻辑。bash

module Fastlane
    module Actions
        module SharedValues
            REMOVE_TAG_CUSTOM_VALUE = :REMOVE_TAG_CUSTOM_VALUE
        end
        
        class RemoveTagAction < Action
            def self.run(params)
            # 最终要执行的东西,在这里执行
            
            # 一、获取全部输入的参数
            # tag 的名称 如 0.1.0
            tageName = params[:tag]
            # 是否须要删除本地标签
            isRemoveLocationTag = params[:isRL]
            # 是否须要删除远程标签
            isRemoveRemoteTag = params[:isRR]
            
            # 二、定义一个数组,准备往数组里面添加相应的命令
            cmds = []
            
            # 删除本地的标签
            # git tag -d 标签名称
            if isRemoveLocationTag
                cmds << "git tag -d #{tageName}"
            end
            
            # 删除远程标签
            # git push origin :标签名称
            if isRemoveRemoteTag
                cmds << "git push origin :#{tageName}"
            end
    
            # 三、执行数组里面的全部的命令
            result = Actions.sh(cmds.join('&'))
            UI.message("执行完毕 remove_tag的操做 🚀")
            return result
   
        end
        
        #####################################################
        # @!group Documentation
        #####################################################
        
        def self.description
        "输入标签,删除标签"
    end
    
    def self.details
    # Optional:
    # this is your chance to provide a more detailed description of this action
"咱们可使用这个标签来删除git远程的标签\n 使用方式是:\n remove_tag(tag:tagName,isRL:true,isRR:true) \n或者 \nremove_tag(tag:tagName)"
end

# 接收相关的参数
def self.available_options

# Define all options your action supports.

# Below a few examples
[

# 传入tag值的参数描述,不能够忽略<必须输入>,字符串类型,没有默认值
FastlaneCore::ConfigItem.new(key: :tag,
                             description: "tag 号是多少",
                             optional:false,# 是否是能够省略
                             is_string: true, # true: 是否是字符串
                             ),
# 是否删除本地标签
FastlaneCore::ConfigItem.new(key: :isRL,
                             description: "是否删除本地标签",
                             optional:true,# 是否是能够省略
                             is_string: false, # true: 是否是字符串
                             default_value: true), # 默认值是啥

# 是否删除远程标签
FastlaneCore::ConfigItem.new(key: :isRR,
                             description: "是否删除远程标签",
                             optional:true,# 是否是能够省略
                             is_string: false, # true: 是否是字符串
                             default_value: true) # 默认值是啥

]
end

def self.output
# Define the shared values you are going to provide
# Example

end

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

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

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

platform == :ios
end
end
end
end
复制代码

5、深刻学习Fastlane

0. Fastlane基本知识

  1. Fastlane文件结构

Gemfile 和 Bundle 是什么: Gemfile文件:gem包管理工具,如:管理fastlane、cocoapods Appfile文件:从 Apple Developer Portal 获取和项目相关的信息 Fastlane文件:核心文件,主要用于 cli 调用和处理具体的流程 Deliverfile:从 iTunes Connect 获取和项目相关的信息

  1. Fastlane的Plugin机制
  • Action:对于Fastlane来讲Action的收录是很是严格,而且有很强的通用性才能收录其中,即便接收了,整个发布周期也会比较长,并且之后不管是升级仍是Bug修复,都依赖Fastlane自己的发版,大大下降了灵活性。

  • Plugin: Plugin就是在Action的基础上作了一层包装,这个包装巧妙的利用了RubyGems这个至关成熟的Ruby库管理系统,因此其能够独立于Fastlane主仓库进行查找,安装,发布和删除。

咱们甚至能够简单的认为:Plugin就是RubyGem封装的Action,咱们能够像管理RubyGems同样来管理Fastlane的Plugin。

安装 fastlane add_plugin [plugin_xxx] 安装完成后 会在fastlane文件夹下生成Pluginfile文件实际就是一个Gemfile文件,里面包含了对于Plugin的引用,格式以下:

# Autogenerated by fastlane
#
# Ensure this file is checked in to source control!
# fastlane-plugin-version_from_last_tag 是插件名字
gem 'fastlane-plugin-version_from_last_tag'
复制代码

使用 和Action使用同样。

  • 发布Plugin 1 能够做为Gem发布到RubyGems上,这样就能够经过fastlane search_plugins xxx 查找,安装。

2 能够到Github / GitLab上 或者 引用本地路径。

gem "fastlane-plugin-version_from_last_tag", git: "https://github.com/jeeftor/fastlane-plugin-version_from_last_tag"
复制代码

发布以前,为了本地调试方便,能够将gem指向本地,在Pluginfile这样声明:

gem "fastlane-plugin-version_from_last_tag", path: "../fastlane-plugin-version_from_last_tag"
复制代码

1. Fastlane不仅是移动端

  • 测试方面: 1 UI自动化测试Action: appium ,如下是appium全部参数 fastlane action appium
    401851C4-6DE4-46EC-862E-CEBAB69F1886.png

2 Android Monkey 下面咱们看看Android通常运行Monkey测试的步骤:

Git Pull拉最新的代码 执行./gradlew clean命令清理环境 执行./gradlew assembleTest打包测试版本 执行命令安装最新的测试版本: adb shell monkey -p com.wanmeizhensuo.zhensuo -c android.intent.category.LAUNCHER 1

每次调用命令: fastlane do_monkey_test times:3 project:GengmeiAndroid apk_path:./GengmeiAndroid_test.apk ... Fastlane文件配置以下:

desc "Android monkey test"
lane :do_monkey_test do |options|
    times        = options[:times]
    project      = options[:project]
    apk_path     = options[:apk_path]
    package_name = options[:package_name]
    
    hipchat(message: "Start monkey test on #{project}")
    
    git_pull
    gradle(task: "clean")
    gradle(task: "assembleGmtest")
    (1..times.to_i).each do |i|
      adb(command: "install -r #{apk_path}")
      adb(command: "shell monkey -p #{package_name} -c android.intent.category.LAUNCHER 1")
      # 等待30秒,确保闪屏页被Finish后,进入到主页.
      sleep(30)
      android_monkey(package_name: "#{package_name}", count: '1000', seed: "#{10+i}")
    end
    
    hipchat(message: "Execute monkey test on project #{project} successfully")
end
复制代码

自定义的Action android_monkey 封装了 Android Monkey adb

  • 理论上全部频繁使用shell操做的,均可以利用fastlane整合,自动化处理。 Fastlane还有如下这些集成好的Actions: ssh scp cli-table cli args parser

更多Actions和Plugins查阅官网 Actions - fastlane docs Plugins - fastlane docs

2. 高级用法

  1. 前置方法 多个lane是可能包含不少共同的方法,fastlane给出的方案:
before_all do |lane, options|
  #git_pull
  #cocoapods
end
复制代码
  1. 后置方法 全部lane执行完时,可能都会有通知逻辑:
after_all do |lane,options|
    slack(message: "fastlane was successful", success: true)
end
复制代码
  1. error处理,每一个lane执行时可能都会遇到错误,这个时候都应该有消息通知到你们。error就是一个全局错误处理方法:
error do |lane, exception|
  slack(message: exception.message, success: false)
end
复制代码
  1. 引用机制 远程引用 import_from_git import_from_git - fastlane docs每次执行fastlane的命令时,首先会从git上将须要的文件clone这个项目到本地的临时文件夹中,而后再执行相关命令。若是某个项目中,你不想使用远端上的某个lane,可在项目中的Fastfile中复写这个lane便可。

  2. 更多高级用法查看文档 Advanced - fastlane docs

0. Fastlane - iOS 和 Android 自动化构建工具 Fastlane实战(一):移动开发自动化之道 - 简书 Fastlane实战(二):Action和Plugin机制 - 简书 Fastlane实战(三):Android平台上的应用 - 简书

Tips

  1. fastlane install命令在bundle update 卡住,gem ruby 源有问题,这里建议添加国内源。

  2. ruby镜像 https://gems.ruby-china.org https://ruby.taobao.org/

替换命令:

$ gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/
$ gem sources -l
*** CURRENT SOURCES ***

https://gems.ruby-china.org
# 请确保只有 gems.ruby-china.org
$ gem install rails
复制代码
  1. 远程SSH到打包机执行打包 报错:code sign 问题致使 unknown error -1=ffffffffffffffff iOS远程自动打包问题 - 简书

相关文章
相关标签/搜索