Skip to content

Commit 0d23f8c

Browse files
committed
build: Refactor scripts to support multi-module log generation
1 parent c20fd4c commit 0d23f8c

File tree

5 files changed

+197
-23
lines changed

5 files changed

+197
-23
lines changed

Help.md

+29-13
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,37 @@ pnpm test core main
88
pnpm test -- -p core,main --coverage
99
```
1010

11-
12-
1311
# Release
1412

1513
## 版本发布
1614

17-
1. `pnpm changeset`
18-
2. `pnpm changeset:version`
19-
- 然后执行 `pnpm changelog` 打印版本日志
20-
3. 更改`change log`后, `git add & commit`
21-
4. `git push` 后触发 github release,自动发布
15+
```bash
16+
# 1. 创建变更集
17+
pnpm changeset
18+
19+
20+
# 2. 更新版本、编辑变更日志、读取和删除变更集的命令
21+
# 注: 该步骤放在本地手动操作
22+
pnpm changeset:version
23+
24+
25+
# 3. 生成日志记录
26+
pnpm changelog core cli
27+
# 查看日志记录
28+
pnpm changelog
29+
30+
31+
# 4. 提交 commit
32+
git add .
33+
git commit -m 'Version Packages'
2234

2335

36+
# 5. 提交远程仓库并发布 (触发 github-action 自动发布)
37+
git push
38+
```
39+
2440
## 语义化版本
41+
2542
严格遵循 [semver](https://semver.org/) 规范。
2643

2744
```
@@ -31,24 +48,23 @@ pnpm test -- -p core,main --coverage
3148
- `Major` - 主版本号:当你做了不兼容的 API 修改
3249
- `Minor` - 次版本号:当你做了向下兼容的功能性新增
3350
- `Patch` - 修订号:当你做了向下兼容的问题修正
34-
先行版本号及版本编译信息可以加到“主版本号.次版本号.修订号”的后面,作为延伸。
51+
先行版本号及版本编译信息可以加到“主版本号.次版本号.修订号”的后面,作为延伸。
3552

