微信小程序自动化部署方案

6,434 阅读9分钟

一、背景

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

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

二、准备工作

环境:一台 Mac 服务器(能够拥有一台 Mac 服务器是最好的选择,实在没有可以用 Windows 系统的机器,但可能会遇到更多不可预知的问题)

工具:Gitlab CI、Gitlab Runner、微信开发者工具、Puppeteer、Node相关

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

三、实现思路

1. 何时打包

通过 Gitlab Runner 实现业务代码的 Git 推送与打包服务器之间的互联,这里基础原理不多赘言,大家可以去阅读 Gitlab Runner 的一些基本原理,大致就是 Gitlab Runner 启动之后,会发起轮询请求,Gitlab Runner 会每隔几秒就去问 Gitlab:“你这边最近有啥 push 操作吗?是否需要我拉下最新代码来打个包?”。

Gitlab Runner原理

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

2. 如何打包

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

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

微信近期对命令库进行了更新,添加、修改了部分 API 的调用方式,我们自然也需要同步的进行一些代码修改,并抽离了名为 miniprogram-ci 的编译模块,支持开发者独立使用 miniprogram-ci 进行小程序代码的上传、预览等操作,这样的话,Linux 机器也可以用来部署小程序应用了。不过这个功能我们目前还未在生产中使用,大家感兴趣可以自己去尝试一下。

3. 后续操作

从社区文章来看,很多做小程序开发的团队也在做上面和提到的内容同样的事情,但是我们团队仍然觉得小程序上传成功之后,还需自己去打开浏览器,扫码登陆开发者后台,再去找刚才提的版本号,点击按钮、扫二维码,才能完成一次体验版或者送审版的选择。因此我们又基于 Puppeteer 做了设置体验版/送审版的自动化(其实是半自动化)脚本功能,进一步提效。

四、具体步骤

1. 安装服务器环境

在服务器上安装 Gitlab Runner,这里大家可以自行百度谷歌,或者查阅官方文档,还是比较简单就可以做成的。值得一提的是,由于我们团队使用的 Gitlab 版本比较老旧,只能使用旧版本的 gitlab-ci-multi-runner,这里大家按自己的实际情况来选择,参考 官方文档 的说明来安装操作。

安装成功之后,需要对其进行注册,这一步的目的是将你刚才安装好的 Gitlab Runner 与你托管代码的 Gitlab 之间建立里关联关系,注册过程中需要填入 GItlab 相关的域名、 Token 信息等等,就是为了确保后续 Gitlab 推送过来的任务,Gitlab Runner 这边可以准确的接收到。

当注册成功之后,在 Gitlab 的 Runner 列表就可以看到刚刚注册好的内容:

2. 添加 Job

Gitlab Runner 安装和注册成功之后,需要做的就是添加 Job。Job 简单来说就是你期望 Gitlab Runner 去帮你做的事情,你需要指定 Gitlab Runner 在某个时机符合某些必要条件时,去执行某个 Job,进行一系列的操作。

添加Job任务的方式,是通过一个YAML格式的配置文件来实现的,具体的配置方式大家也可以自行查找,网上资料很多,官方文档 的介绍也很详细。

这一步的目的,就是再未来你某次push操作之后,触发远端的 Gitlab Runner 帮你执行这个Job,并且在配置文件中详细描述了这个Job执行的各类参考信息,如分支、命令、条件等等。

这里贴一个简单的案例,以供参考:

# .gitlab-ci.yml 文件

stages:
  - upload

# 上传微信公众平台
upload:
  stage: upload
  before_script:
    # 这里还可以做很多我们自定义的前置操作,Lint校验、自动化测试等等
    - yarn
  script:
    # 获取当前的Git项目路径
    - PROJECT_PATH=`pwd`
    - node /我们编写的发布脚本的路径/upload.js $PROJECT_PATH
  only:
    - master
  tags:
    - upload

3. 通过 Puppeteer 选择体验版/送审版

