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

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
}
项目文件结构
相关推荐
陈思杰系统思考Jason2 小时前
系统思考—深层结构
百度·微信·微信公众平台·新浪微博·微信开放平台
尚梦6 小时前
uni-app 封装刘海状态栏(适用小程序, h5, 头条小程序)
前端·小程序·uni-app
paopaokaka_luck10 小时前
基于Spring Boot+Vue的助农销售平台(协同过滤算法、限流算法、支付宝沙盒支付、实时聊天、图形化分析)
java·spring boot·小程序·毕业设计·mybatis·1024程序员节
IT-民工2111011 小时前
CI/CD 实践总结
运维·ci/cd·自动化
Bessie23413 小时前
微信小程序eval无法使用的替代方案
微信小程序·小程序·uni-app
蜕变菜鸟13 小时前
小程序跳转另一个小程序
小程序
16 小时前
躺平成长-代码开发,利用kimi开发小程序(09)
小程序
19 小时前
微信小程序运营日记(第四天)
微信小程序·小程序
guanpinkeji19 小时前
旧衣回收小程序:提高回收效率,扩大服务范围
大数据·小程序·团队开发·软件开发·小程序开发·旧衣回收·旧衣回收小程序
说私域21 小时前
完美日记营销模式对开源 AI 智能名片 2 + 1 链动模式 S2B2C 商城小程序的启示
人工智能·小程序