基于SAAS原生小程序自动化部署上传审核方案

2,000 阅读6分钟

今年一直在开发壹号体系的SAAS小程序,租户太多(壹号食品、肉联帮、后续可能还有壹号土猪、壹号土鸡、天地壹号巴拉巴拉的)每次都要手动发布总是担心发错环境配置。就花了两天时间捣鼓了一下微信小程序的自动化部署方案(如有不正之处,请各位大佬指出)。那么废话不多说,直接进入今天的正题吧。

一、背景

随着业务的快速发展,小程序的包体积和逻辑也与日俱增,以及各类工具和预编译命令的前置执行,使我们进行一次小程序的部署操作变得越来越复杂,越来越迟缓,效率极低。而且在复杂的发布操作流程中,稍有不慎和遗漏,就有可能出现生产环境事故的隐患。

因此我们团队在今年划分出来一部分时间和精力,快速地产出了一套简易的小程序前端应用自动化部署方案,将原本流程复杂的操作,统一收敛到一台服务器上去执行。开发者仅需关心自身业务代码的编写与提交,而无需过多关注测试之后,代码是如何实现上传、并完成送审的。试图通过这一套规范的工程化流程,有效提高工作效率及发布部署的基本稳定性。

二、准备工作

环境:一台服务器

工具:Gitlab、微信开发者工具、Node相关、miniprogram-ci、cross-env

编码要求:基本的Node脚本编写能力、熟悉微信开发者 Cli 命令调用的文档

三、实现思路

1. 何时打包

通过 发布平台(没有自己集成的可以使用 Gitlab Runner) 实现业务代码的 Git 推送与打包服务器之间的互联,这里基础原理不多赘言,大致就是服务器通过 GIt 命令 pull 最新代码来执行打包构建上传到小程序平台。

Gitlab Runner原理

简单来说,就是把你本地 push 代码的一次操作及其相关的附带信息,通知到你期望为你打包的服务器,最终服务器还会将执行结果再反馈给你。

2. 如何打包

上一步中服务器收到需要执行打包任务的信号后,开始从仓库拉取本次 push 的代码,调用本地打包脚本,完成打包和后续操作。

微信为我们提供了比较完善的一套 CI 命令库,支持我们通过调用命令实现那些日常需要手动点击的操作,例如打开工具、点击预览、上传代码、关闭工具等等。我们需要实现一次代码打包和上线部署,就需要调用上传的命令进行代码上传的操作。

微信近期对命令库进行了更新,添加、修改了部分 API 的调用方式,我们自然也需要同步的进行一些代码修改,并抽离了名为 miniprogram-ci 的编译模块,支持开发者独立使用 miniprogram-ci 进行小程序代码的上传、预览等操作,这样的话,Linux 机器也可以用来部署小程序应用了。

3. 后续操作

从社区文章来看,很多做小程序开发的团队也在做上面和提到的内容同样的事情,但是我们团队仍然觉得小程序上传成功之后,还需自己去打开浏览器,扫码登陆开发者后台,再去找刚才提的版本号,点击按钮、扫二维码,才能完成一次体验版或者送审版的选择。因为我们将采用 Puppeteer 做了设置体验版/送审版的自动化(其实是半自动化)脚本功能,进一步提效。因为我们是SASS化的产品,需要发布的租户小程序太多,手动发布需要点击太多吗,所有成为微信第三方平台,通过平台代理的方式,对旗下所有小程序提供业务支持,版本发布等.

四、具体步骤

1. 本地打包测试

安装miniprogram-ci

npm i miniprogram-ci -S

安装cross-env

npm i cross-env -S

因为我们是做SAAS商城的,区别根据不同租户环境去打包不同小程序,采用cross-env 结合 node 就可以自定义环境变量来打包

准备上传密钥

密钥文件只有小程序的管理员有权限生成。 具体位置是在小程序管理平台中的,开发->开发设置->小程序代码上传->小程序代码上传密钥。 将生成的密钥文件放在项目配置中。 这里还可以开启ip白名单,指定的ip才能执行上传脚本(我们这种方案里,就是发布平台所在的机器的ip)。

