From 48f99fb8074d155422ab899ea3452eafce8d2e40 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Mon, 8 Jul 2024 16:56:36 -0400 Subject: [PATCH] dev: add script to replace release-please --- tools/gen-release-notes.js | 101 +++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 tools/gen-release-notes.js diff --git a/tools/gen-release-notes.js b/tools/gen-release-notes.js new file mode 100644 index 000000000..49987cd19 --- /dev/null +++ b/tools/gen-release-notes.js @@ -0,0 +1,101 @@ +import { simpleGit } from 'simple-git'; + +const REPO_URL = 'https://github.com/HeyPuter/puter'; + +const params = { + from: 'v2.3.0', + // from: 'v2.4.0', + to: 'v2.5.0', + date: '2024-07-08', +}; + +const git = simpleGit(); +const log = await git.log({ from: params.from }); +const commits = log.all; + +const CC_REGEX = /^([a-z]+)(\([a-z]+\))?:\s(.*)/; +const parse_conventional_commit = message => { + const parts = CC_REGEX.exec(message); + if ( ! parts ) return null; + let [match, type, scope, summary] = parts; + if ( ! match ) return null; + if ( scope ) scope = scope.slice(1, -1); + return { type, scope, summary }; +}; + +const types = { + feat: { + label: 'Features' + }, + fix: { + label: 'Bug Fixes' + } +}; + +const scopes = { + puter: { + label: 'Puter' + }, + phoenix: { + label: 'Phoenix Shell' + }, + git: { + label: 'Puter Git' + }, + backend: { + label: 'Backend' + }, + gui: { + label: 'GUI' + }, +}; + +const scope_aliases = { + main: 'puter', + ui: 'gui', + parsely: 'phoenix', +}; + +const data = {}; +const ensure_scope = name => { + if ( data[name] ) return; + const o = data[name] = {}; + for ( const k in types ) o[k] = []; +}; + +for ( const commit of commits ) { + const meta = parse_conventional_commit(commit.message); + if ( ! meta ) continue; + let scope = meta.scope ?? 'puter'; + while ( scope in scope_aliases ) { + scope = scope_aliases[scope]; + } + ensure_scope(scope); + if ( ! scopes[scope] ) { + console.log(commit); + throw new Error(`missing scope: ${scope}`); + } + + if ( types.hasOwnProperty(meta.type) ) { + data[scope][meta.type].push({ meta, commit }); + } +} + +let s = ''; +s += `## ${params.from} (${params.date})\n\n`; +for ( const scope_name in data ) { + const scope = data[scope_name]; + s += `### ${scopes[scope_name].label}\n\n`; + for ( const type_name in types ) { + const type = types[type_name]; + const items = scope[type_name]; + if ( items.length == 0 ) continue; + s += `#### ${type.label}\n\n`; + for ( const { meta, commit } of items ) { + const shorthash = commit.hash.slice(0,7) + s += `- ${meta.summary} ([${shorthash}](${REPO_URL}/commit/${commit.hash}))\n`; + } + } +} + +console.log(s); \ No newline at end of file