新增 微信小程序自动化上传功能

This commit is contained in:
yuantao
2026-01-19 11:46:56 +08:00
parent 9d1bb3c87d
commit c85fe69b3b
3 changed files with 255 additions and 1 deletions

2
package-lock.json generated
View File

@@ -7,7 +7,7 @@
"dependencies": { "dependencies": {
"dayjs": "*", "dayjs": "*",
"dotenv": "^17.2.2", "dotenv": "^17.2.2",
"uniapp-error-monitor": "^1.0.0", "uniapp-error-monitor": "*",
"vue": "^3.5.21" "vue": "^3.5.21"
} }
}, },

View File

@@ -1,4 +1,7 @@
{ {
"scripts": {
"upload:weapp": "node scripts/upload-weapp.js"
},
"dependencies": { "dependencies": {
"dayjs": "*", "dayjs": "*",
"dotenv": "^17.2.2", "dotenv": "^17.2.2",

251
scripts/upload-weapp.js Normal file
View File

@@ -0,0 +1,251 @@
const fs = require('fs')
const path = require('path')
const { execSync } = require('child_process')
/**
* 微信小程序自动化上传脚本
* 功能:
* 1. 版本号自增
* 2. 附加git日志为上传备注
* 3. 调用微信开发者工具CLI上传
*/
// 配置
const CONFIG = {
// 微信开发者工具CLI路径需要根据实际情况修改
// macOS: '/Applications/wechatwebdevtools.app/Contents/MacOS/cli'
// Windows: 'C:\\Program Files (x86)\\Tencent\\微信web开发者工具\\cli.bat'
cliPath: process.env.WECHAT_CLI_PATH || 'C:\\Program Files (x86)\\Tencent\\微信web开发者工具\\cli.bat',
// 源项目路径
sourcePath: path.resolve(__dirname, '..'),
// 编译后的项目路径(用于上传)
projectPath: path.resolve(__dirname, '..', 'unpackage', 'dist', 'build', 'mp-weixin'),
// manifest.json路径
manifestPath: path.resolve(__dirname, '..', 'manifest.json'),
}
/**
* 读取manifest.json
*/
function readManifest() {
try {
const content = fs.readFileSync(CONFIG.manifestPath, 'utf-8')
return JSON.parse(content)
} catch (error) {
console.error('读取manifest.json失败:', error.message)
process.exit(1)
}
}
/**
* 写入manifest.json
*/
function writeManifest(manifest) {
try {
fs.writeFileSync(CONFIG.manifestPath, JSON.stringify(manifest, null, 4), 'utf-8')
} catch (error) {
console.error('写入manifest.json失败:', error.message)
process.exit(1)
}
}
/**
* 自增版本号
* @param {string} version - 当前版本号 (例如: 1.0.0)
* @returns {string} - 自增后的版本号
*/
function incrementVersion(version) {
const parts = version.split('.').map(Number)
parts[2]++ // 自增最后一位
return parts.join('.')
}
/**
* 自增versionCode
* @param {number} code - 当前versionCode
* @returns {number} - 自增后的versionCode
*/
function incrementVersionCode(code) {
return parseInt(code) + 1
}
/**
* 获取最新的git提交日志
* @param {number} count - 获取最近几条提交默认5条
* @returns {string} - git日志字符串
*/
function getGitLog(count = 2) {
try {
// 获取最近N条提交的简短日志使用相对时间
const log = execSync(`git log -${count} --pretty=format:"%s (%an, %ar)"`, {
encoding: 'utf-8',
cwd: CONFIG.projectPath,
})
return log.trim()
} catch (error) {
console.warn('获取git日志失败:', error.message)
return '自动化上传'
}
}
/**
* 将英文相对时间转换为中文
* @param {string} timeStr - 英文时间字符串
* @returns {string} - 中文时间字符串
*/
function translateTimeToChinese(timeStr) {
const translations = [
['seconds', '秒'],
['minutes', '分钟'],
['hours', '小时'],
['days', '天'],
['weeks', '周'],
['months', '月'],
['years', '年'],
['second', '秒'],
['minute', '分钟'],
['hour', '小时'],
['day', '天'],
['week', '周'],
['month', '月'],
['year', '年'],
['ago', '前'],
]
let result = timeStr
for (const [en, zh] of translations) {
result = result.replace(new RegExp(en, 'g'), zh)
}
// 去除时间单位和"前"之间的多余空格
result = result.replace(/\s+前/g, '前')
return result
}
/**
* 获取当前git分支名
* @returns {string} - 分支名
*/
function getGitBranch() {
try {
const branch = execSync('git rev-parse --abbrev-ref HEAD', {
encoding: 'utf-8',
cwd: CONFIG.projectPath,
})
return branch.trim()
} catch (error) {
console.warn('获取git分支名失败:', error.message)
return 'unknown'
}
}
/**
* 获取当前git提交的hash
* @returns {string} - 提交hash
*/
function getGitCommitHash() {
try {
const hash = execSync('git rev-parse --short HEAD', {
encoding: 'utf-8',
cwd: CONFIG.projectPath,
})
return hash.trim()
} catch (error) {
console.warn('获取git提交hash失败:', error.message)
return 'unknown'
}
}
/**
* 调用微信开发者工具CLI上传
* @param {string} version - 版本号
* @param {string} desc - 上传描述
*/
function uploadToWechat(version, desc) {
try {
console.log('开始上传微信小程序...')
console.log('版本号:', version)
console.log('描述:', desc)
console.log('CLI路径:', CONFIG.cliPath)
console.log('项目路径:', CONFIG.projectPath)
// 将换行符替换为空格,避免命令行参数解析问题
const safeDesc = desc.replace(/\n/g, ' ').replace(/\r/g, ' ')
const command = `"${CONFIG.cliPath}" upload --project "${CONFIG.projectPath}" --version ${version} --desc "${safeDesc}"`
console.log('执行命令:', command)
execSync(command, { stdio: 'inherit' })
console.log('上传成功!')
} catch (error) {
console.error('上传失败:', error.message)
process.exit(1)
}
}
/**
* 主函数
*/
function main() {
console.log('=== 微信小程序自动化上传 ===\n')
// 读取manifest.json
console.log('1. 读取manifest.json...')
const manifest = readManifest()
console.log(' 当前版本:', manifest.versionName)
console.log(' 当前版本号:', manifest.versionCode)
// 自增版本号
console.log('\n2. 自增版本号...')
const newVersion = incrementVersion(manifest.versionName)
const newVersionCode = incrementVersionCode(manifest.versionCode)
console.log(' 新版本:', newVersion)
console.log(' 新版本号:', newVersionCode)
// 获取git信息
console.log('\n3. 获取git信息...')
const branch = getGitBranch()
const commitHash = getGitCommitHash()
const gitLog = getGitLog()
console.log(' 分支:', branch)
console.log(' 提交:', commitHash)
// 构建上传描述
const translatedLog = translateTimeToChinese(gitLog)
const logItems = translatedLog.split('\n')
const numberedLogs = logItems.map((item, index) => `(${index + 1}) ${item}`)
const uploadDesc = `[${branch}] ${numberedLogs.join('')}`
console.log('\n上传描述:')
console.log('---')
console.log(uploadDesc)
console.log('---')
// 更新manifest.json
console.log('\n4. 更新manifest.json...')
manifest.versionName = newVersion
manifest.versionCode = String(newVersionCode)
writeManifest(manifest)
console.log(' 已更新版本号')
// 检查编译目录是否存在
console.log('\n5. 检查编译目录...')
if (!fs.existsSync(CONFIG.projectPath)) {
console.error('错误: 编译目录不存在!')
console.error('请先使用 HBuilderX 编译项目')
console.error('编译目录:', CONFIG.projectPath)
process.exit(1)
}
console.log(' 编译目录存在')
// 上传到微信
console.log('\n6. 上传到微信...')
uploadToWechat(newVersion, uploadDesc)
console.log('\n=== 上传完成 ===')
console.log(`新版本: ${newVersion} (${newVersionCode})`)
console.log('请前往微信公众平台查看上传结果')
}
// 执行主函数
main()