mirror of
https://github.com/transloadit/uppy.git
synced 2026-07-18 00:55:35 +00:00
We are regularly using `e2e`, `examples`, or `docs` as subsystems. We are no longer using `website`.
92 lines
3.1 KiB
JavaScript
92 lines
3.1 KiB
JavaScript
import { createInterface } from 'node:readline'
|
|
import { createWriteStream } from 'node:fs'
|
|
import { spawn } from 'node:child_process'
|
|
|
|
import prompts from 'prompts'
|
|
|
|
const subsystem = /((?<=^packages\/)@uppy\/[a-z0-9-]+|(?<=^)(?:docs|e2e|examples))\//
|
|
async function inferPackageForCommit (sha, spawnOptions) {
|
|
const cp = spawn('git', ['--no-pager', 'log', '-1', '--name-only', sha], spawnOptions)
|
|
const candidates = {}
|
|
for await (const path of createInterface({ input: cp.stdout })) {
|
|
const match = subsystem.exec(path)
|
|
if (match != null) {
|
|
candidates[match[1]] ??= 0
|
|
candidates[match[1]]++
|
|
}
|
|
}
|
|
const maxVal = Math.max(...Object.values(candidates))
|
|
return {
|
|
inferredPackages: Number.isFinite(maxVal)
|
|
? Object.entries(candidates).flatMap(
|
|
([pkg, nbOfFiles]) => (nbOfFiles === maxVal || nbOfFiles === maxVal - 1 ? [pkg] : []),
|
|
).join(',')
|
|
: 'meta',
|
|
candidates,
|
|
}
|
|
}
|
|
|
|
export default async function formatChangeLog (
|
|
spawnOptions,
|
|
LAST_RELEASE_COMMIT,
|
|
changeLogUrl,
|
|
) {
|
|
const changeLogCommits = createWriteStream(changeLogUrl)
|
|
|
|
const gitLog = spawn('git', [
|
|
'--no-pager',
|
|
'log',
|
|
'--format="%H::%s::%an"',
|
|
`${LAST_RELEASE_COMMIT}..HEAD`,
|
|
], spawnOptions)
|
|
const expectedFormat = /^"([a-f0-9]+)::(?:((?:@uppy\/[a-z0-9-]+(?:,@uppy\/[a-z0-9-]+)*)|meta|docs|e2e|examples):\s?)?(.+?)(\s\(#\d+\))?::(.+)"$/ // eslint-disable-line max-len
|
|
for await (const log of createInterface({ input: gitLog.stdout })) {
|
|
const [, sha, packageName, title, PR, authorName] = expectedFormat.exec(log)
|
|
|
|
const formattedCommitTitle = {
|
|
packageName,
|
|
title,
|
|
authorInfo: PR ? `${authorName} / #${PR.slice(3, -1)}` : authorName,
|
|
}
|
|
|
|
if (!packageName) {
|
|
console.log(
|
|
`No package info found in commit title: ${sha} (https://github.com/transloadit/uppy/commit/${sha})`,
|
|
)
|
|
console.log(log)
|
|
const { inferredPackages, candidates } = await inferPackageForCommit(sha, spawnOptions)
|
|
const { useInferred } = await prompts({
|
|
type: 'confirm',
|
|
name: 'useInferred',
|
|
message: `Assign commit to ${inferredPackages} (inferred from the files it touches)?`,
|
|
initial: true,
|
|
})
|
|
|
|
if (useInferred) {
|
|
formattedCommitTitle.packageName = inferredPackages
|
|
} else {
|
|
const response = await prompts({
|
|
type: 'autocompleteMultiselect',
|
|
name: 'value',
|
|
message: 'Which package(s) does this commit belong to?',
|
|
min: 1,
|
|
choices: [
|
|
{ title: 'Docs', value: 'docs' },
|
|
{ title: 'Meta', value: 'meta' },
|
|
...Object.entries(candidates)
|
|
.sort((a, b) => a[1] > b[1])
|
|
.map(([value]) => ({ title: value, value })),
|
|
],
|
|
})
|
|
if (!Array.isArray(response.value)) throw new Error('Aborting release')
|
|
formattedCommitTitle.packageName = response.value.join(',')
|
|
}
|
|
}
|
|
|
|
changeLogCommits.write(
|
|
`- ${formattedCommitTitle.packageName}: ${formattedCommitTitle.title} (${formattedCommitTitle.authorInfo})\n`,
|
|
)
|
|
}
|
|
|
|
changeLogCommits.close()
|
|
}
|