基于jenkins webhook 实现自动化部署微信小程序

1,657 阅读2分钟

一、自动部署流程

  1. 将小程序代码提交到GitLab上的test/master分支;
  2. GitLab触发Jenkins进行构建(安装依赖,打包项目);【工具:webhook】
  3. 构建时执行项目中的push.js将打包好的代码上传到小程序服务器,并通过机器人发布体验版。【工具:Miniprogram-Ci】

二、配置Jenkins

在Jenkins中新建任务,进行如下配置:

image.png

image.png

image.png

image.png

image.png

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服务器需要自动构建。

image.png

四、上传代码到小程序平台

平时我们上传代码都通过微信开发者工具的上传按钮,上传成功后去微信公众平台小程序->版本管理将上传的版本设置为体验版(默认会延续上一个体验版的开发者发布的新版本作为新的体验版)。

若不想通过微信开发者工具,而是直接使用命令将代码上传,需借住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()