React native 持续集成实践

在React Native项目开发中,我们使用CircleCI + Fastlane搭建了一套持续集成的环境,来自动完成CI CD。

基本需求

  • 每次push代码,CI可以自动跑测试,并在线查看测试覆盖率
  • 自动打包ios app,发布到TestFlight
  • 自动打包android app,发布到Crashlytics

React native 持续集成实践

使用到的工具

React native 持续集成实践

使用CircleCI搭建持续集成环境

设置基本环境

由于需要打包ios app,而ios app打包要求系统必须是macOS,所以需要选择CircleCI为macOS plan。并且在CircleCI设置的Build Enviroment里开启Build macOS project选项。

React native 持续集成实践

首先,在项目根目录上创建circle.yml文件(当时只有CircleCI 1的版本支持macOS plan),设置xcode版本,直接指定所需版本即可,我们项目中当时使用的xcode版本为8.3.3。

machine:
  enviroment:
    xcode:
      version: 8.3.3

安装依赖

我们可以先查看一下当前macOS环境中已经安装了哪些软件(macOS -
xcode 8.3.3)。可以看出当前macOS环境没有nvm,不能直接设置node的版本,所以我们需要手动安装nvm,并安装所需版本的node。由于项目中使用的包管理工具是yarn,所以也需要安装yarn。

dependencies:
  pre:
    # 安装nvm
    - curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
    # 安装所需node版本,我们项目中使用的是8.9.1
    - nvm install 8.9.1
    # 全局安装yarn
    - npm install yarn --global
  override:
    # 安装项目所需依赖
    - yarn install
  cache_directories:
    # 缓存依赖节省后续build的时间
    - ~/.cache/yarn
    - node_modules

自动运行测试

