forked from payloadcms/payload
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathupdate-changelog.ts
executable file
·133 lines (118 loc) · 3.37 KB
/
update-changelog.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import fse, { createWriteStream, createReadStream } from 'fs-extra'
import { ExecSyncOptions, execSync } from 'child_process'
import chalk from 'chalk'
import path from 'path'
import prompts from 'prompts'
import minimist from 'minimist'
import chalkTemplate from 'chalk-template'
import { PackageDetails, getPackageDetails, showPackageDetails } from './lib/getPackageDetails'
import semver from 'semver'
import addStream from 'add-stream'
import tempfile from 'tempfile'
import concatSream from 'concat-stream'
import getStream from 'get-stream'
import conventionalChangelogCore, {
Options,
Context,
GitRawCommitsOptions,
ParserOptions,
WriterOptions,
} from 'conventional-changelog-core'
import conventionalChangelog, { Options as ChangelogOptions } from 'conventional-changelog'
const execOpts: ExecSyncOptions = { stdio: 'inherit' }
const args = minimist(process.argv.slice(2))
async function main() {
const { tag = 'latest', bump = 'patch' } = args
const packageName = args._[0]
const packageDetails = await getPackageDetails()
showPackageDetails(packageDetails)
let pkg: PackageDetails | undefined
if (packageName) {
pkg = packageDetails.find((p) => p.shortName === packageName)
if (!pkg) {
abort(`Package not found: ${packageName}`)
}
} else {
;({ pkg } = (await prompts({
type: 'select',
name: 'pkg',
message: 'Select package to update changelog',
choices: packageDetails.map((p) => {
const title = p?.newCommits ? chalk.bold.green(p?.shortName) : p?.shortName
return {
title,
value: p,
}
}),
})) as { pkg: PackageDetails })
}
console.log({ pkg })
if (!pkg) {
abort()
process.exit(1)
}
// Prefix to find prev tag
const tagPrefix = pkg.shortName === 'payload' ? 'v' : pkg.prevGitTag.split('/')[0] + '/'
const generateChangelog = await confirm('Generate changelog?')
if (!generateChangelog) {
abort()
}
const nextReleaseVersion = semver.inc(pkg.version, bump) as string
const changelogStream = conventionalChangelog(
{
preset: 'conventionalcommits',
append: true, // Does this work?
// currentTag: pkg.prevGitTag, // The prefix is added automatically apparently?
tagPrefix,
pkg: {
path: `${pkg.packagePath}/package.json`,
},
},
{
version: nextReleaseVersion, // next release
},
{
path: 'packages',
// path: pkg.packagePath,
// from: pkg.prevGitTag,
// to: 'HEAD'
},
).on('error', (err) => {
console.error(err.stack)
console.error(err.toString())
process.exit(1)
})
const changelogFile = 'CHANGELOG.md'
const readStream = fse.createReadStream(changelogFile)
const tmp = tempfile()
changelogStream
.pipe(addStream(readStream))
.pipe(createWriteStream(tmp))
.on('finish', () => {
createReadStream(tmp).pipe(createWriteStream(changelogFile))
})
}
main().catch((error) => {
console.error(error)
process.exit(1)
})
async function abort(message = 'Abort', exitCode = 1) {
console.error(chalk.bold.red(`\n${message}\n`))
process.exit(exitCode)
}
async function confirm(message: string): Promise<boolean> {
const { confirm } = await prompts(
{
name: 'confirm',
initial: false,
message,
type: 'confirm',
},
{
onCancel: () => {
abort()
},
},
)
return confirm
}