意义
- 小程序代码发布统一收口,上传必须通过合并分支进行。解决小程序新建分支功能经常忘记合并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
执行结果
- 代码上传成功
- 预览二维码生成
- 小程序后台提交记录
扩展
- 本文中上述方式是在本地项目中添加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"
}
}
}
]
- 做一些异常监控,最后对执行结果进行钉钉或其他方式通知即可。