| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- /**
- * bump-version.js — 构建时自动递增 package.json 版本号
- *
- * 逻辑:
- * 检查自上次构建以来的 git commit,若仅包含工程化变更(chore/build/ci/auto bump)或没有新 commit,
- * 则跳过版本号递增,保持当前版本号。
- * 否则按指定类型(默认 patch)递增版本号。
- *
- * 用法: node scripts/bump-version.js [patch|minor|major]
- * 默认 patch,每次 npm run build 前自动执行
- */
- const fs = require('fs');
- const path = require('path');
- const { execSync } = require('child_process');
- const pkgPath = path.resolve(__dirname, '..', 'package.json');
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
- const rootDir = path.resolve(__dirname, '..');
- const lastBuildFile = path.join(rootDir, '.last_build_commit');
- // ----- 判断是否有有效变更 -----
- let hasMeaningfulChanges = true;
- try {
- let fromHash = '';
- try {
- fromHash = fs.readFileSync(lastBuildFile, 'utf-8').trim();
- } catch {
- fromHash = '';
- }
- if (fromHash) {
- const range = `${fromHash}..HEAD`;
- const log = execSync(
- `git log --no-merges --pretty=format:"%s" ${range}`,
- { cwd: rootDir, encoding: 'utf-8' }
- ).trim();
- const commits = log ? log.split('\n').filter(Boolean) : [];
- if (commits.length === 0) {
- hasMeaningfulChanges = false;
- console.log('[bump-version] 没有新 commit,跳过版本号递增');
- } else {
- const allChore = commits.every(msg => {
- const s = msg.toLowerCase().trim();
- return (
- s.startsWith('chore:') ||
- s.startsWith('chore(') ||
- s.startsWith('build:') ||
- s.startsWith('build(') ||
- s.startsWith('ci:') ||
- s.startsWith('ci(') ||
- /auto ?bump/i.test(s) ||
- /工程化/.test(s) ||
- /skip ?ci/i.test(s)
- );
- });
- if (allChore) {
- hasMeaningfulChanges = false;
- console.log(`[bump-version] 仅有工程化变更(${commits.length} 条),跳过版本号递增`);
- } else {
- console.log(`[bump-version] 检测到 ${commits.length} 条提交,其中 ${commits.filter(msg => {
- const s = msg.toLowerCase().trim();
- return !(s.startsWith('chore:') || s.startsWith('chore(') ||
- s.startsWith('build:') || s.startsWith('build(') ||
- s.startsWith('ci:') || s.startsWith('ci(') ||
- /auto ?bump/i.test(s) || /工程化/.test(s) || /skip ?ci/i.test(s));
- }).length} 条有效变更`);
- }
- }
- } else {
- console.log('[bump-version] 首次构建,正常递增版本号');
- }
- } catch (e) {
- console.warn(`[bump-version] 检查变更失败(${e.message}),回退到默认递增`);
- hasMeaningfulChanges = true;
- }
- // ----- 版本号递增 -----
- if (!hasMeaningfulChanges) {
- console.log(`[bump-version] 保持版本号 ${pkg.version}`);
- process.exit(0);
- }
- const current = pkg.version;
- const parts = current.split('.').map(Number);
- if (parts.length !== 3 || parts.some(isNaN)) {
- console.error(`[bump-version] 无效版本号: ${current}`);
- process.exit(1);
- }
- const type = process.argv[2] || 'patch';
- switch (type) {
- case 'major':
- parts[0] += 1;
- parts[1] = 0;
- parts[2] = 0;
- break;
- case 'minor':
- parts[1] += 1;
- parts[2] = 0;
- break;
- case 'patch':
- default:
- parts[2] += 1;
- break;
- }
- const next = parts.join('.');
- pkg.version = next;
- fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
- console.log(`[bump-version] ${current} → ${next}`);
|