小程序CI一键发布

1,805 阅读3分钟

意义

  • 小程序代码发布统一收口,上传必须通过合并分支进行。解决小程序新建分支功能经常忘记合并master,导致后期新增功能时历史功能被覆盖。
  • 体验版始终设置为由机器人上传版本,避免每次换组员上传后还需要去微信小程序后台手动切换体验版。
  • 测试到生产因人为导致配置错误等问题。
  • 解决测试,开发频繁找开发编译二维码导致开发效率低等问题。可使用Jenkins自动化构建部署。

开发

前期准备

  • 下载各自小程序的上传私钥。
    • 位置:微信小程序后台->开发->开发管理->开发设置->小程序代码上传->小程序代码上传秘钥,生成。
    • 将秘钥放在项目根目录下。
  • 配置ip白名单,如有ci机器可通过服务器统一发布,即配置服务器ip名单或本地发布ip地址。

项目开发

大致思路

  • 拿到配置环境中各变量值
  • 调用ci.Project 微信小程序提供api,创建项目。
  • 调用ci.upload 微信小程序提供api,上传本地代码到小程序后台。
  • 调用ci.preview 微信小程序提供api,生成预览二维码。

环境变量设置

.env.development文件配置

VUE_APP_ENV=development
VUE_APP_MP_APPID =xxxxxxxxxxx
VUE_APP_PROJECT_PATH='./dist/dev/mp-weixin'

核心代码

ci.js文件

const path = require('path');
const ci = require('miniprogram-ci');
const shelljs = require('shelljs');
const dotenv = require('dotenv');
const package = require('./package.json');

const BRANCH_MAP = {
  'mini-ci': 'development',
  feat_ci: 'development',
};

// 检查控制台是否以运行`git `开头的命令
if (!shelljs.which('git')) {
  //在控制台输出内容
  shelljs.echo('Sorry, this script requires git');
  shelljs.exit(1);
}

function getEnvironment() {
  // 1. 获取当前的环境,使用分支名区分; 2. 环境变量注入
  const branch = shelljs.exec('git symbolic-ref --short -q HEAD').trim();
  return BRANCH_MAP[branch];
}

function getConfig(env) {
  let content = dotenv.config({ path: resolve(`./.env.${env}`) });
  return content && !content.error ? content.parsed : undefined;
}

function resolve(p) {
  return path.resolve(__dirname, p);
}

function defaultDesc() {
  return new Date().toLocaleString() + '发布了版本' + package.version;
}

async function run() {
  const env = getEnvironment();
  if (!env) {
    console.log(`当前分支${branch}不支持自动部署`);
    return;
  }
  console.log('env = ', env);

  const config = getConfig(env);
  if (!config) {
    console.log('---- 获取config文件失败 ----');
    return;
  }

  try {
    // 创建项目
    const project = new ci.Project({
      appid: config.VUE_APP_MP_APPID,
      type: 'miniProgram',
      projectPath: config.VUE_APP_PROJECT_PATH, // 可以配在环境变量
      privateKeyPath: `./private.${config.VUE_APP_MP_APPID}.key`, // 可以配在环境变量 或 是在线拉取
      ignores: ['node_modules/**/*', 'dist/*'],
    });

    // 小程序代码上传
    const uploadResult = await ci.upload({
      project,
      version: package.version,
      desc: package.version_desc || defaultDesc(),
      setting: {
        es6: true,
        minify: true,
        autoPrefixWXSS: true,
      },
      robot: 1,
      onProgressUpdate: console.log,
    });
    console.log('uploadResult = ', uploadResult);
    console.log('---- 代码部署完毕,请到小程序后台 https://mp.weixin.qq.com/ 进行后续操作 ----');

    // 小程序预览二维码代码生成
    const previewParams = {
      project,
      desc: package.version_desc || defaultDesc(),
      setting: {
        es6: true,
        minify: true,
        autoPrefixWXSS: true,
      },
      qrcodeFormat: 'image',
      qrcodeOutputDest: resolve('./destination.jpg'),
    };

    const previewResult = await ci.preview(previewParams);
    console.log('previewResult = ', previewResult);
    console.log('---- 代码部署完毕,请到本地项目 destination.jpg 处查看预览二维码 ----');
  } catch (error) {
    console.log('uploadResult error = ', error);
  }
}

run();

package.json文件配置:

 "publish": "node ./ci.js"

运行命令:

npm run publish

执行结果

  • 代码上传成功

image.png

  • 预览二维码生成 image.png
  • 小程序后台提交记录

image.png

扩展

  • 本文中上述方式是在本地项目中添加ci.js文件,最后执行进行上传的方式。但是在大型公司中小程序项目会很多,每个项目中都添加此文件会很低效。
  • 因此可以将小程序ci添加到统一的发布平台去拦截自动上传代码。
    • 例如:在gitlab中使用Webhooks进行拦截,项目发布触发CICD,将小程序项目代码统一上传至微信小程序后台。
    • 其中上述方式通过环境变量获取变量方式可改为json文件维护,获取json文件并进行匹配得到对应项目的配置。配置方式如下:
[
  {
    "projectGroup": "f2e",
    "projectName": "lemon-mp",
    "qatest": {
      "project": {
        "appId": "xxxxxxx1",
        "appName": "小程序测试环境",
        "type": "miniProgram",
        "projectPath": "/dist/build/mp-weixin",
        "privateKeyPath": "/private.xxxxxxx1.key"
      }
    },
    "pre-release": {
      "project": {
        "appId": "xxxxxxx2",
        "appName": "小程序预发环境",
        "type": "miniProgram",
        "projectPath": "/dist/build/mp-weixin",
        "privateKeyPath": "/private.xxxxxxx2.key"
      }
    },
    "prod": {
      "project": {
        "appId": "xxxxxxx3",
        "appName": "小程序线上环境",
        "type": "miniProgram",
        "projectPath": "/dist/build/mp-weixin",
        "privateKeyPath": "/private.xxxxxxx3.key"
      }
    }
  }
]
  • 做一些异常监控,最后对执行结果进行钉钉或其他方式通知即可。

附件

小程序ci三方API