撸一套持续化集成-实现RN的差分更新

目录

  • 一、搭建Jenkins环境
    • 1. 下载Jenkins镜像
    • 2. 开启Jenkins服务
    • 3. Docker填坑
    • 4. Jenkins填坑
  • 二、RN的Jenkins打包脚本
    • 1. Jenkinsfile文件
    • 2. diff.sh文件及实现逻辑
  • 三、差分更新Bundle流程
    • 1. 差分填坑
    • 2. 如何使用Google-diff-match-patch
  • 四、开源代码
    • 服务端
    • RN端

前言

在真正开始接触持续化集成之前,始终有一种可望不可即的感觉,但就在某一天就突然想跟他较较劲,于是就自己搞了一套。为了纪念跟他相爱相杀的那段时间,就做下记录吧

一、搭建Jenkins环境

1. 下载Jenkins镜像

在你本地或者服务器执行docker pull jenkins/jenkins下载jenkins镜像
Jenkins/jenkins版本的镜像自带长期稳定版本的jenkins,强烈推荐此版本

2. 开启Jenkins服务

执行docker run -it -d -p 80:8080 -v /jenkins_home:/var/jenkins_home jenkins/jenkins

  • 在指定镜像中开启jenkins服务,并且穿透到宿主(执行docker命令的地方)
  • 80指的是穿透到宿主的端口,8080指的是镜像中实际开启的端口
  • /var/jenkins_home指的是镜像中jenkins服务所在的路径, /jenkins_home指的jenkins服务映射到宿主的服务路径,宿主的jenkins_home文件夹必须得手动创建

3. Docker填坑

  1. 如果要将Docker运行在服务器,CPU至少要2G。 我最初搞1G内存,在打Bundle过程中CPU直接飙到100%,整个服务被卡爆

  2. 我们可能会进入Docker镜像配置一些环境,配置完成以后要通过docker commit做保存,要不然容器重启以后所有的配置都会消失

  3. 启动镜像时要设置Jenkins在宿主环境的映射目录
    镜像每次重启都不会保存此次运行的数据,如果不在宿主环境设置映射目录,每次启动都会将Jenkins给初始化,之前Jenkins的配置都会消失,启动时设置映射目录后,每次对Jenkin的改动都会映射到宿主环境的映射目录,启动时也直接读取宿主环境中的jenkins服务,而不会重启初始化Jenkins服务

  4. 可能会用到的docker命令

     // 查看当前镜像
     docker images
     
     // 查看当前运行的容器
     docker ps 
     
     // 启动容器并指定穿透到本地的端口和目录
     docker run -it -d -p 80:8080  -v /app/jenkins_home:/var/jenkins_home wangliguang/jenkins
    
     // 登录Docker指定容器(-u 0代表使用root用户)
     docker exec -u 0 -it b06fae9dcf21 /bin/bash
    
     // 保存对容器的修改,后面跟的是容器id和镜像名
     docker commit cb439fb2c714 wangliguang/jenkins
    
     // 删除当前镜像
     docker rmi <镜像名字>
    
     //删除当前运行的容器, 后面加-f为强制删除
     docker rm <容器id>
    

4. Jenkins填坑

  1. 直接下载自带Jenkins服务的镜像,强烈建议使用jenkins/jenkins镜像,因为这个镜像集成的Jenkins是LTS(长期稳定版)版本,另外这个镜像自带两个用户,分别为root和jenkins,打包操作默认是在jenkins用户下,因此要注意权限问题
  2. 刚启动Jenkins服务时,会提示让你安装一些插件,此时一定要选择安装他们推荐的插件。千万不要跳过想着以后再安装,因为作为初学者你压根就不知道你需要什么插件,而且跳过以后,在也不会推荐你安装插件。
  3. 打包完成以后,需要通过scp命令将产物上传到自己的服务器,如果配置过ssh后还是一直失败,建议检查一下ssh配置的是root用户还是jenkins用户,默认打包脚本时在jenkins用户下操作的

二、RN的Jenkins打包脚本

1. Jenkinsfile文件

pipeline {
   agent any
   environment {
	  HOME = '.'
   }
   stages {
	  stage('build') {
	     steps {
	        sh 'yarn install'
	        sh 'rm -rf .cache/'
	        sh 'whoami'
	        sh 'node ./node_modules/react-native/local-cli/cli.js bundle --platform ios --dev false --entry-file index.js --bundle-output ./index.bundle'
	        sh 'chmod 744 ./diff.sh && ./diff.sh'
	     }
	  }
   }
}	

2. diff.sh文件及实现逻辑

#! /bin/bash

localNewFile='./index.bundle'
# 已时间戳为文件名
newName=`date +"%s".bundle`;
scp $localNewFile [email protected]:/app/s_phoenix/public/bundle/$newName
count=`ssh [email protected] "cd /app/s_phoenix/public/bundle && ls -l | grep "^-" | wc -l"`
if [  $count -gt 8 ]; then
   oldFile=`ssh [email protected] "cd /app/s_phoenix/public/bundle && ls -t * | tail -1"`
   echo $oldFile
   ssh [email protected] "rm /app/s_phoenix/public/bundle/${oldFile}" 
fi

撸一套持续化集成-实现RN的差分更新_第1张图片

三、差分更新Bundle流程

撸一套持续化集成-实现RN的差分更新_第2张图片

1. 差分填坑

  1. 在Linux系统上可以通过diffpatch命令做差分及合并,但由于这两个命令不能再Native层使用,因此推荐使用谷歌的Google-diff-match-patch算法,这是一个跨平台框架,基本支持所有的主流语言。
  2. linux的diff/patch算法和Google-diff-match-patch算法不一致,因此不能混着用,比如:使用linux的diff做差分,使用google算法做合并
  3. 我把该算法的Framework拖到iOS工程中会各种报错,最后还是直接将相关类直接拖到项目中

2. 如何使用Google-diff-match-patch

  • 这个库提供了三个网页,分别来查看diff/match/patch的效果,
    建议直接看patch,里面完整的展示了一个差分合并的流程,

  • 我当时仅仅看了diff,发现生成的差分文件不想我想要的,最后
    查看patch的源码才发现少调用了一个api

四、开源代码

服务端

RN端

你可能感兴趣的:(自动化)