123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- import inquirer from 'inquirer'
- import { execSync } from 'child_process'
- import fs from 'fs'
- // 运行命令
- const run = (cmd) => execSync(cmd, { stdio: 'inherit' })
- // Git 工作区是否干净
- const isGitClean = () => {
- const status = execSync('git status --porcelain').toString().trim()
- return status === ''
- }
- // 获取最新 tag
- const getLatestTag = () => {
- try {
- return execSync('git describe --tags --abbrev=0').toString().trim()
- } catch {
- return ''
- }
- }
- // 获取最新 tag 到现在的提交记录
- const getCommitsSinceTag = (tag) => {
- try {
- const range = tag ? `${tag}..HEAD` : 'HEAD'
- return execSync(`git log ${range} --pretty=format:%s`).toString().trim()
- } catch {
- return ''
- }
- }
- // 检查是否有符合 Angular 规范的提交
- const hasConventionalCommits = (log) => {
- return /^(feat|fix|docs|style|refactor|perf|test|chore)(\(.+\))?:/m.test(log)
- }
- // 1. 检查 git 工作区
- if (!isGitClean()) {
- console.error('❌ Git 工作区有未提交的改动,请先提交后再发版!')
- process.exit(1)
- }
- // 2. 检查提交记录
- const latestTag = getLatestTag()
- const commitLog = getCommitsSinceTag(latestTag)
- if (!hasConventionalCommits(commitLog)) {
- console.error('⚠️ 没有检测到符合 Angular 提交规范的提交,跳过 changelog 生成!')
- process.exit(1)
- }
- // 3. 选择发布模式
- const { mode } = await inquirer.prompt([
- {
- type: 'list',
- name: 'mode',
- message: '请选择发布模式:',
- choices: [
- { name: '正式发版(更新版本号 + 生成 tag + 推送)', value: 'release' },
- { name: '自测模式(仅生成 changelog,不推送)', value: 'test' },
- ],
- },
- ])
- // 4. 选择 changelog 生成方式
- const { changelogMode } = await inquirer.prompt([
- {
- type: 'list',
- name: 'changelogMode',
- message: '请选择 changelog 生成方式:',
- choices: [
- { name: '增量追加日志(推荐)', value: 'incremental' },
- { name: '全量生成日志(会覆盖原文件)', value: 'all' },
- ],
- },
- ])
- // 5. 生成 changelog
- if (changelogMode === 'all') {
- run('npx conventional-changelog -p angular -i CHANGELOG.md -s -r 0')
- } else {
- run('npx conventional-changelog -p angular -i CHANGELOG.md -s')
- }
- // 6. 检查 changelog 是否更新
- const changelogContent = fs.readFileSync('CHANGELOG.md', 'utf8')
- if (!changelogContent.includes(new Date().getFullYear().toString())) {
- console.error('⚠️ changelog 没有生成新的内容,请检查提交记录!')
- process.exit(1)
- }
- // 7. 如果是正式模式,选择版本号递增类型
- if (mode === 'release') {
- const { versionType } = await inquirer.prompt([
- {
- type: 'list',
- name: 'versionType',
- message: '请选择版本号递增类型:',
- choices: [
- { name: '补丁版本(patch)', value: 'patch' },
- { name: '小版本(minor)', value: 'minor' },
- { name: '大版本(major)', value: 'major' },
- ],
- },
- ])
- // 更新版本号 & 提交 tag
- run(`npm version ${versionType} -m "release: v%s"`)
- // 推送代码 & tag
- run('git push && git push --tags')
- console.log('✅ 正式发版完成!')
- } else {
- console.log('✅ 自测模式完成(未生成 tag / 未推送)')
- }
|