-
-
Notifications
You must be signed in to change notification settings - Fork 67
/
changelog-generate.ts
112 lines (89 loc) · 3.04 KB
/
changelog-generate.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import {
generateMarkDown,
getGitDiff,
loadChangelogConfig,
parseCommits,
syncGithubRelease,
} from 'changelogen'
import { exec } from 'node:child_process'
import { existsSync, promises as fsp } from 'node:fs'
import { version } from './lerna.json'
async function execPromise(command: string): Promise<{ stdout: string; stderr: string }> {
return await new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
if (error) {
console.error(`🔴 [cli](${command}) Execution failed - ${error.message}.`)
reject(error)
} else {
resolve({ stdout, stderr })
}
})
})
}
export async function checkConfig() {
const config = await loadChangelogConfig(process.cwd())
if (!config.output) {
throw new Error('No output specified in changelog config')
}
if (!config.tokens.github) {
throw new Error('No GitHub token specified in changelog config')
}
console.log('Changelogen config is valid')
}
export async function updateChangelog() {
await checkConfig()
// const { stdout: penultimateTag } = await execPromise("git tag --sort=-v:refname | sed -n '2p'")
const { stdout: previousTag } = await execPromise("git tag --sort=-v:refname | sed -n '1p'")
const previousTagTrimed = previousTag.trim()
const newTag = `v${version.trim()}`
await execPromise(`git tag ${newTag}`)
await execPromise(`git push origin ${newTag}`)
console.log('Tag pushed to GitHub.')
console.log()
const config = await loadChangelogConfig(process.cwd(), {
from: previousTagTrimed,
to: newTag,
})
const rawCommits = await getGitDiff(previousTagTrimed, newTag)
const commits = parseCommits(rawCommits, config).filter((commit) => {
return (
config.types[commit.type] &&
!(commit.type === 'chore' && ['release'].includes(commit.scope) && !commit.isBreaking)
)
})
const newChangelog = await generateMarkDown(commits, config)
let changelogMD: string
if (typeof config.output === 'string' && existsSync(config.output)) {
changelogMD = await fsp.readFile(config.output, 'utf8')
} else {
changelogMD = '# Changelog\n\n'
}
const lastEntry = changelogMD.match(/^###?\s+.*$/m)
if (lastEntry) {
changelogMD =
changelogMD.slice(0, lastEntry.index) +
newChangelog +
'\n\n' +
changelogMD.slice(lastEntry.index)
} else {
changelogMD += '\n' + newChangelog + '\n\n'
}
await fsp.writeFile(config.output as string, changelogMD)
await execPromise('pnpm format')
const changelogWithoutTitle = newChangelog.split('\n').slice(2).join('\n')
console.log(changelogWithoutTitle)
await execPromise(`git add -u`)
await execPromise(`git commit -m "chore(release): bump version to ${newTag}"`)
await execPromise(`git push origin HEAD`)
try {
const response = await syncGithubRelease(config, {
version: newTag.replace('v', ''),
body: changelogWithoutTitle,
})
console.log()
console.log('Release pushed to GitHub.', response)
console.log()
} catch (error: any) {
console.error('error', error)
}
}