fastlane自动化打包React Native笔记

1,212 阅读4分钟

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.png

首先使用新的开发者账号来配置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 development
fastlane 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
  end
end

安装证书到新开发的机器

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/')
  end
end

关于环境变量问题

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

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

执行命令

fastlane ios deploy env:dev 

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


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

还有最近做了半年React Native,人有点傻了,CSS的知识都忘了不少,感觉这样拧螺丝拧下去吃枣要废,幸好React Router出了v6,明日开始读源码。

我越来越觉得我就是个看点源码,不怎么懂业务的代码白痴了,生活没啥动力,好久都没分享文章了。