小程序CI/CD之自动化打包预览并钉钉通知发布进程
小程序打包方式分为两种:手动打包、自动打包
那如何实现 自动打包 呐?我们今天就来聊一聊!
首先,很重要,看 官方文档
这里提到今天我们要聊的“主角” miniprogram-ci
miniprogram-ci 是从微信开发者工具中抽离的关于小程序/小游戏项目代码的编译模块。
开发者可不打开小程序开发者工具,独立使用 miniprogram-ci 进行小程序代码的上传、预览等操作。
然后,我们 怎么做!!!
一:准备工作
使用 miniprogram-ci 前应访问"微信公众平台-开发-开发设置"后下载代码上传密钥(最终是需要放在项目根目录下的),并配置 IP 白名单 开发者可选择打开 IP 白名单,打开后只有白名单中的 IP 才能调用相关接口。

再者便是,需要在我们的项目中做好环境区分,即做好:测试环境 、预发环境、生产环境 等环境的区分
package.json 文件中代码如下所示:

ps:我们的小程序使用的是 Uni-App 开发的,因此代码打包命令行的前缀是 build:mp-weixin-xx 类似这样
二:下载包
npm install miniprogram-ci --save
三:项目根目录下编写脚本文件upload.js-实现自动化上传
直接上代码,有注释!(ps:不清楚的地方,我们评论区见~~)
const project_config = require("./project.config.json");
const child_process = require("child_process");
const ci = require("miniprogram-ci");
const inquirer = require("inquirer");
const request = require("request");
const fse = require("fs-extra");
const util = require("util");
const path = require("path");
const fs = require("fs");const example = {appid: "", // 小程序的appidname: "", // 小程序的名字choices: ["测试环境3-test3","测试环境4-test4","预发环境-pre","演示环境-rep","生产环境-prod",],robot_1: 1, // 机器人 1 号robot_2: 2, // 机器人 2 号robot_3: 3, // 机器人 3 号version: "1.0.0",
};class appletCI {exec = util.promisify(child_process.exec);config = {};// 流水线执行上传操作方法async init() {const result_data = await this.inquirer(project_config);this.config = await this.update_config(result_data);this.fs_rewrite_config();await this.upload(result_data);}// 问答:选择环境、版本号、描述async inquirer(config) {return inquirer.prompt([{type: "list",name: "env",message: "请选择部署环境:",default: 0,choices: example.choices,},{type: "input",name: "version",message: `设置上传的版本号(当前版本号:${config.version}):`,filter(opts) {if (opts === "") {return config.version;}return opts;},},{type: "input",name: "desc",message: "请写一个简单的介绍来描述这个版本改动过:",},]);}// 更新配置信息async update_config(user_info) {const env = user_info.env.split("-")[1];const env_desc = user_info.env.split("-")[0];const config = {appid: "", // 小程序的appidname: "", // 小程序的名字env,env_desc,version: user_info.version,desc: user_info.desc || env_desc,robot:env === "prod" || env === "pre"? example.robot_3: env === "rep"? example.robot_2: example.robot_1,};return config;}// 重写配置文件fs_rewrite_config() {fs.writeFileSync("./project.config.json",JSON.stringify(this.config),(err) => {if (err) {console.log("自动写入 project.config.json 文件失败,请手动填写,并检查错误!");}});}// 打包上传async upload() {const {appid: "", // 小程序的appidname: "", // 小程序的名字env = "test3",env_desc = "测试环境3",desc = "测试环境3",robot = example.robot_1,version = example.version,} = this.config || {};console.log(`${env_desc}正在打包`);this.message(`${name}小程序-${env_desc},正在部署`);await this.exec(`npm run build:mp-weixin-${env}`, { cwd: "./" });await this.copyFiles();console.log(`${env_desc}正在部署`);const project = new ci.Project({appid,type: "miniProgram",projectPath: path.join(__dirname, "./dist/build/mp-weixin"),privateKeyPath: path.join(__dirname, "./private." + appid + ".key"),ignores: ["node_modules/**/*", ".vscode", ".hbuilderx"],});await ci.upload({project,robot,desc,version,onProgressUpdate: console.log,}).then(() => {this.message(`${name}小程序-${env_desc},部署完成`);console.log("部署完成");}).catch((error) => {if (error.errCode == -1) {this.message(`${name}小程序-${env_desc},部署完成`);console.log("部署完成");return;}this.message(`${name}小程序-${env_desc},部署失败,原因为:${error}`);console.log("部署失败", error);process.exit(-1);});}// 复制 project.config 文件至 distasync copyFiles() {try {await fse.copy(path.join(__dirname, "./project.config.json"),path.join(__dirname, "./dist/build/mp-weixin/project.config.json"));} catch (err) {console.error(err);}}// 发送钉钉消息message(content) {const data = {msgtype: "text",text: { content },};request({url: "", // 钉钉群里可以看到的webhook地址method: "POST",headers: {"content-type": "application/json",},body: JSON.stringify(data),});}
}const CI = new appletCI();
CI.init();
执行 :
node upload
执行完命令行的终端交互:


