ZHANGYU.dev

October 14, 2023

fastlane自动化打包React Native笔记

Others3.9 min to read

fastlane

fastlane是使用Ruby写的一套自动化打包IOS和Android应用的工具,提供了很多插件化操作,包括证书管理,上传商店。

由于它只是一套自动化打包工具,所以想要部署还是需要使用Github Actions这种CI平台的。

需要提前需要安装好ruby环境,macOS自带ruby,如果没有,可以使用rbenv来管理。

安装fastlane

setup

xcode-select --install

安装

brew install fastlane

初始化fastlane

项目根目录执行

fastlane init

项目下会创建fastlane文件夹和Gemfile文件

├── Gemfile└── fastlane    ├── Appfile    └── Fastfile

Appfile是存一些fastlane的变量文件,不过我没有使用这个文件,大部分的值是通过环境变量来拿的。

Fastfile则是主要的执行文件了,里面定一些所谓lane的执行命令。

证书管理

证书管理这一块浪费了我很多时间,可算整好了。

IOS

IOS的证书一直都很麻烦,分为development和上架需要的distribution证书。使用fastlane的match就可以很轻松的管理证书,甚至开发人员根本不需要登陆Xcode的开发者账号,如果有新成员执行一下命令就能安好证书了。

match可以将证书存放在一个私有的git仓库中,然后开发者只需要执行命令,就可以将证书安装到本地了,这样共用同一个证书,避免申请多个证书。

同时它推荐创建一个新的开发者账号作为公用账号,并申请一个App Store Connect API

截屏2021-11-05 下午9.01.34

首先使用新的开发者账号来配置match,输入一个私有的git仓库地址用来存放证书。

fastlane match init

现在会增加一个Matchfile在fastlane文件夹,里面则是match的配置。

如果你想将证书放在不同的分支,可以在Matchfile文件中加上你自定义的分支名称

git_branch("fastlane_certificates")

还需要申请一个Github Token,用于后续的仓库访问。

将Token转为base64。

echo -n your_github_username:your_personal_access_token | base64

写入Matchfile文件

git_basic_authorization("xxxxxxxxx")

app identifier写入Matchfile,如果有多个,可以写为一个数组。

app_identifier("com.xxx.xxx")

如果想要撤销掉之前发放的所有证书,可以执行

fastlane match nuke developmentfastlane match nuke distribution

创建新证书

执行过程中会输入Apple ID,同时会设定一个访问密码。

fastlane match appstore
fastlane match development

速度会有一些慢,建议代理加速,执行完后看Github仓库里会有对应的证书文件。

增加Matchfile的配置

clone_branch_directly(true)shallow_clone(true) // 加速clonereadonly(true) // 不会生成新证书

之前有说申请一个App Store Connect API,现在将它配置上。

fastlane目录下创建一个api-key.json文件

{  "key_id": "xxx",  "issuer_id": "xxx",  "key_content": "-----BEGIN PRIVATE KEY-----\nxxxxxxx\n-----END PRIVATE KEY-----"}

增加Matchfile配置

api_key_path("fastlane/api-key.json")	

Android

Android证书比较简单,但是没有提供插件来处理,我的方法是将证书转为base64,在CI过程中把它转完文件写入。

转base64

base64 -i xxx.keystore > key

自动化打包

IOS

fastlane ios deploy

platform :ios do  lane :deploy do    # React Native对应项目的配置和名称    XCODE_PROJECT = './ios/rnapp.xcodeproj'    XCODE_WORKSPACE = './ios/rnapp.xcworkspace'    PLIST_PATH = "./rnapp/Info.plist"    SCHEME = 'rnapp'    setup_ci        if is_ci      unlock_keychain(      	path: "fastlane_tmp_keychain",      	password: "",      	set_default: true    	)    end    increment_build_number(xcodeproj: XCODE_PROJECT)    match(type: "appstore")    # 需要先关闭自动签名    update_code_signing_settings(      use_automatic_signing: false,      path: XCODE_PROJECT    )    build_ios_app(      workspace: XCODE_WORKSPACE,      scheme: SCHEME,      clean: true,      export_method: "app-store"    )    update_code_signing_settings(      use_automatic_signing: true,      path: XCODE_PROJECT    )    upload_to_testflight  endend

安装证书到新开发的机器

fastlane certificates

lane :certificates do  match(    type: "development",    force_for_new_devices: true,    readonly: true  )  match(    type: "appstore",    readonly: true  )end

Android

fastlane android deploy

require 'base64'platform :android do	lane :deploy do |options|	  setup_ci          puts "env file path: #{ENV['ENVFILE']}"		      # 把之前base64的Android证书写入          if !ENV["ANDROID_KEY_STORE"].empty?            File.open("../android/app/rnapp-release-key.keystore", 'wb') do |file|              file.write(Base64.decode64(ENV["ANDROID_KEY_STORE"]))            end          end          gradle(task: 'clean', project_dir: 'android/')                gradle(task: 'app:assemble',  build_type: 'Release', project_dir: 'android/')	endend

关于环境变量问题

如果使用了react-native-config这样的包来管理环境变量,就需要额外的配置了。

require 'dotenv'projectPath = File.join(Dir.pwd,"..")before_all do |lane, options|  filePath = "../.env.#{options[:env]}"  Dotenv.load filePath  ENV["ENVFILE"] = filePathend# Android读不到相对路径,不知道为什么platform :android do	...  ENV["ENVFILE"] = File.join(projectPath, ".env.#{options[:env]}")	...end

执行命令

fastlane ios deploy env:dev	

就能够读取.env.dev这个环境


废了老大时间来做这个不属于前端的活路,真是累死我了,简单做个笔记,再也不想整这个了。