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。
首先使用新的开发者账号来配置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
这个环境
废了老大时间来做这个不属于前端的活路,真是累死我了,简单做个笔记,再也不想整这个了。