OC底层原理43.3:自动化打包(三)Fastlane
前言
除了Jenkins可以自动打包,还有另一个方式:Fastlane,下面来了解下。
Fastlane 是一个完全开源的项目,是一款为iOS和Android开发者提供的自动化构建工具。它可以帮助开发者将 App打包、签名、测试、发布等
流程串联起来,实现完全自动化的工作流。其官网地址为:https://fastlane.tools/
Fastlane安装
参考 配置文档 ,安装步骤如下:
- 检查ruby版本,需要2.0及以上,并且将gem的source改为
gems.ruby-china.com/
1 | // 查看 Ruby 版本 |
- 检查Xcode命令行工具是否安装,如果没有安装则会自动开始安装
1 | xcode-select --install |
- 安装Fastlane
1 | sudo gem install fastlane --verbose |
Fastlane相关block、lanes、actions
在完善打包逻辑之前,首先介绍Fastlane中提供的常用的 blocks、lanes和actions
blocks:fastlane中除了lane的其他模块
lanes:Lanes的相关用法介绍
actions:fastlane内置好的常用操作
Blocks
block主要分为三类:
before_all & before_each
after_all & after_each
error
before_all & before_each
1 | 其中before_all会先于before_each执行,且仅执行一次, |
- before_all:在lane执行前执行一次
1 | before_all do |lane| |
- before_each:会在任意lane执行前执行,与before_all只执行一次不同,如果在一个 lane 中多次调用了其他的 lane,则其他的 lane 执行前都会执行 before_each。
1 | before_each do |lane, options| |
after_all & after_each
1 | after_all 会在 after_each 执行完后执行,且仅执行一次。 |
- after_all:会在lane执行完后执行一次
1 | after_all do |lane| |
- after_each:会在任意lane执行完后执行,如果在一个lane中多次调用了其他的lane,则其他的lane执行完后都会执行after_each
1 | after_each do |lane, options| |
例如下面的例子,before_each将after_each被调用 4 次
- before_each:调用deploy之前、切换到archive之前、切换到sign之前、切换到upload之前
- after_each:执行deploy之后、切换到archive执行之后、切换到sign执行之后、切换到upload执行之后
1 | before_each do |lane, options| |
error
在任何流程中发生错误时,都会退出并执行error,错误后的after_all和after_each将不会执行
1 | error do |lane, exception| |
Actions
一个命名的lane代表一个持续集成的任务,每个任务由多个步骤组成,步骤组成是已经定义好的 action 工具。在终端可以通过 fastlane action actionName
查看某个具体的 action
,也可以通过 fastlane action
查看fastlane中定义好的action及说明。
除了使用ruby代码在lane中实现的各种功能,fastlane也内置了许多写好的独立方法库即action,每一个action都是一个独立Ruby脚本,是fastlane的最小执行单位,下面介绍几个常用的action
1、cocoapods:执行pod install
2、gym:项目编译、打包等
3、increment_build_number:build号自增
4、match:管理证书和配置文件
5、app_store_connect_api_key:为其他 action 生成 App Store Connect API token
1、cocoapods
调用cocoapods action会执行pod install,如果工程中使用了cocoapods管理三方库,需要在Gemfile中添加以下命令
1 | gem "cocoapods" |
在lane中使用直接调用即可
1 | lane :debug do |
2、gym
gym 是fastlane提供的用于构建、打包的action,是build_app的别名。可以根据配置参数编译iOS应用,并生成ipa包。以下是常用的参数
workspace:workspace 文件路径,使用
cocoapods
后需要使用project:project 文件路径,若有
workspace
此项可忽略scheme: schema名
clean:是否在编译前清理工程
configuration:编译环境设置,Relese、Debug、自定义
export_method:包输出类型,app-store、ad-hoc、package、enterprise、development
archive_path : 读取xarchive的路径
output_directory:ipa包输出路径
output_name:ipa包名称
include_symbols:是否集成调试符号,若为 false 则会单独生成符号文件
include_bitcode: 是否开启bitcode
其他参数如下:
export_options: 可以指定更详细的打包配置,可以是配置文件路径
skip_build_archive: 跳过构建,打包阶段,直接签名;使用archive_path 作为输入
skip_archive:仅构建
skip_codesigning: 仅构建,打包,不签名
以下是CI中具体的例子
1 | lane :release do |
3、increment_build_number
- 通过app_store_build_number获取最新版本的build_number
1 | currentBuildNumber = app_store_build_number( |
- 通过increment_build_number设置项目的build_number
1 | increment_build_number( |
4、match
match主要用于证书和配置文件的管理,用于开发成员之间共享,具体的过程可参考代码签名指南
match配置步骤:
在gitLab上创建一个仓库用于保存证书
在项目根目录下执行 fastlane match init,输入仓库的git地址,会在fastlane目录下生成Matchfile文件,包含match的配置信息
match参数说明:
type: 同步的配置文件类型: appstore,adhoc,development,enterprise,默认 development
readonly: 默认false,如果是true,不会生成新的证书和描述配置文件
app_identifier: 指定描述配置文件的bundle id;如果不指定则使用 AppFile 中的 app_identifier
git_url: 证书保存的git地址
keychain_name : 保存证书的keychain,默认login.keychain
以下是在CI中使用match的例子
1 | # match 中需要配置参数 |
match说明:
执行这些命令fastlane match development, fastlane match adhoc, fastlane match enterprise,fastlane match appstore,首次执行自动在apple store connect中创建provisioning file,证书并下载加密保存在git仓库,并上传.
其他开发者就可以使用fastlane match命令共享github中的证书和配置文件。
5、App Store Connect API
在早先访问App Store Connect信息时需要双因素认证。而在持续集成的过程中一般无法人机交互(例如github-action),会导致持续集成无法完成。在WWDC18中,苹果提出了App Store Connect API,提供另外的认证方式。Fastlane也对App Store Connect API提供了支持,具体查看 Using App Store Connect API 文档
Using App Store Connect API是一个官方公共API,用于管理应用元数据、定价、配置等。但是在使用之前,需要获取AppStore Connect的访问权限,即获取issuer ID和apiKey。
app_store_connect_api_key 是用来为其他 action 生成 App Store Connect API token 的 action; match,pilot以及 deliver等 action 都可以使用 App Store Connect API token,有如下参数:
key_id:密钥ID,需要在AppStore Connect -> 用户和访问 -> 密钥中创建并获取
issuer_id:标识创建认证令牌的发放者。也是在AppStore Connect -> 用户和访问 -> 密钥中获取
key_filePath: p8文件的路径
key_content: p8文件的内容,未编码直接提供需要将回车替换为\n
is_key_content_base64: 是否key的内容经过base64编码
in_house: 是app store还是 enterprise
以下是在CI中的使用例子
1 | lane :release do |
Lanes
lanes的使用方式请参考文档,可以分为以下几种:
命令行参数传递
lane之间的调用
返回值
如何停止执行中的lane
lane的上下文通信
如果访问lane的属性
私有lane
如何配置多个lane的环境变量
命令行参数传递
1、传递:如果需要将参数从命令行传递到lane,语法如下
1 | //格式 |
2、使用:在lanes中接收传入的值,是通过options实现的,格式为:options[:参数名]
1 | lane :deploy do |options| |
lane之间的调用
lane之间的调用,有点类似于函数的调用,通过lane的名字来调用
1 | lane :deploy do |options| |
返回值
除此之外,lane还可以检索返回值,在Ruby中,lane定义的最后一行是返回值,在其他lane中通过options进行使用
1 | lane :deploy do |options| |
如何停止执行中的lane
在lane中可以通过next关键字来停止执行中的lane,如下所示
1 | lane :build do |options| |
当next作用在切换lane时,会控制流程返回到前lane正在执行的位置,即当前lane的next以后的代码将不会执行
1 | lane :first_lane do |options| |
lane的上下文通信
lane的上下文通信,简单来说就是如何在不同的action间通信。不同的action可以通过分享哈希来进行通信,如下所示
1 | lane_context[SharedValues::VARIABLE_NAME_HERE] |
如果访问lane的属性
我们也可以通过lane_context动态访问当前lane的属性,如下所示
1 | lane_context[SharedValues::PLATFORM_NAME] # Platform name, e.g. `:ios`, `:android` or empty (for root level lanes) |
同时这些属性也可用作.env文件的环境变量
1 | ENV["FASTLANE_PLATFORM_NAME"] |
私有lane
当我们有不同lane调用同一个lane时,可以将这个lane定义为私有的lane,防止在外部通过fastlane laneName进行调用,如下所示,我们不能通过fastlane build来访问私有的lane
1 | lane :production do |
如何配置多个lane的环境变量
通常Appfile只会使用配置项的第一个值,如下所示,app_identifier配置了两个值,我们一般只会取第一个com.used.id,而com.ignored.id将被忽略。
1 | app_identifier "com.used.id" |
为了避免以上情况,fastlane提供了for_lane和for_platform来解决多个配置的情况,所有的配置文件中都可使用
- for_lane:当调用的lane和指定的lane名称匹配时,会调用对应的block
1 | locales ['en-US', 'fr-FR', 'ja-JP'] |
- for_platform:根据当前的platform决定执行的block
1
2
3
4
5
6
7
8
9
10
11
12
13
14app_identifier "com.default.id"
for_lane :enterprise do
app_identifier "com.forlane.enterprise"
end
for_platform :mac do
app_identifier "com.forplatform.mac"
for_lane :release do
app_identifier "com.forplatform.mac.forlane.release"
end
end
Fastlane配置
Fastlane的配置主要分为三步:
- fastlane初始化
- 创建.env配置全局变量,并修改Appfile
- fastfile完善打包逻辑
【第一步】fastlane的初始化配置
主要执行以下命令
1 | cd [项目根目录,xcodeproj的同级目录] |
init操作主要完成以下操作:
1、会要求输入开发者账户和密码,会存储在钥匙串中,后续使用无需再输入密码
2、会检测当前项目的App Identifier是否已经存在Developer中
3、会检测App是否已经在AppStore Connect中,如果都满足,过程是比较顺利的
4、会在项目工程的目录下生成一个fastlane文件夹,里面是Fastlane的一些配置文件。fastlane可以通过配置Appfile、Deliverfile、Fastfile 来完成各种工作。
下面分别介绍下fastlane文件夹中常用的文件:
Appfile :存放 App 的基本信息包括 App_Identifier 、AppID 、Team_ID 等。这个文件的参数是已经定义好的,新增并没有用
Fastfile :最核心的用来控制流程走向的配置文件,是最重要的一个文件,在这个文件里面可以编写和定制我们打包脚本的一个文件,所有自定义的功能都写在这里
Deliverfile :可用于配置提交AppStore Connect的一些参数。(注:这个文件只有在选择由fastlane管理metadata为YES时,才会生成,如下所示)
- .env或.env.default:为了更灵活的使用Appfile的内容,可以使用.env文件来进行环境配置,新增其他的变量在fastfile中使用
除此之外,还需要关注fastlane同级的Gemfile和Gemfile.lock文件:
Gemfile:私用bundler来安装和引入该App所需的gem,类似于cocoapods中的podfile
Gemfile.lock:gem的版本控制文件,类似于cocoapods的podfile.lock文件
【第二步】创建.env配置全局变量,并修改Appfile
注:因为是.env文件是.开头文件,默认是在finder中隐藏的,可以通过快捷键来显示隐藏文件:CMD + Shift + .
为了更加灵活的使用Appfile的内容,可以引入.env文件来进行环境配置,具体的请参考
.env环境配置 文档。这样在执行命令时,可以在气候加上环境变量,以达到使用不同配置的目的。
其命名规则为:.env.
- 在命令中如下使用
1 | fastlane <lane-name> --env development |
- Appfile中使用.env,直接读取变量即可
1 | //.env内容 |
【第三步】Fastfile完善打包逻辑
编辑fastlane的逻辑可参考fastlane自动部署iOS AppStore文档,构建步骤如下:
更新pod,清理缓存
版本号修改
编译并打包
上传AppStore
以下是具体的编译、打包代码:
1 | # 因为fastlane存在新老版本兼容问题,所以一般会指定fastlane版本 |
到此,fastlane就配置完成了
Fastlane使用
跳转到项目的根目录:cd [项目根目录]
自动打包并上传到AppStore Connect,在终端执行lane:fastlane lanename
除了可以在本地终端执行,还可以在Jenkins构建打包服务,具体步骤参考文档:Jenkins集成fastlane
最终,Fastlane整体流程汇总如下
iOS中打包方式汇总如下:
- Post title:OC底层原理43.3:自动化打包(三)Fastlane
- Post author:张建
- Create time:2023-05-09 16:06:17
- Post link:https://redefine.ohevan.com/2023/05/09/OC底层原理/OC底层原理43.3:自动化打包(三)Fastlane/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.