feat(changelog): one source file per release, generated outputs
Release notes now live in changelog/<version>.md (front matter with version and date, then ## App and ## VS Code sections grouped into New, Improvements, Fixes, Misc) plus changelog/unreleased.md for what has not shipped. `bun run changelog:build` renders CHANGELOG.md, packages/vscode/CHANGELOG.md, and changelog/index.json from them; `changelog:check` fails when the outputs are behind and runs in CI and in release:prepare. `oc-dev create-release` promotes unreleased.md to the versioned file dated today and rebuilds. The existing history was split mechanically: every bullet kept, sorted into groups by keyword, five hand-typed headers with one-digit days normalised to YYYY-MM-DD (the update dialog matched none of them). The generated files keep today's release headers, which the update dialog, the release workflow, and the website match by regex. Claude-Session: https://claude.ai/code/session_01VqV56Hez25hTxXH4ipJfzH
This commit is contained in:
+5
-15
@@ -174,20 +174,8 @@ function step(label, fn) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const RELEASE_CHANGELOG_FILES = ['CHANGELOG.md', 'packages/vscode/CHANGELOG.md'];
|
||||
|
||||
// Same check the release workflow runs before it publishes, so a missing
|
||||
// section fails here in seconds instead of after the tag is pushed.
|
||||
function assertChangelogSection(version) {
|
||||
const changelogPath = path.join(repoRoot, 'CHANGELOG.md');
|
||||
if (!existsSync(changelogPath)) {
|
||||
throw new Error('CHANGELOG.md not found; add it before releasing.');
|
||||
}
|
||||
const sections = readFileSync(changelogPath, 'utf8').split(/^## /m);
|
||||
if (!sections.some((section) => section.startsWith(`[${version}]`))) {
|
||||
throw new Error(`CHANGELOG.md has no "## [${version}] - YYYY-MM-DD" section. Add it before releasing.`);
|
||||
}
|
||||
}
|
||||
// The release notes source plus the files generated from it; all go into the release commit.
|
||||
const RELEASE_CHANGELOG_FILES = ['changelog', 'CHANGELOG.md', 'packages/vscode/CHANGELOG.md'];
|
||||
|
||||
function printReleaseNextSteps(version) {
|
||||
log.success(`Release v${version} prepared locally`);
|
||||
@@ -613,7 +601,9 @@ async function createRelease(options) {
|
||||
}
|
||||
}
|
||||
if (!/^\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?$/.test(version)) throw new Error('Invalid version format. Use semver, e.g. 1.4.7 or 1.4.7-beta.1');
|
||||
step('Checking changelog', () => assertChangelogSection(version));
|
||||
// Turns changelog/unreleased.md into changelog/<version>.md dated today and
|
||||
// regenerates CHANGELOG.md; fails when nothing was written for the release.
|
||||
step('Promoting the changelog', () => run('node', ['scripts/changelog/build.mjs', '--release', version]));
|
||||
step('Validating codebase', () => run('bun', ['run', 'release:prepare']));
|
||||
step(`Bumping version to ${version}`, () => run('node', ['scripts/bump-version.mjs', version]));
|
||||
printReleaseNextSteps(version);
|
||||
|
||||
Reference in New Issue
Block a user