小程序ci自动打包上传到微信平台

发布时间:2024年01月24日
?yarn start? -- index.js配置文件
/*
 * @Date: 2024-01-04 10:58:50
 * @Description: 
 */
const fs = require('fs')
const spawn = require('cross-spawn')
const inquirer = require('inquirer')
const ci = require('miniprogram-ci');
const { getFeiShuDocContent } = require('./feishuNotify')

/** 确认用户的选项 */
function checkList() {
  const promptList = [
    {
      type: 'list',
      message: '请选择操作类型',
      pageSize: 100,
      name: 'action',
      choices: [
        {
          name: '开发',
          value: 'develop',
        },
        {
          name: '打包',
          value: 'build',
        },
      ],
    },
    {
      type: 'list',
      message: '选择环境',
      pageSize: 100,
      name: 'env',
      choices: [
        {
          name: '测试',
          value: 'dev',
        },
        {
          name: '预发布',
          value: 'pre',
        },
        {
          name: '生产',
          value: 'prod',
        },
      ],
    },
    
  ]
  return inquirer.prompt(promptList)
}

const additionalList = [
  {
    type: 'input',
    message: '请输入打包备注:',
    name: 'desc',
  }
]


checkList().then(({ action, env }) => {
  let arr = []
  if (action == 'build') {
    inquirer.prompt(additionalList).then(({desc}) => {
      if(desc) {
        arr = ['run', 'build:weapp', '--', '--mode', `${env}`]
      }else {
        return 
      }
      uploadProject({arr, desc, env})
    })
  } else {
    arr = ['run', 'build:weapp', '--', '--watch', '--mode', `${env}`]
    spawn('npm', arr, {
      stdio: 'inherit',
    })
  }
})


function uploadProject(options) {
  const {arr, desc, env }  = options
  spawn.sync('npm', arr, {
    stdio: 'inherit',
  })
  /** 读取配置文件(如果项目中 公共文件 配置的变量 比如version) */
  const configData = fs.readFileSync('src/core/config/index.ts', 'utf-8')
  const project = new ci.Project({
    appid: appId,
    type: 'miniProgram',
    projectPath: `./dist/weapp`,
    privateKeyPath: `./script/private.appId.key`, //配置了公网IP后,下载密钥文件
    ignores: [],
  })
  /** version版本获取 */
  const match = configData.match(/export const version = '(.+?)'/)
  const version = match && match[1]
  /** 总包 */
  let totalSize = '0KB'
  /** 主包 */
  let mainSize = '0KB'
  let errorMsg = ''
  ci.upload({
    project,
    version: version,
    desc: desc || '',
    threads: 50,
    setting: {
      es6: true,
      es7: true,
      minify: true,
      minifyJS: true,
      minifyWXML: true,
      minifyWXSS: true,
    },
  })
  .then((res) => {
    res.subPackageInfo.forEach((item) => {
      if (item.name === '__APP__') {
        mainSize = `${Math.round(item.size / 1024)}KB`
      } else if (item.name === '__FULL__') {
        totalSize = `${Math.round(item.size / 1024)}KB`
      }
    })
  })
  .catch((err) => {
    console.log('上传失败')
    errorMsg = '上传失败'
  })
  .finally((res) => {
    //发送通知 (拓展: 可以绑定飞书文档)
    getFeiShuDocContent({
      desc,
      errorMsg,
      version,
      mainSize,
      totalSize,
      env
    })
  })
}
飞书群机器人通知-配置文件feishuNotify.js

const https = require('https'); 
const { spawn } = require('cross-spawn')

/** 发送飞书通知 */
function sendNotifyFeiShu(option) { 
  const data = JSON.stringify({
      msg_type: 'interactive',
      card: {
        'config': {
          'wide_screen_mode': true,
        },
        'i18n_elements': {
          'zh_cn': [
            {
              'tag': 'markdown',
              'content': `**【小程序】- 打包日志**
版本:${option.version}
操作人:${option.userName}
打包分支:${option.branchName}
主包大小:${option.mainSize}
环境:${option.development}
**更包备注:${option.desc} **
            `,
            },
          ],
        },
      },
    }
)
  /** 发送机器人通知 */ 
   //这个就是飞书群里面的机器人的Webhook 地址
  postRequest({ path: '/open-apis/bot/v2/hook/47e40a4f-fa60-4e4b-b598-da45201b143b', data })
}

/** 获取飞书文档文本内容 */
async function getFeiShuDocContent(options) {
  // 如果需要绑定飞书文档, 需要在飞书开发平台创建企业应用,然后就会有这些数据
  //const data = JSON.stringify({
    //app_id: 'cli_a5197b60c4b0xxxxx',
    //app_secret: 'aNbQHj8OhYyY6KCasFJsIhasatxxxxxx'
  //})
  try {
    /** 当前分支信息 */
    const branchResult = spawn.sync('git', ['rev-parse', '--abbrev-ref', 'HEAD'])
    /** 分支名称 */
    const branchName = branchResult.status === 0 ? branchResult.stdout.toString().trim() : ''
    /** 当前用户信息 */
    const result = spawn.sync('git', ['config', 'user.name'])
    /** 用户名称 */
    const userName = result.status === 0 ? result.stdout.toString().trim() : ''
    /** 当前时间 */
    const time = new Date()
    /** 环境 */
    let development = '正式站'
    if(options.env == 'dev') {
      development = '测试站'
    }else if(options.env == 'pre') {
      development = '预发布'
    }

    /** 发送飞书通知 */
    if(!options.errorMsg) {
      sendNotifyFeiShu({...options, branchName, time, userName, development})
    }
  } catch (error) {
    console.log(error)
  }
}

/** POST请求 */
function postRequest(options) {
  return new Promise((resolve, reject) => {
    const { path, data, headers} = options;
    const req = https.request({
      hostname: 'open.feishu.cn', 
      port: 443,
      path, 
      method: 'POST', 
      headers: { 
        'Content-Type': '"application/json; charset=utf-8"',
        ...headers
      } 
    }, (res) => {
      let responseData = '';
      res.on('data', (chunk) => {
        responseData += chunk;
      });
      res.on('end', () => {
        resolve(JSON.parse(responseData))
      });
    });
    req.on('error', (error) => {
      reject(`${options.path}:${error.message}`)
    });
    req.write(data);
    req.end();
  })
}

/** GET请求 */
function getRequest(options) {
  return new Promise((resolve, reject) => {
    const req = https.request(options.path,
      { method: 'GET', headers: { 'Authorization': `Bearer ${options.token}` } }, (res) => {
        let responseData = '';
        res.on('data', (chunk) => {
          responseData += chunk;
        });
        res.on('end', () => {
          const { data, code } = JSON.parse(responseData)
          if(code == '0') {
            resolve(data)
          }
        });
      });
      req.on('error', (error) => {
        reject(`${options.path}:${error.message}`)
      });
      req.end();
  })
}

module.exports = {
  getFeiShuDocContent
}
项目文件结构

文章来源:https://blog.csdn.net/qq_40610760/article/details/135823779
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。