ci.js 发布脚本

在项目根目录下创建ci.js文件

const ci = require('miniprogram-ci')
const fs = require('fs');
const merchants = require('./config/merchant');
var version = '2.2.2.3'
var desc = 'desc'
const mid = process.env.NODE_ENV
// const version = process.env.VERSIONconsole.log('version',version)
​
//根据不同环境租户命令来创建mid
let writeContent = `export const mid = '${mid}'`
fs.writeFile('./config/mid.js',writeContent,function(err){
    console.log('write file error',err);
})
​
//创建成功后获取对应租户信息
const merchant = merchants[mid]
​
// appid 和privateKeyPath需要设置下
const project = new ci.Project({
  appid: merchant.appid,
  type: 'miniProgram',
  projectPath: './',
  privateKeyPath: `./config/key/${mid}.key`,
  ignores: ['node_modules/**/*']
})
​
/** 构建npm */
async function packNpm() {
  // 在有需要的时候构建npm
  const warning = await ci.packNpm(project, {
    ignores: ['pack_npm_ignore_list'],
    reporter: (infos) => { console.log(infos) }
  })
  console.warn(warning)
}
​
/** 上传 */
async function upload({ version = '0.0.0', desc = 'test', robot = 1 }) {
  await ci.upload({
    project,
    version: mid,
    desc: `发布${mid}租户`,
    setting: {
      es7: true,
      minify: true,
      autoPrefixWXSS: true
    },
    onProgressUpdate: console.log
  })
}
​
async function done () {
  await packNpm()
  await upload({ version, desc })
}
​
done()

编写脚本

//package.json
  "scripts": {
    "9t9fw": "cross-env NODE_ENV=9t9fw node ./ci.js",
  },

运行脚本

npm run 9t9fw

可以在微信公众平台发现ci机器人已经帮我们构建上传成功,当然如果只是本地测试可以不用构建只上传 image.png

2. 部署平台集成发布

部署平台点击发布也是让服务器执行 shell 脚本来处理对应命令来来最新代码仓库到服务器来打包构建上传。当然没有自己集成的部署平台可以使用gitlab ci等来部署,原理都是为了执行对应服务器打包。

image.png

对应执行的shell脚本

PROJECT_NAME=商家端小程序\
\
#项目文件夹\
PROJECT_FOLDER=XXX
#项目仓库\
PROJECT_REPO=XXX
\
#待发布分支\
BRANCH_TO_RELEASE=cl\
#工作目录\
WORKSPACE=XXX
\
\
echo "${PROJECT_NAME}项目上传中..."\
\
cd ${WORKSPACE}\
if [ ! -d ${PROJECT_FOLDER} ]; then\
        echo "项目不存在,创建中..."\
        git clone -b ${BRANCH_TO_RELEASE} ${PROJECT_REPO}\
        if [ $? -ne 0 ]; then\
                echo "项目创建异常"\
                exit 1\
        fi\
        echo "项目创建成功"\
fi\
\
cd ${PROJECT_FOLDER}\
\
#更新ERP项目\
git pull origin ${BRANCH_TO_RELEASE}\
echo "项目更新成功"\
\
#编译项目\
echo "开始上传项目..."\
cnpm install\
\
cnpm run 9t9fw\
\
if [ $? -ne 0 ]; then\
        echo "编译项目异常"\
        exit 1\
fi\
\
echo "项目上传成功"

五、总结交流

我们放弃使用手动上传的方式来发布主要是为了在效率,安全和规范三个层面有一个提升。其次是由于做SAAS需要一套代码发布的小程序可能有很多个租户,需要接入自动化发布审核

每次发布只要提交代码到指定的分支,实现自动打包发布,避免因多人开发频繁切换开发版本(这还导致代码版本不好管理)。

不同分支有对应的机器人来发布,避免了发布正式版本后,需要重新打包切换回测试环境的动作。

体验版发布带上commit sha帮助我们更好追踪代码的版本。

这个方案集成后,发布版本的代码必定在代码仓库中,在一定程度上避免风险,确保历史记录有迹可循。