这一步就比较简单,也很容易理解,就是把原本需要人为手动执行的操作,变成自动化的脚本去执行。这里的实现思路和步骤也简要介绍一下:

  • 模拟用户输入,填写当前微信公众账号和密码,登入后台。(这里一般不会出现需要填写验证码的情况)

  • 在页面中查找本次需要选择的版本 DOM 结构,点击相关按钮,完成设置体验版或者送审版

  • 送审版还需要模拟用户输入送审版本相关信息,如果当前已存在送审版,还需视情况做特殊处理

4. 其他处理

  • 扫码

当服务器上安装的微信开发者工具未登录账号时,执行CI命令会返回权限错误的错误,此时则需要用户去手动扫码,成功登录后才可进行后续操作。此处我们选择了将登录二维码转为图片格式的钉钉机器人消息,并在输出控制台中打印的方式,通知和引导用户快捷扫码,完成登录操作。并且在成功的回调函数重试前一步执行失败的相关命令。

上面提到的在 Puppeteer 中登录公众平台后台系统,也可以通过这种机制来实现。

  • 体验版/送审版的附带信息

当我们在后台中选择体验版/送审版时,需要知道本次操作对应的版本号,当为选择送审版本时,还需得知送审的相关备注信息。这些内容我们是通过在本地代码的 push 操作之前,手动地填入这些信息,生成一份 JSON 格式的配置文件,最终在部署脚本执行时读取这份配置来实现。

这里也贴一个简单的示范:

// upload.config.json 配置文件

{
  "project": "MyProject", // 项目名,用于后台设置的账号密码匹配
  "type": 1, // 发布类型(默认0:上传完成不做任何操作;1:仅设置体验版;2:仅送审;3:设置体验版并送审)
  "version": "0.0.1", // 本次发布的版本号
  "uploadDesc": "上传备注信息",
  "publishDesc": "送审备注信息" // 送审时(type为2或3)此条为必填项
}

五、遗留问题

1. 重复扫码问题

虽然需要每次扫码,但是省去了操作浏览器,点击页面的操作,一定程度上提高了效率,并且降低人工发布的出错率。尤其是在做一些 Saas 类小程序部署时,一次代码 push 需要触发多个小程序的上传和发布,这种半自动化的机制还是可以省去不少时间的。

2. 最终发布操作仍需手动执行

我们目前实现的功能,仅覆盖到了送审阶段。当微信方完成审核、或者审核出现异常时,仍需我们手动进入后台进行相关操作。这一块我们团队目前没有投入过多精力去研究解决,主要原因还是因为现阶段的工程化、自动化程度已经可以很大程度上提高效率和稳定性,暂时无需投入更多精力和资源。大家如果仍感兴趣,可以自行研究实现,通过定时监听后台的版本送审状态信息,实现全盘的自动化。如果时类似 Saas 相关业务的发布,还可以考虑接入微信服务商的相关能力,官方会提供较为完善的批量发布能力。

3. 不能多开

Gitlab Runner 本身是可以支持多个 Job 并发执行,可以通过设置并发阈值进行修改。但由于微信开发者工具本身原因,同时运行多个 CI 命令时,内部会出现不可预知的 Bug ,这一点在近几个版本的微信开发者工具中仍然存在,不知道微信后续是否会解决这些 bug 。我们后续还可以尝试使用脱离工具的 miniprogram-ci 模块,进一步提高任务执行效率。

六、总结交流

目前此套工程化方案已经在团队中试行了近半年,过程没有出现太大的问题,偶然出现的一些环境、版本需要更新的情况,也可以很快得以解决。整体来说,这种自动化或者半自动化的方案,还是可以从一定程度上提高我们的工作效率,有效的避免了因人为操作失误而导致的部署故障问题,最终影响到线上用户。

上面提到了一些遗留问题有待解决,以及大家对过程中某个阶段有所疑惑或者改进意见,都可以与我联系,共同探讨,欢迎大家积极讨论!