test:
  pre:
    - yarn lint
  override:
    - yarn test
  post:
    # 保存测试覆盖率文件夹,用于在线查看
    - mkdir $CIRCLE_ARTIFACTS/coverage
    - mv coverage/* $CIRCLE_ARTIFACTS/coverage

在运行测试之前,我们要先运行lint来检查代码格式是否符合规范。yarn test用来运行测试。在测试运行完之后,要将测试覆盖率的文件夹保存在CircleCI上,用于在线查看测试报告。
在每次build之前,CircleCI会创建一个空白文件夹,并导出一个只读环境变量$CIRCLE_ARTIFACTS。在build结束之后,在这个文件夹里的内容会被保存下来,并链接到这个build。

React native 持续集成实践

CircleCI在每个阶段都有默认的执行命令,我们可以使用下面三个特殊键来指定何时运行哪些自定义的命令:

  • pre: 在该阶段命令前运行
  • override: 自定义该阶段的命令
  • post: 在该阶段命令后运行

使用fastlane自动进行IOS APP beta deplopment

fastlane是为iOS和Android app自动化测试部署和发布的最简单方法。 它可以处理所有繁琐的任务,如生成屏幕截图、管理code signing以及发布app。
fastlane提供了一系列的工具来处理这些工作,每一个工具用来处理一项工作,可以根据项目来进行组合。如:gym用来打包app。

React native 持续集成实践
对于iOS app,会发布到TestFlight。

安装fastlane

确保已经安装最新的xcode命令行工具:

xcode-select --install

在macOS上使用brew安装fastlane

brew cast install fastlane

在系统的shell profile文件(如:~/.bash_profile)中设置环境变量:

export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8

在本机上安装好fastlane之后,接下来我们可以set up fastlane。

Set up fastlane

在React Native项目根目录下运行下面的命令:

cd ios
fastlane init

上面的命令运行完之后,会生成下图中的目录。

Appfile:该文件存储apple_id、app_identifier信息,一般不用修改
Fastfile:该文件包含所有用于发布app的信息

React native 持续集成实践

iOS beta deployment

打包 iOS App
fastlane使用gym acttion打包iOS App,将下面代码添加到fastfile文件中:

lane :beta do
  gym(scheme: "MyApp")
end

运行这个lane:

fastlane ios beta

如果运行成功,会得到一个.ipa的文件。但通常我们会遇到一些问题。

配置xcode

设置bundle identifier同AppFile里的app_identifier
设置Signing - 不选中“Automatically manage signing”,使用手动的方式管理code signing。
设置Signing(Release)为release所用的code signing,我们这里没有使用fastlane的match来进行管理,而是使用手动管理的方式。

React native 持续集成实践

上传到TestFlight

lane :beta do
  # 每次build,先从TestFlight取得最新的build number, 再加1
  increment_build_number(
    build_number: latest_testflight_build_number + 1,
    xcodeproj: "MyApp.xcodeproj"
  )
  # 打包 app
  gym(scheme: "MyApp")
  # 上传至TestFlight
  pilot(skip_waiting_for_build_processing: true)
end

至此,我们完成了fastlane iOS beta deployment在本地的配置,已经能够正常打包

fastlane进行android app beta deployment

在打包iOS app的时候,我们需要code signing,而android则需要google json key,以及签名密钥。

生成 release APK

生成签名密钥

可以使用keytool命令行工具直接生成一个私有的签名密钥:

keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000

这条命令会要求你输入密钥库(keystore)和对应密钥的密码,然后设置一些与发行相关的信息。最后会生成一个叫做my-release-key.keystore的密钥库文件,密钥的有效期为10000天(特别注意:密钥的有效期一旦设定,后期无法修改)。

设置gradle变量

将my-release-key.keystore文件,放在项目的android/app目录下;
修改~/.gradle/gradle.properties 或 android/app/gradle.properties(我们项目修改的是这个)文件,添加下面几句(将*替换为自己实际设置的密码):

MYAPP_RELEASE_STORE_FILE=my-release-key.keystore
MYAPP_RELEASE_KEY_ALIAS=my-key-alias
MYAPP_RELEASE_STORE_PASSWORD=*****
MYAPP_RELEASE_KEY_PASSWORD=*****

添加签名到项目的gradle配置文件
修改项目中的android/app/build.gradle文件并添加签名配置:

android {
    ...
    defaultConfig { ... }
    signingConfigs {
        release {
            if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
                storeFile file(MYAPP_RELEASE_STORE_FILE)
                storePassword MYAPP_RELEASE_STORE_PASSWORD
                keyAlias MYAPP_RELEASE_KEY_ALIAS
                keyPassword MYAPP_RELEASE_KEY_PASSWORD
            }
        }
    }
    buildTypes {
        release {
            ...
            signingConfig signingConfigs.release
        }
    }
}

生成 release APK

cd android && ./gradlew assembleRelease

只需运行上面的命令,就可以生成android release APK。生成的APK可以在
android/app/build/outputs/apk/app-release.apk路径找到。
做完上面的这些,我们就可以来配置fastlane来自动打包android apk并beta deploy到Crashlytics.

Set up fastlane

在React Native项目根目录下运行下面的命令:

cd android
fastlane init

运行fastlane init时,会要求输入google service json文件,可以先不填,后续取得json文件之后更新到android/fastlane/Appfile文件里(参考:collect your google credentials)。
上面的命令运行完之后,会在android目录下生成fastlane文件夹,里面主要有下面两个文件:

Appfile:该文件存储json_key_file(该字段用来设置上面说到的google service json文件目录)、package_name信息
Fastfile:该文件包含所有用于发布app的信息

android beta deployment

由于我们选择将android app beta deploy到crashlytics,所以需要先给项目配置crashlytics。

  • 首先到Fabric官网申请帐号并登录,会提示需要到android studio安装fabric插件。
  • 按提示在android studio上安装好fabric插件之后,点击fabric图标,会出现如下图所示界面

React native 持续集成实践

  • 在fabric界面登录之后,一直向下选择,直到出现如下界面,先择Crashlytics,按提示进行配置即可(初次配置可能要等好几分钟)

React native 持续集成实践

配置 beta lane

lane :beta do
  # 打包android app
  gradle(
    task: "assembleRelease",
  )

上传android app至crashlytics

crashlytics(api_token: "YOUR_FABRIC_CRASHLYTICS_API_TOKEN",
              build_secret: "YOUR_FABRIC_CRASHLYTICS_BUILD_SECRET")
end

上面crashlytics的api_token以及build_secret可以在fabric origanizations里找到。

React native 持续集成实践

运行下面的命令,即可打包android app并发布到crashlytics。
cd android && fastlane android beta

在Fabric Crashlytics上查看你的app

React native 持续集成实践

相关推荐