uniapp 小程序 CI(持续集成) 工具集,提供 CLI 和 Vite 插件(推荐)两种使用方式。
在 uni 的 build 或 dev 命令完成后自动执行:
- 打开开发者工具并打开项目
- 上传开发版并生成预览二维码(等同于点击微信开发者工具中的“预览”按钮)
- 上传体验版并生成预览二维码 (等同于点击微信开发者工具中的“上传”按钮)
- 交交互式的更新版本号 -> 创建 git commit 和 tag -> git push。
如我开发微信小程序的常用工作流
{
"scripts": {
// [开发] 运行开发模式 -> 自动打开微信开发者工具并打开项目
"dev:mp-weixin": "uni dev -p mp-weixin -- --open",
// [测试] 构建生产包(测试接口) -> 终端显示预览二维码。(等同 `build` 生产包后,点击微信开发工具的『预览』按钮)
"build:mp-weixin:preview:test": "uni build -p mp-weixin --mode test -- --preview",
// [测试] 构建生产包(生产接口) -> 上传代码到微信控制台作为开发版本 -> 终端显示预览二维码
"build:mp-weixin:upload": "uni build -p mp-weixin -- --upload",
// [上线] 更新 package.json 版本号,创建 git commit 和 tag -> 构建生产包(生产接口) -> 上传代码到微信控制台作为开发版本 -> 终端显示预览二维码
"build:mp-weixin:release": "uni build -p mp-weixin -- --bump --upload"
}
}目前我只测试了微信小程序的,其他平台因为需要开发账号,所以还没测试😬。如果有问题欢迎反馈。
| 平台 | 依赖 CI SDK 包名 | SDK 文档 |
|---|---|---|
mp-weixin(微信) |
miniprogram-ci |
查看 |
mp-alipay(阿里) |
minidev |
查看 |
mp-baidu(百度) |
swan-toolkit |
查看 |
mp-jd(京东) |
jd-miniprogram-ci |
查看 |
mp-toutiao(字节抖音) |
tt-ide-cli |
查看 |
按需安装目标平台 CI SDK:
pnpm add -D miniprogram-ci # 微信
pnpm add -D minidev # 支付宝
pnpm add -D swan-toolkit # 百度
pnpm add -D jd-miniprogram-ci # 京东
pnpm add -D tt-ide-cli # 抖音两种使用方式均支持以下操作:
| 操作 | 说明 |
|---|---|
--open |
打开开发者工具并打开项目 |
--preview |
上传开发版并生成预览二维码(等同于点击微信开发者工具中的“预览”按钮) |
--upload |
上传体验版并生成预览二维码 (等同于点击微信开发者工具中的“上传”按钮) |
--bump |
在执行 CI 操作前调用 bumpp 交互式的更新版本号 -> 创建 git commit 和 tag -> git push(适用于发布生产版本) |
--open、--preview、--upload 可以组合使用;组合时执行顺序固定为 open -> preview -> upload,不受命令行书写顺序影响。
CLI 的 minici.config.ts 和 Vite 插件的 uniMiniCI(options) 使用同一套配置结构MiniCIConfig:
| 字段 | 类型 | 说明 |
|---|---|---|
version |
string |
发布版本号(一般不建议配置),不定义时默认读取 package.json 中的 version。 如果配置了 --bump, 这个配置将不再生效 |
desc |
string | (context: MiniCIDescContext) => string | Promise<string> |
发布描述,--upload 时使用。不定义时默认取 package.json 中的 description;如果想每次 upload 时自定义,可以参考 Tip |
projectPath |
string |
构建产物目录,支持相对路径。正常不需要定义,内部自动判断 |
hooks |
MiniCIHooks |
完成和错误 hook。支持 onPreviewComplete、onUploadComplete、onError |
qrcodePath |
{preview?: string, upload: string} |
二维码图片保存路径, 可选 |
bumpOptions |
VersionBumpOptions | ((ctx: BumpOptionsContext) => VersionBumpOptions | Promise<VersionBumpOptions>) |
bumpp 程序化 API 参数。mini-ci 默认 commit 为 true、tag/push 为 false,可在此显式覆盖 |
mp-weixin |
WeappConfig |
微信小程序平台配置 |
mp-alipay |
AlipayConfig |
支付宝小程序平台配置 |
mp-baidu |
SwanConfig |
百度小程序平台配置 |
mp-jd |
JdConfig |
京东小程序平台配置 |
mp-toutiao |
TTConfig |
抖音小程序平台配置 |
bumpOptions 复用 bumpp 的 VersionBumpOptions。文档只列出常用字段:
| 字段 | 说明 |
|---|---|
release |
发布类型或明确版本号,例如 patch、minor、major、1.2.3 |
commit |
是否创建 git commit。 默认 true |
tag |
是否创建 git tag。默认 false |
push |
是否推送 commit 和 tag。 默认 false |
confirm |
是否让用户执行确认提示,默认是 true. 如果需要适用 CI/CD 等自动化场景,建议设置为 false |
各平台配置字段的详细说明见对应使用文档。
pnpm add -D vite-plugin-uni-mini-ci在 vite.config.ts 中注册插件:
import { defineConfig } from "vite";
import uni from "@dcloudio/vite-plugin-uni";
import { uniMiniCI } from "vite-plugin-uni-mini-ci";
export default defineConfig({
plugins: [
uni(),
uniMiniCI({
desc: ({ platform, version }) => `${platform} v${version} 自动构建`,
"mp-weixin": {
// 如果只想 --open 操作,可以不配置 "mp-weixin"
appid: "wx1234567890abcdef",
privateKeyPath: "./key/private.key",
robot: 1,
},
}),
],
});通过 -- 向插件透传操作参数,构建完成后自动执行:
uni build -p mp-weixin -- --upload
uni build -p mp-weixin -- --preview
uni build -p mp-weixin -- --preview --upload
uni -p mp-weixin -- --open!
-- --upload开头的--是必须的,用来结束 uni 自身参数,后续参数由插件解析(因为 uni 命令不支持新增命令参数,所以只能出此下策)。
uni dev 场景支持 --open 和 --preview,不支持 --upload。
详细用法、构建模式差异 → docs/vite-plugin.md
pnpm add -D uni-mini-ci-cli在项目根目录创建 minici.config.ts:
import { defineConfig } from "uni-mini-ci-cli";
export default defineConfig({
desc: ({ platform, version }) => `${platform} v${version} 自动构建`,
hooks: {
async onPreviewComplete(result) {
console.log("preview 完成", result.success, result.data.qrCodeLocalPath);
},
async onUploadComplete(result) {
console.log("upload 完成", result.success, result.data.version);
},
async onError(result) {
console.error("CI 错误", result.operation, result.error.message);
},
},
// bumpp 配置(可选):版本更新相关
bumpOptions: {
commit: true,
tag: true,
push: false,
},
"mp-weixin": {
appid: "wx1234567890abcdef",
privateKeyPath: "./key/private.key",
robot: 1,
},
});构建后执行 CI 操作:
minici --upload --platform mp-weixin
minici --preview --platform mp-weixin
minici --open --platform mp-weixin --dev # 开发环境下,需要显示的定义 --dev, 否则会从 dist/build/mp-weixin 读取产物。
minici --open --preview --upload --platform mp-weixin注意,使用 cli,如果你想开发时直接打开开发工具 "dev:mp-weixin": "uni -p mp-weixin && minici --open --platform mp-weixin",, --open 并不会生效,因为 uni dev 会启动一个持续监听的本地开发服务器,导致命令不会结束,无法运行 && 后续的 minici 命令。如果需要这样使用,建议让 AI 找找 hack 方案,或者直接使用 Vite 插件版本。
常用 script 示例:
{
"scripts": {
// [开发] 运行开发模式 -> 自动打开微信开发者工具并打开项目
"dev:mp-weixin": "uni dev -p mp-weixin -- --open",
// [测试] 构建生产包(测试接口) -> 终端显示预览二维码。(等同 `build` 生产包后,点击微信开发工具的『预览』按钮)
"build:mp-weixin:preview:test": "uni build -p mp-weixin --mode test -- --preview",
// [测试] 构建生产包(生产接口) -> 上传代码到微信控制台作为开发版本 -> 终端显示预览二维码
"build:mp-weixin:upload": "uni build -p mp-weixin -- --upload",
// [上线] 更新 package.json 版本号,创建 git commit 和 tag -> 构建生产包(生产接口) -> 上传代码到微信控制台作为开发版本 -> 终端显示预览二维码
"build:mp-weixin:release": "uni build -p mp-weixin -- --upload --bump"
}
}// vite.config.ts
export default defineConfig({
plugins: [
uniMiniCI({
...
bumpOptions: {
commit: true,
tag: true,
push: true,
},
}),
],
});desc 支持函数形式, 如下面的配置支持让用户手动输入,部分 script 命令时又可自动生成
import readline from "node:readline/promises";
import process from "node:process";
export default defineConfig({
plugins: [
uni(),
uniMiniCI({
desc: getDesc,
}),
],
});
async function getDesc() {
// 当前执行的 npm script
const npmScript = process.env.npm_lifecycle_event;
// 只有 npm 命令以 :upload:release 结尾才会询问用户,填写更新备注
if (npmScript?.endsWith(":upload:release")) {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const desc = await rl.question("请填写更新备注(如不填写,默认:优化体验,修复缺陷):");
rl.close();
return desc;
}
if (npmScript?.endsWith(":test")) return "优化体验,修复缺陷 [测试环境接口]";
return "优化体验,修复缺陷";
}也可以在代码中调用:
import { runMiniCIWithConfig } from "uni-mini-ci-core";
// 直接传入配置
await runMiniCIWithConfig({
args: {
operation: "upload",
platform: "mp-weixin",
projectPath: "dist/build/mp-weixin",
},
cwd: process.cwd(),
config: {
version: "1.0.0",
"mp-weixin": {
appid: "wx1234567890abcdef",
privateKeyPath: "key/private.key",
},
},
});{
"mp-weixin": {
appid: "wx1234567890abcdef", // 必填
privateKeyPath: "key/private.key", // 必填,CI 密钥文件路径
robot: 1, // 机器人编号 1-30
type: "miniProgram", // 项目类型
ignores: ["node_modules/**"], // 上传排除目录
setting: {}, // 编译设置
devToolsInstallPath: "", // 开发者工具安装路径
}
}{
"mp-alipay": {
appid: "2021001100000001", // 必填
toolId: "tool-id-xxx", // 必填
privateKeyPath: "key/alipay.key", // 私钥文件路径(二选一)
privateKey: "-----BEGIN...", // 私钥文本(二选一)
clientType: "alipay", // 上传终端类型
deleteVersion: "0.0.1", // 上传时删除的旧版本
devToolsInstallPath: "", // 开发者工具安装路径
}
}{
"mp-baidu": {
token: "百度小程序鉴权 token", // 必填
minSwanVersion: "3.350.0", // 最低基础库版本
devToolsInstallPath: "", // 开发者工具安装路径
}
}{
"mp-jd": {
privateKey: "京东小程序密钥", // 必填
robot: 1, // 机器人编号
ignores: [], // 上传忽略规则
}
}{
"mp-toutiao": {
email: "dev@example.com", // 必填
password: "xxx", // 必填
setting: {
skipDomainCheck: false, // 是否跳过域名校验
},
}
}pnpm install
pnpm run test
pnpm run build本仓库为 monorepo,包含三个独立发布的 npm 包:
| 包名 | 说明 |
|---|---|
uni-mini-ci-cli |
CLI 命令 minici 和 defineConfig() |
vite-plugin-uni-mini-ci |
Vite 插件 uniMiniCI() |
uni-mini-ci-core |
共享运行时(内部依赖,通常不需要直接安装) |
uni-mini-ci-core 承载平台 CI 实现、配置归一化、公共类型和 runMiniCIWithConfig(),由 CLI 和 Vite 插件各自作为普通依赖引入,不需要手动安装。