#!/usr/bin/env node import { execSync } from 'child_process' import inquirer from 'inquirer' import fs from 'fs' function run(cmd, opts = {}) { execSync(cmd, { stdio: 'inherit', ...opts }) } function runOut(cmd) { return execSync(cmd, { encoding: 'utf8' }).trim() } function getVersion() { return JSON.parse(fs.readFileSync('package.json', 'utf8')).version } function isGitClean() { return runOut('git status --porcelain') === '' } async function main() { console.log('🚀 开始发布流程...') // 0. 保护:工作区必须干净(否则 npm version 会报错) if (!isGitClean()) { console.error('❌ Git 工作区有未提交的改动,请先提交/暂存后再发版!') process.exit(1) } // 1) 选择版本类型(默认 patch) const { versionType } = await inquirer.prompt([ { type: 'list', name: 'versionType', message: '请选择版本类型:', default: 'patch', choices: [ { name: '补丁版本 (patch)', value: 'patch' }, { name: '小版本 (minor)', value: 'minor' }, { name: '大版本 (major)', value: 'major' }, ], }, ]) // 2) 选择日志生成模式(默认增量) const { changelogMode } = await inquirer.prompt([ { type: 'list', name: 'changelogMode', message: '请选择 changelog 生成模式:', default: 'incremental', choices: [ { name: '增量生成(只追加本次更新的内容)', value: 'incremental' }, { name: '全量生成(会覆盖整个文件)', value: 'full' }, ], }, ]) // 3) 先只更新 package.json 版本,不提交、不打 tag(确保 changelog 标题用到新版本) run(`npm version ${versionType} --no-git-tag-version`) const version = getVersion() // 4) 生成 changelog(增量/全量) console.log('📝 正在生成 changelog...') // 确保文件存在,避免第一次运行时 in-place 报错 if (!fs.existsSync('CHANGELOG.md')) fs.writeFileSync('CHANGELOG.md', '') if (changelogMode === 'full') { run('npx conventional-changelog -p angular -i CHANGELOG.md -s -r 0') } else { run('npx conventional-changelog -p angular -i CHANGELOG.md -s') } // 5) 一次性提交:把 package.json + CHANGELOG.md 一起提交,并打 tag(保证日志与版本同步) run('git add package.json package-lock.json 2> NUL || :') run('git add CHANGELOG.md') run(`git commit -m "chore(release): v${version}"`) run(`git tag v${version}`) // 6) 推送代码 & tag run('git push') run('git push --tags') // 7) 提示 console.log('\x1b[36m=========================\x1b[0m') console.log('\x1b[32m🎉 发布成功!\x1b[0m') console.log(`\x1b[33m📦 版本号:v${version}\x1b[0m`) console.log('\x1b[35m⚙️ 部署:\x1b[0m') console.log('\x1b[34m * 测试环境:npm run deploy:test\x1b[0m') console.log('\x1b[34m * 开发环境:npm run build:dev\x1b[0m') console.log('\x1b[34m * 生产环境:npm run build\x1b[0m') console.log('\x1b[36m=========================\x1b[0m') } main()