
Research
/Security News
Chrome and Firefox Extensions Posing as Free VPNs Add Clipboard Stealers via Malicious Updates
Malicious Chrome and Firefox extensions posed as free VPNs while stealing clipboard data through later extension updates.
@wot-ui/ci
Advanced tools
@wot-ui/ci 是一个面向多平台小程序产物上传的 ESM 库,支持微信、支付宝、钉钉三端上传能力,并支持通过 JS/TS 配置文件读取环境变量。
# 推荐:项目内安装(devDependency)
pnpm add -D @wot-ui/ci
# 或
# npm i -D @wot-ui/ci
# yarn add -D @wot-ui/ci
全局安装后可直接使用 wotci 命令:
pnpm add -g @wot-ui/ci
# 或
# npm i -g @wot-ui/ci
# yarn global add @wot-ui/ci
在项目根目录准备配置文件(推荐 wotci.config.ts/js),然后执行:
# 直接运行(node_modules/.bin)
pnpm exec wotci --platform weixin
# 或
npx wotci --platform weixin
也可以把上传命令写进 package.json:
{
"scripts": {
"upload:weixin": "wotci -p weixin",
"upload:alipay": "wotci -p alipay",
"upload:dingtalk": "wotci -p dingtalk"
}
}
然后通过包管理器的 scripts 运行(npm run/pnpm/yarn 都会把 node_modules/.bin 加到 PATH 里):
https://docs.npmjs.com/cli/v9/commands/npm-run-script
与构建命令组合:
{
"scripts": {
"upload:mp-weixin": "uni build -p mp-weixin && wotci -p weixin",
"upload:mp-alipay": "uni build -p mp-alipay && wotci -p alipay",
"upload:mp-dingtalk": "uni build -p mp-dingtalk && wotci -p dingtalk"
}
}
wotci --platform weixin
wotci --platform alipay --config ./wotci.config.mjs
wotci --platform dd
推荐使用 JS 配置文件。默认搜索顺序如下:
为了兼容旧项目,配置中历史上使用的 dd 字段仍然可用,加载后会自动归一为 dingtalk 配置。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| projectPath | string | 是 | 微信小程序产物目录,例如 dist/build/mp-weixin |
| appid | string | 是 | 小程序/小游戏项目的 appid |
| privateKeyPath | string | 是 | 代码上传密钥文件路径(相对或绝对均可);密钥需在微信公众平台生成,并配置 IP 白名单 |
| type | string | 否 | 项目类型:miniProgram / miniGame / miniProgramPlugin / miniGamePlugin |
| ignores | string[] | 否 | 上传需要排除的目录/文件规则(glob 风格,行为以微信 CI 为准) |
| robot | number | 否 | 指定使用哪一个 ci 机器人,可选值:1 ~ 30 |
| setting | object | 否 | 上传编译设置(透传给 miniprogram-ci;常用字段见下表,更多字段以官方文档为准) |
微信 CI 文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html
setting 常用字段
| 字段 | 类型 | 说明 |
|---|---|---|
| useProjectConfig | boolean | 是否使用项目 project.config.json 中的设置 |
| es6 | boolean | 对应微信开发者工具「es6 转 es5」 |
| es7 | boolean | 对应微信开发者工具「增强编译」 |
| disableUseStrict | boolean | 「增强编译」开启时,是否禁用 JS 文件严格模式 |
| minifyJS | boolean | 上传时压缩 JS 代码 |
| minifyWXML | boolean | 上传时压缩 WXML 代码 |
| minifyWXSS | boolean | 上传时压缩 WXSS 代码 |
| minify | boolean | 上传时压缩所有代码(对应「上传时压缩代码」) |
| codeProtect | boolean | 上传时进行代码保护 |
| autoPrefixWXSS | boolean | 上传时样式自动补全 |
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| projectPath | string | 是 | 支付宝小程序产物目录,例如 dist/build/mp-alipay |
| appid | string | 是 | 支付宝小程序 appid |
| toolId | string | 是 | 支付宝开放平台工具 ID(在开放平台控制台的「工具」里创建/查看):https://open.alipay.com/dev/workspace/key-manage/tool |
| privateKey / privateKeyPath | string | 是(二选一) | 私钥文本内容或私钥文件路径;私钥可通过官方工具生成:https://opendocs.alipay.com/common/02kipl |
| clientType | string | 否 | 上传终端类型,默认 alipay(可选值见下表) |
| autoincrement | boolean | 否 | 版本号是否自动递增(默认开启);关闭后需要提供顶层 version,且版本号必须大于线上最新版本 |
支付宝小程序 CLI 文档:
clientType 可选值
| 值 | 含义 |
|---|---|
| alipay | 支付宝 |
| ampe | AMPE |
| amap | 高德 |
| genie | 天猫精灵 |
| alios | ALIOS |
| uc | UC |
| quark | 夸克 |
| koubei | 口碑 |
| alipayiot | IoT |
| cainiao | 菜鸟 |
| alihealth | 阿里健康 |
| health | 阿里医院 |
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| projectPath | string | 是 | 钉钉小程序产物目录,例如 dist/build/mp-dingtalk |
| appid | string | 是 | 钉钉开发者后台的 MiniAppId |
| token | string | 是 | 钉钉开发者后台的 API Token |
| projectType | string | 否 | 钉钉小程序应用类型(预留字段;当前上传实现未使用) |
| autoincrement | boolean | 否 | 版本号是否自动递增(默认开启) |
钉钉上传相关文档(Design CLI):https://github.com/open-dingtalk/dingtalk-design-cli
import { defineConfig } from '@wot-ui/ci'
export default defineConfig(({ env }) => ({
version: env.WOTCI_VERSION,
desc: env.WOTCI_DESC,
weixin: {
appid: env.WEIXIN_APPID!,
projectPath: env.WEIXIN_PROJECT_PATH || 'dist/build/mp-weixin',
privateKeyPath: env.WEIXIN_PRIVATE_KEY_PATH!,
robot: env.WEIXIN_ROBOT ? Number(env.WEIXIN_ROBOT) : 1,
setting: {
useProjectConfig: true,
},
},
alipay: {
appid: env.ALIPAY_APPID!,
toolId: env.ALIPAY_TOOL_ID!,
projectPath: env.ALIPAY_PROJECT_PATH || 'dist/build/mp-alipay',
privateKey: env.ALIPAY_PRIVATE_KEY,
privateKeyPath: env.ALIPAY_PRIVATE_KEY_PATH,
clientType: env.ALIPAY_CLIENT_TYPE,
autoincrement: env.ALIPAY_AUTOINCREMENT ? env.ALIPAY_AUTOINCREMENT === 'true' : undefined,
},
dingtalk: {
appid: env.DINGTALK_APPID!,
token: env.DINGTALK_TOKEN!,
projectPath: env.DINGTALK_PROJECT_PATH || 'dist/build/mp-dingtalk',
autoincrement: env.DINGTALK_AUTOINCREMENT ? env.DINGTALK_AUTOINCREMENT === 'true' : undefined,
},
}))
import { defineConfig } from '@wot-ui/ci'
export default defineConfig(({ env }) => ({
version: env.WOTCI_VERSION,
desc: env.WOTCI_DESC,
weixin: {
appid: env.WEIXIN_APPID,
projectPath: env.WEIXIN_PROJECT_PATH || 'dist/build/mp-weixin',
privateKeyPath: env.WEIXIN_PRIVATE_KEY_PATH,
robot: env.WEIXIN_ROBOT ? Number(env.WEIXIN_ROBOT) : 1,
setting: {
useProjectConfig: true,
},
},
alipay: {
appid: env.ALIPAY_APPID,
toolId: env.ALIPAY_TOOL_ID,
projectPath: env.ALIPAY_PROJECT_PATH || 'dist/build/mp-alipay',
privateKey: env.ALIPAY_PRIVATE_KEY,
privateKeyPath: env.ALIPAY_PRIVATE_KEY_PATH,
clientType: env.ALIPAY_CLIENT_TYPE,
autoincrement: env.ALIPAY_AUTOINCREMENT ? env.ALIPAY_AUTOINCREMENT === 'true' : undefined,
},
dingtalk: {
appid: env.DINGTALK_APPID,
token: env.DINGTALK_TOKEN,
projectPath: env.DINGTALK_PROJECT_PATH || 'dist/build/mp-dingtalk',
autoincrement: env.DINGTALK_AUTOINCREMENT ? env.DINGTALK_AUTOINCREMENT === 'true' : undefined,
},
}))
playground 中的 playground/wotci.config.ts 已经预留了微信、支付宝、钉钉三端配置,统一通过环境变量注入:
WOTCI_VERSION:上传版本号,未传时回退到 playground 的 package.json versionWOTCI_DESC:上传描述,未传时回退到 playground 的 package.json descriptionWEIXIN_APPIDWEIXIN_PRIVATE_KEY_PATHWEIXIN_PROJECT_PATHWEIXIN_ROBOTALIPAY_APPIDALIPAY_TOOL_IDALIPAY_PRIVATE_KEY 或 ALIPAY_PRIVATE_KEY_PATHALIPAY_PROJECT_PATHALIPAY_CLIENT_TYPEALIPAY_AUTOINCREMENTDINGTALK_APPIDDINGTALK_TOKENDINGTALK_PROJECT_PATHDINGTALK_AUTOINCREMENT本地示例命令:
WOTCI_VERSION=1.0.0 pnpm upload:playground:weixin
ALIPAY_PRIVATE_KEY="$(cat keys/alipay.private.key)" pnpm upload:playground:alipay
DINGTALK_APPID=xxx DINGTALK_TOKEN=xxx pnpm upload:playground:dingtalk
仓库内提供了可手动触发的工作流 upload-playground.yml。建议在 GitHub Secrets 中配置以下变量:
WEIXIN_APPIDWEIXIN_PRIVATE_KEYWEIXIN_ROBOTALIPAY_APPIDALIPAY_TOOL_IDALIPAY_PRIVATE_KEYALIPAY_CLIENT_TYPEALIPAY_AUTOINCREMENTDINGTALK_APPIDDINGTALK_TOKENDINGTALK_PROJECT_PATHDINGTALK_AUTOINCREMENT其中:
WEIXIN_PRIVATE_KEY 写入 playground/keys/weixin.private.key,再把路径注入 WEIXIN_PRIVATE_KEY_PATHALIPAY_PRIVATE_KEY 内容;如果你更想走文件,也可以改成 ALIPAY_PRIVATE_KEY_PATHdist/build/mp-dingtalk,如果你的产物目录不同,直接在 Secret DINGTALK_PROJECT_PATH 里覆盖import wotci, { loadConfig } from '@wot-ui/ci'
const loaded = await loadConfig()
const result = await wotci.uploadPlatform('weixin', loaded.config, { cwd: loaded.cwd })
console.log(result.version)
console.log(result.message)
库层不再调用 process.exit。配置错误会抛出 ConfigError,上传过程错误会抛出 UploadError,由调用方决定日志输出和退出策略。
MIT
FAQs
小程序多平台 CI 上传工具,支持 JS/TS 配置文件与环境变量注入
We found that @wot-ui/ci demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Malicious Chrome and Firefox extensions posed as free VPNs while stealing clipboard data through later extension updates.

Research
/Security News
Miasma Mini Shai-Hulud hits @immobiliarelabs Backstage plugins, targeting GitLab and LDAP auth packages on npm.

Security News
Rolldown paused Rust React Compiler integration after a 5MB binary size increase raised concerns about shipping React-specific code to all Vite users.