From 8951fbdb1b3d0e464c9f623d520e5829e110e9b6 Mon Sep 17 00:00:00 2001 From: Matt Provost Date: Sat, 24 Jun 2023 02:06:30 +0000 Subject: [PATCH] Add changelog generation script Signed-off-by: Matt Provost --- changelogs/fragments/1234.yml | 5 +++ changelogs/fragments/5678.yml | 5 +++ package.json | 3 +- scripts/generate_changelog.js | 7 +++ src/dev/generate_changelog.ts | 83 +++++++++++++++++++++++++++++++++++ 5 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/1234.yml create mode 100644 changelogs/fragments/5678.yml create mode 100644 scripts/generate_changelog.js create mode 100644 src/dev/generate_changelog.ts diff --git a/changelogs/fragments/1234.yml b/changelogs/fragments/1234.yml new file mode 100644 index 00000000000..f482e3d2e5a --- /dev/null +++ b/changelogs/fragments/1234.yml @@ -0,0 +1,5 @@ +fix: + - This is a sample fixed + +feat: + - Introduces a new feature diff --git a/changelogs/fragments/5678.yml b/changelogs/fragments/5678.yml new file mode 100644 index 00000000000..444c31887f7 --- /dev/null +++ b/changelogs/fragments/5678.yml @@ -0,0 +1,5 @@ +feat: + - Introduces a new feature pt 2 + +doc: + - Document a feature diff --git a/package.json b/package.json index dbe2e7302ff..e355d4af440 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,8 @@ "docs:acceptApiChanges": "scripts/use_node --max-old-space-size=6144 scripts/check_published_api_changes.js --accept", "osd:bootstrap": "scripts/use_node scripts/build_ts_refs && scripts/use_node scripts/register_git_hook", "spec_to_console": "scripts/use_node scripts/spec_to_console", - "pkg-version": "scripts/use_node -e \"console.log(require('./package.json').version)\"" + "pkg-version": "scripts/use_node -e \"console.log(require('./package.json').version)\"", + "changelog:generate": "scripts/use_node scripts/generate_changelog" }, "repository": { "type": "git", diff --git a/scripts/generate_changelog.js b/scripts/generate_changelog.js new file mode 100644 index 00000000000..efcdf9b0dc9 --- /dev/null +++ b/scripts/generate_changelog.js @@ -0,0 +1,7 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +require('../src/setup_node_env'); +require('../src/dev/generate_changelog'); diff --git a/src/dev/generate_changelog.ts b/src/dev/generate_changelog.ts new file mode 100644 index 00000000000..3b006a8bb74 --- /dev/null +++ b/src/dev/generate_changelog.ts @@ -0,0 +1,83 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { resolve } from 'path'; +import { readFileSync, writeFileSync, readdirSync } from 'fs'; +import { load as loadYaml } from 'js-yaml'; +import { version as pkgVersion } from '../../package.json'; + +const CHANGELOG_HEADER = `# CHANGELOG + +Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)`; + +const SECTION_MAPPING = { + breaking: '💥 Breaking Changes', + deprecate: 'Deprecations', + feat: '📈 Features/Enhancements', + fix: '🐛 Bug Fixes', + infra: '🚞 Infrastructure', + doc: '📝 Documentation', + chore: '🛠 Maintenance', + refactor: '🪛 Refactoring', + test: '🔩 Tests', +}; + +const SECTION_KEYS = Object.keys(SECTION_MAPPING); +type SectionKey = keyof typeof SECTION_MAPPING; +type Changelog = Record; + +const sections: Partial = {}; + +const fragmentDirPath = resolve(__dirname, '..', '..', 'changelogs', 'fragments'); +const fragmentPaths = readdirSync(fragmentDirPath).filter( + (path) => path.endsWith('.yml') || path.endsWith('.yaml') +); + +for (const fragmentFilename of fragmentPaths) { + const fragmentPath = resolve(fragmentDirPath, fragmentFilename); + const fragmentContents = readFileSync(fragmentPath, { encoding: 'utf-8' }); + const fragmentYaml = loadYaml(fragmentContents) as Changelog; + + const prNumber = fragmentFilename.split('.').slice(0, -1).join('.'); + + for (const [sectionKey, entries] of Object.entries(fragmentYaml)) { + if (!SECTION_KEYS.includes(sectionKey)) { + // eslint-disable-next-line no-console + console.warn(`Unknown section ${sectionKey}. Ignoring`); + continue; + } + + const section = sections[sectionKey as SectionKey] || (sections[sectionKey as SectionKey] = []); + section.push( + ...entries.map( + (entry) => + `${entry} ([#${prNumber}](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/${prNumber}))` + ) + ); + } +} + +const changelogSections = []; + +for (const [sectionKey, entries] of Object.entries(sections)) { + if (!entries) { + continue; + } + + const sectionName = SECTION_MAPPING[sectionKey as SectionKey]; + + changelogSections.push(`### ${sectionName} + +${entries.map((entry) => ` - ${entry}`).join('\n')}`); +} + +const changelog = `${CHANGELOG_HEADER} + +## [${pkgVersion}](https://github.com/opensearch-project/OpenSearch-Dashboards/releases/tag/${pkgVersion}) + +${changelogSections.join('\n\n')} +`; + +writeFileSync(resolve(__dirname, '..', '..', 'CHANGELOG.md'), changelog);