3653
> **Tag**
54+
>
3755
> - `alpha` - alpha 版本, 内部测试版,一般不向外部发布;
3856
> - `beta` - beta 版本, 测试版,该版本会一直加入新的功能;
39-
> - `rc` - rc 版本 (Release Candidate) 发行候选版本。不再加新功能,着重于除错。
57+
> - `rc` - rc 版本 (Release Candidate) 发行候选版本。不再加新功能,着重于除错。
4058
>
4159
> 优先层级:
4260
> 例如:1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0。
4361
44-
4562
## refs
46-
- [pnpm构建monorepo工程](https://github.com/astonishqft/pnpm-monorepo-demo)
63+
64+
- [pnpm 构建 monorepo 工程](https://github.com/astonishqft/pnpm-monorepo-demo)
4765
- [webpack5 的多页脚手架](https://github.com/kailong321200875/webpack-multi-page-cli)
4866
- [pnpm-workspaces-example & changeset](https://github.com/DavidWells/pnpm-workspaces-example/)
4967

50-
5168
# Todo
5269

53-
5470
# Help

scripts/changelog.js

+25-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
const simpleGit = require('simple-git')
22
const { promisify } = require('util')
33
const log = require('diy-log')
4+
const minimist = require('minimist')
5+
const { readPackageJson, readPackageFile, writePackageFile, updateChangelog } = require('./utils')
46

7+
const rawArgs = process.argv.slice(2)
8+
const args = minimist(rawArgs)
59
const git = simpleGit()
610

711
// 获取从特定 commit ID 开始的所有最新记录
@@ -62,10 +66,20 @@ function formatCommits(commits, filter = (commit) => commit) {
6266
})
6367
}
6468

69+
// 生成日志记录
70+
async function generateLogs(name, logs) {
71+
const pkg = await readPackageJson(name)
72+
const content = await readPackageFile(name)
73+
const result = updateChangelog(content, pkg.version, logs[name])
74+
await writePackageFile(name, result)
75+
76+
return result
77+
}
78+
6579
;(async () => {
6680
const moduleRegex = /^[a-z]{1,10}\(\w+\).*/i
6781
try {
68-
// const commits = await getCommitsSince('4ac1e7a')
82+
// const commits = await getCommitsSince('d9acb96')
6983
const commits = await getCommitsSinceLatestTag()
7084
const formattedCommits = formatCommits(commits, (commit) => {
7185
return moduleRegex.test(commit.message)
@@ -81,14 +95,22 @@ function formatCommits(commits, filter = (commit) => commit) {
8195
)
8296
return acc
8397
}, {})
98+
8499
console.log(
85100
'Commit messages:',
86101
formatCommits(commits).map((commit) => commit.message)
87102
)
103+
88104
Object.entries(formattedCommits).forEach(([key, value]) => {
89105
log.tag.warn('\n' + value.join('\n'), key)
90106
})
91-
} catch (error) {
92-
console.error('error:', error.message)
107+
108+
if (args._.length) {
109+
for (const name of args._) {
110+
await generateLogs(name, formattedCommits)
111+
}
112+
}
113+
} catch (err) {
114+
console.error('error:', err.message)
93115
}
94116
})()

scripts/config.js

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* 模块及对应路径
3+
*/
4+
const packagesMap = {
5+
core: 'packages/core',
6+
cli: 'packages/cli',
7+
main: 'packages/main',
8+
utils: 'packages/utils',
9+
renew: 'plugins/renew',
10+
}
11+
12+
/**
13+
* 版本 emoji 标识
14+
*/
15+
const semverSymbol = {
16+
Major: '🎉',
17+
Minor: '🚀',
18+
Patch: '🌟',
19+
}
20+
21+
/**
22+
* 显示的日志类型
23+
* // (revert: )?(feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip)
24+
*/
25+
const messagesType = ['feat', 'fix', 'perf', 'refactor', 'docs']
26+
27+
/**
28+
* changeset 默认变更日志 (待替换)
29+
*/
30+
const defaultChangeLog = `- update.`
31+
32+
module.exports = {
33+
packagesMap,
34+
semverSymbol,
35+
messagesType,
36+
defaultChangeLog,
37+
}

scripts/test.js

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
const minimist = require('minimist')
22
const rawArgs = process.argv.slice(2)
33
const args = minimist(rawArgs)
4-
const packagesMap = {
5-
core: 'packages/core',
6-
cli: 'packages/cli',
7-
main: 'packages/main',
8-
utils: 'packages/utils',
9-
renew: 'plugins/renew',
10-
}
4+
const { packagesMap } = require('./config')
115

126
let regex
137
if (args.p) {

scripts/utils.js

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
const fs = require('fs')
2+
const path = require('path')
3+
const { packagesMap, semverSymbol, messagesType, defaultChangeLog } = require('./config')
4+
5+
/**
6+
* 读取模块文件内容
7+
*
8+
* @param {string} name 模块名
9+
* @param {string} filename 文件名
10+
* @returns {Promise}
11+
*/
12+
function readPackageFile(name, filename) {
13+
return new Promise((resolve, reject) => {
14+
const filePath = path.resolve(__dirname, '../', packagesMap[name], filename || 'CHANGELOG.md')
15+
fs.readFile(filePath, 'utf8', (err, data) => {
16+
if (err) {
17+
reject(err)
18+
}
19+
resolve(data)
20+
})
21+
})
22+
}
23+
24+
/**
25+
* 写入模块文件内容
26+
*
27+
* @param {string} name 模块名
28+
* @param {string} filename 文件名
29+
* @returns {Promise}
30+
*/
31+
function writePackageFile(name, data, filename) {
32+
return new Promise((resolve, reject) => {
33+
fs.writeFile(
34+
path.resolve(__dirname, '../', packagesMap[name], filename || 'CHANGELOG.md'),
35+
data,
36+
(err) => {
37+
if (err) {
38+
reject(err)
39+
}
40+
resolve()
41+
}
42+
)
43+
})
44+
}
45+
46+
/**
47+
* 日志排序
48+
*
49+
* @param {Array.<string>} logs 日志列表
50+
* @returns {Array.<string>}
51+
*/
52+
function sortLogsByType(logs) {
53+
const msgRegex = new RegExp(`- (${messagesType.join('|')}):[\\s\\S]+`)
54+
return logs
55+
.reduce((acc, cur) => {
56+
const type = cur.match(msgRegex)?.[1]
57+
const index = messagesType.indexOf(type)
58+
if (index > -1) {
59+
acc[index].push(cur)
60+
}
61+
return acc
62+
}, messagesType.map(() => []).concat([[]]))
63+
.reduce((acc, cur) => acc.concat(cur), [])
64+
}
65+
66+
/**
67+
* 更新日志内容
68+
*
69+
* @param {string} content 日志内容
70+
* @param {string} version 版本号
71+
* @param {Array.<string>} logs 日志列表
72+
* @returns {Promise}
73+
*/
74+
function updateChangelog(content, version, logs) {
75+
const [v1, v2, v3] = version.split('.')
76+
const regex = new RegExp(`## ${v1}\\.${v2}\\.${v3}[\\s]*### (Patch|Minor|Major) Changes\\n`)
77+
logStr = sortLogsByType(logs).join('\n')
78+
79+
return content
80+
.replace(regex, (match, p1) => {
81+
// console.log('replace : ', match, p1)
82+
return match.replace('Changes', 'Changes ' + semverSymbol[p1])
83+
// return match + ' ' + semverSymbol[p1]
84+
})
85+
.replace(defaultChangeLog, logStr)
86+
}
87+
88+
/**
89+
* 读取JSON文件内容
90+
*
91+
* @param {string} name 模块名
92+
* @param {string} filename 文件名
93+
* @returns {Promise}
94+
*/
95+
function readPackageJson(name, filename) {
96+
return readPackageFile(name, filename || 'package.json').then((data) => JSON.parse(data))
97+
}
98+
99+
module.exports = {
100+
readPackageFile,
101+
writePackageFile,
102+
readPackageJson,
103+
updateChangelog,
104+
sortLogsByType,
105+
}

0 commit comments

Comments
 (0)