React Native 技术详解 (十) - APP打包和热更新自动化

React Native 技术详解 (十) - APP打包和热更新自动化

Posted by SkioFox on July 30, 2022

背景

为了提高APP开发过程的整体效率,摆脱开发人员手动依赖,因此需要搭建一套能支持APP自动打包构建和热更新推送的可视化工具,简化打包和热更新过程,并实现打包以及热更新的自动化。

整体要功能实现需分为以下三步:

  • 打包和热更新自动化平台搭建
  • 私有化App的打包
  • IOS和Android端的打包自动化

打包和热更新自动化平台搭建

前面我们已经详细讲过code-push更新的接入, 这里我们主要需要实现打包的平台化。

1.平台搭建

由于IOS端打包需要强依赖MacOS,因此我们选择一台macOS作为打包服务器。打包过程比较复杂,对原生ios/android环境依赖性比较强,本地需要完成比较复杂的配置。 参考打包方案设计:来访多APP构建打包方案(IOS+Android) 热更新:热更新推送是基于code-push,只需通过命令行手动触发,相对比较简单。

通过调研Jenkins工具,可以很好实现在本机上实现界面化的CI/CD管理,通过配置脚本任务准确执行打包和热更新过程,基本流程如下:

alt text

方案核心逻辑:

  1. 利用mac电脑作为服务器搭建RN的ios/android打包环境;
  2. ios利用xcode和fastlane工具、android利用gradle完成打包过程;
  3. 利用jenkins配置流水线和脚本任务;
  4. jenkins脚本触发来访app自定义脚本完成打包和热更新推送;
  5. 利用jenkins插件分发ipa或者apk文件上传蒲公英/生成安装二维码(二期优化);

安装并配置Jenkins

1. 准备前提:mac上安装homebrew和java jdk1.8,可通过查看版本验证是否安装成功

2.推荐使用brew安装Jenkins便于后期管理

brew install Jenkins

注意:安装过程可能会遇到网络问题(配置代理解决)或者brew更新问题(取决于brew版本和mac电脑google解决)

安装成功提示

brew services start jenkins

3.启动并在浏览器直接打开http://localhost:8080/,按照推荐初始化jenkins并创建管理员账号进入主页。

4. 设置jenkins全局变量(如需要配置开启自启动和更改端口)

// 查看mac服务器环境变量
echo $path

进入jenkins=>系统管理-系统配置-全局属性-环境变量

5.创建流水线任务(来访登记APP—打包(同步公有云版本)例)

新建Jenkins任务

进行参数化配置

配置shell脚本(执行打包的配置)

6. 核心脚本实现

/**
 * app热更新
 * 1. 重置本地代码状态并拉取最新代码
 * 2. 更新js依赖
 * 3. 选择热更新app
 * 4. 选择热更新环境
 * 4. 更新内容描述
 * 5. 执行热更新
 */
 const { promiseSpawn, codepushUpdateMap, judgeHotUpdateArgs } = require('./utils');

 const argv = process.argv.splice(2);
 const appType = argv[0];
 const appPlatform = argv[1];
 const appEnv = argv[2];
 const desc = argv[3] || `版本功能更新`;

const run = async() => {
  if(judgeHotUpdateArgs(argv)) {
    try {
      const cmd = `${codepushUpdateMap[appType][appPlatform][appEnv]} ${desc}`

      console.log(`热更新命令:${cmd}`)

      const resBuild = await promiseSpawn(cmd)
      if(resBuild) {
        console.log(`热更新成功${appType}-${appPlatform}-${appEnv}`)
      }
      console.log(`热更新命令:${cmd}`)
    } catch (err) {
      console.log(`热更新失败${err}`)
    }
  }
}

run();
/**
 * app打包
 * 1. 重置本地代码状态并拉取最新代码
 * 2. 更新js依赖
 * 3. 指定APP(比如yunke、jindi、aoyuan...)
 * 4. 更新域名
 * 5. 选择app打包类型(ios/android)
 * 6. 选择app打包环境(test/prod)
 * 7. 安装更新原生依赖库(ios需要)
 * 8. 执行打包
 */
const { judgeArgs, promiseSpawn, buildAppCmdMap } = require('./utils');

const argv = process.argv.splice(2);
const appType = argv[0];
const appPlatform = argv[1];
const appEnv = argv[2];

const run = async() => {
  if(judgeArgs(argv)) {
    try {
      const resBuild = await promiseSpawn(buildAppCmdMap[appType][appPlatform][appEnv])
      if(resBuild) {
        console.log(`app打包成功${appType}-${appPlatform}-${appEnv}`)
        console.log(`app打包命令:${buildAppCmdMap[appType][appPlatform][appEnv]}`)
        let appStorageDir = ''
        const outputsDir = `/Users/Shared/msdj-app/${appPlatform}`
        if(appPlatform === 'ios') {
          appStorageDir = `./ios/fastlane/build/${appType}`
        }else {
          appStorageDir=`./android/app/build/outputs/apk/${appType}`
        }
        try {
          const copy = await promiseSpawn(`cp -rf ${appStorageDir} ${outputsDir}`)
          if(copy) {
            console.log(`app存储目录如下:${outputsDir}/${appType}`)
          }
        } catch (err) {
          console.log(`app文件copy失败${err}`)
        }
      }
    } catch (err) {
      console.log(`app打包失败${err}`)
    }
  }
}

run();

这里只列举了核心逻辑,ios和android打包的前置工作以及code-push接入需要你提前完成。

最终效果如下:

实现了打包和热更新的自动化和平台化。

参考文档:

https://www.jenkins.io/zh/doc/pipeline/tour/getting-started/

https://juejin.cn/post/6931966634907320333

https://juejin.cn/post/7045512176139763743

https://www.jenkins.io/download/lts/macos/

https://stackoverflow.com/questions/64520921/how-to-change-default-port-for-brew-installed-jenkins-in-macos

https://blog.csdn.net/wbk0905/article/details/127057266

https://www.jianshu.com/p/15c4941f8ae9