继续回车即可 自动化打包完成!
随后,我们去小程序管理后台拿到预览码即可

附录1:钉钉通知结果:

附录:2:钉钉的webhook地址如下图:

附录3:代码中有写到,自动化打包更改的 project.config.json 文件内容如下(每次打包后,该文件都会被更新):
{
"name":"",
"appid":"",
"env":"test3",
"env_desc":"测试环境3",
"version":"",
"desc":"",
"robot":1
}
再聊点其他的,提升点
鉴于在使用过程中获取体验码时,还需打开小程序管理后台获取验证码图片,未彻底解放双手,那么我们再去官方文档中扒拉扒拉,发现 preview 方法是专门实现预览功能滴,即,可实现:自动下载预览二维码图片至本地的某个路径!
具体可查看-预览模块如何实现:

至此,解放双手,happy end!!!
相关文章:
小程序CI/CD之自动化打包预览并钉钉通知发布进程
小程序打包方式分为两种:手动打包、自动打包 那如何实现 自动打包 呐?我们今天就来聊一聊! 首先,很重要,看 官方文档 这里提到今天我们要聊的“主角” miniprogram-ci miniprogram-ci 是从微信开发者工具中抽离的关于…...
C++使用QtHttpServer开发服务端Server的Http POST接口和客户端Client示例
Client HTTP POST 假设http://127.0.0.1:8888/post/是一个能够接受POST请求的路径,我们想要向它提交一段json数据,用Qt可以这样实现: Suppose we want to make an HTTP POST with json body to http://127.0.0.1:8888/post/. QCoreApplica…...
计算机基础(8)——音频数字化(模电与数电)
💗计算机基础系列文章💗 👉🍀计算机基础(1)——计算机的发展史🍀👉🍀计算机基础(2)——冯诺依曼体系结构🍀👉ἴ…...
手搓单链表(无哨兵位)(C语言)
目录 SLT.h SLT.c SLTtest.c 测试示例 单链表优劣分析 SLT.h #pragma once#include <stdio.h> #include <assert.h> #include <stdlib.h>typedef int SLTDataType;typedef struct SListNode {SLTDataType data;struct SListNode* next; }SLTNode;//打印…...
代码随想录算法训练营第18天|二叉树
513. 找树左下角的值 最左边的结点的特性 1.只能是叶子结点, 2.必须考虑是最底层,所以要考虑树的深度 3.同样的深度考虑左子树 考虑迭代法,层序遍历 递归优点难搞的 /*** Definition for a binary tree node.* function TreeNode(val, left, righ…...
使用tftpd更新开发板内核
我们升级内核可以通过原厂提供的升级软件来进行,比如瑞芯微的RKDevTool.exe,只不过这种方式必须通过指定的OTG升级口,还得借助按键进入loader模式后才可以。 其实还可以利用一些通用的工具来进行升级,比如tftpd工具。 下载地址p…...
MySQL数据库整体知识点简述
目录 第一章:数据库系统概述 第二章:信息与数据模型 第3章 关系模型与关系规范化理论 第四章——数据库设计方法 第六-七章——MySQL存储引擎与数据库操作管理 第九章——索引 第10章——视图 第11章——MySQL存储过程与函数 第12章——MySQL 触…...
深入理解MySQL索引下推优化
在MySQL中,索引的使用对于查询性能至关重要。然而,即使有合适的索引,有时查询性能仍然不尽如人意。索引下推(Index Condition Pushdown,ICP)是一项能够进一步优化查询性能的技术。本文将详细讲解索引下推的…...
论文降重技巧:AI工具如何助力论文原创性提升?
论文降重一直是困扰各界毕业生的“拦路虎”,还不容易熬过修改的苦,又要迎来降重的痛。 其实想要给论文降重达标,我有一些独家秘诀。话不多说直接上干货! 1、同义词改写(针对整段整句重复) 这是最靠谱也是…...
el-date-picker的使用,及解决切换type时面板样式错乱问题
这里选择器的类型可以选择日月年和时间范围,根据类型不同,el-date-picker的面板也展示不同,但是会出现el-date-picker错位,或者面板位置和层级等问题。 源代码: <el-selectv-model"dateType"placeholder&…...
Flutter 中的 ToggleButtonsTheme 小部件:全面指南
Flutter 中的 ToggleButtonsTheme 小部件:全面指南 Flutter,作为由 Google 开发的跨平台 UI 框架,为开发者提供了丰富的组件来构建现代化的应用程序。ToggleButtons 是 Material Design 组件库中的一个组件,它允许用户从一组选项…...
新手教程之使用LLaMa-Factory微调LLaMa3
文章目录 为什么要用LLaMa-Factory什么是LLaMa-FactoryLLaMa-Factory环境搭建微调LLaMA3参考博文 为什么要用LLaMa-Factory 如果你尝试过微调大模型,你就会知道,大模型的环境配置是非常繁琐的,需要安装大量的第三方库和依赖,甚至…...
Java函数笔记
1. Statement.executeQuery 和 Statement.executeUpdate 作用: 用于执行SQL查询和更新操作。 问题: 容易导致SQL注入攻击。 解决方法: 使用PreparedStatement进行参数化查询。 // 不安全的做法 Statement stmt connection.createStat…...
Maven实战: 从工程创建自定义archetype
在上一节中(创建自定义archetype)我们手动创建了一个项目模板,经过5步能创建出一个项目模板,如果我有一个现成的项目,想用这个项目作为模板来生成其他项目呢?Maven提供了基于项目生成archetype模板的能力,我们分3步来讲…...
初识JAVA中的包装类,时间复杂度及空间复杂度
目录: 一.包装类 二.时间复杂度 三.空间复杂度 一.包装类: 在Java中,由于基本类型不是继承自Object,为了在泛型代码中可以支持基本类型,Java 给每个基本类型都对应了一个包装类型。 1 基本数据类型和对应的包装类 &am…...
RapidMiner如何利用Hugging Face中的模型实现更有趣的事
RapidMiner Studio最新发布的功能更新,重点是嵌入Hugging Face和Open AI,Hugging face中含有大量的可用模型,包含翻译、总结、文本生成等等强大的模型,Open AI更不必说了,生成界的鼻祖。那么今天主要介绍一下RapidMine…...
Vue3 自定义Hooks函数的封装
1、如何理解vue3中的自定义hooks 在Vue 3中,自定义hooks允许开发者封装和重用逻辑代码。自定义hooks是使用Composition API时创建的函数,这些函数可以包含任意的组合逻辑,并且可以在多个组件之间共享。 自定义hooks通常遵循这样的命名约定&…...
python的DataFrame和Series
Series、DataFrame 创建 pd.Series() pd.DataFrame() # 字典{列名:[值1,值2],} [[]] [()] numpy Pandas的底层的数据结构,就是numpy的数组 ndarray 常用属性 shape (行数,) (行数,列数) values → ndarray index 索引名 siz…...
ARP欺骗的原理与详细步骤
ARP是什么: 我还记得在计算机网络课程当中,学过ARP协议,ARP是地址转换协议,是链路层的协议,是硬件与上层之间的接口,同时对上层提供服务。在局域网中主机与主机之间不能直接通过IP地址进行通信,…...
25、DHCP FTP
DHCP 动态主机配置协议 DHCP定义: 服务器配置好了地址池 192.168.233.10 192.168.233.20 客户端从地址池当中随机获取一个ip地址,ip地址会发生变化,使用服务端提供的ip地址,时间限制,重启之后也会更换。 DHCP优点&a…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门  bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
