一、自动部署流程
- 将小程序代码提交到GitLab上的test/master分支;
- GitLab触发Jenkins进行构建(安装依赖,打包项目);【工具:webhook】
- 构建时执行项目中的push.js将打包好的代码上传到小程序服务器,并通过机器人发布体验版。【工具:Miniprogram-Ci】
二、配置Jenkins
在Jenkins中新建任务,进行如下配置:
npm config set registry https://registry.npm.taobao.org // 使用淘宝镜像
npm install // 安装依赖
npm run build:mp-weixin:test // 打包项目
npm run push --env=test // 执行./build/push.js上传代码到小程序平台
三、配置gitlab中webhook
通过配置一些钩子,当触发到这些钩子说,webhook机制发出请求,告知Jenkins服务器需要自动构建。
四、上传代码到小程序平台
平时我们上传代码都通过微信开发者工具的上传按钮,上传成功后去微信公众平台小程序->版本管理将上传的版本设置为体验版(默认会延续上一个体验版的开发者发布的新版本作为新的体验版)。
若不想通过微信开发者工具,而是直接使用命令将代码上传,需借住miniprogram-ci插件 。 首先安装依赖:
npm install miniprogram-ci --save
npm install shelljs --save
项目根目录新建文件/build/push.js:
const ci = require('miniprogram-ci')
const shell = require('shelljs')
const package = require('../package.json')
const argvs = JSON.parse(process.env.npm_config_argv).original // 获取命令参数
// 注意: new ci.Project 调用时,请确保项目代码已经是完整的,避免编译过程出现找不到文件的报错。
const project = new ci.Project({
appid: 'xxxxxxx', //小程序appid
type: 'miniProgram', // 默认miniProgram
projectPath: './dist/build/mp-weixin/', // 项目打包路径
privateKeyPath: './build/private.aaaaaaaaaaaaa.key', // 微信公众平台->开发->开发管理->小程序代码上传->生成小程序代码上传密钥
ignores: ['node_modules/**/*'] // 忽略无需上传的文件
})
// 测试环境:npm run push --env=test
// 生产环境:npm run push --env=production
// 获取env参数值
const getEnv = () => {
let env = 'test'
argvs.some((argv) => {
if (argv.includes('--env')) {
const result = argv.split('=')
if (result) {
const [_, envTag] = result
env = envTag
return true
}
}
return false
})
return env
}
//
const getLastCommit = () => {
const res = shell.exec('git log -1 --pretty=format:%h:%s') // 获取执行命令的结果,返回git提交记录编码和提交名称,例:ecec2cb:修复XXX问题
if (!res) return null
const [hash, desc] = res.stdout.split(':')
return {
hash, // 例:ecec2cb
desc // 例:修复XXX问题
}
}
// 上传小程序后台
const upload = async () => {
try {
const commit = getLastCommit()
if (!commit) {
console.log('未找到提交记录')
return
}
const { hash, desc } = commit
const [major, minor] = package.version.split('.')
// 测试版本最后一位版本号为git提交记录编码
const env = getEnv()
const isTest = env === 'test'
const version = isTest ? `${major}.${minor}.${hash}` : package.version
// 换行
console.log('')
console.log('版本号:', version)
console.log('----------------------开始处理----------------------')
const uploadResult = await ci.upload({
project,
version,
desc,
setting: {
es6: true
},
robot: isTest ? 1 : 2,
onProgressUpdate: (res) => {
if (res._msg === 'upload') {
if (res._status === 'doing') {
console.log('')
}
}
}
})
console.log('----------------------上传成功----------------------')
console.log(uploadResult)
console.log('---------------------------------------------------')
} catch (e) {
console.log('----------------------上传失败----------------------')
console.log(e)
console.log('---------------------------------------------------')
}
}
upload()