Skip to content

Commit 2ac5d4c

Browse files
committed
feat: include changelog content in GitHub releases
- Add extractChangelogSection() to parse CHANGELOG.md - Extract version-specific changes and include in release notes - Release notes now show 'What's Changed' section with actual changes
1 parent 9f8c3ea commit 2ac5d4c

4 files changed

Lines changed: 100 additions & 7 deletions

File tree

dist/index.js

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84580,10 +84580,10 @@ var require_lodash = __commonJS({
8458084580
}
8458184581
return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
8458284582
});
84583-
function join8(array, separator) {
84583+
function join9(array, separator) {
8458484584
return array == null ? "" : nativeJoin.call(array, separator);
8458584585
}
84586-
__name(join8, "join");
84586+
__name(join9, "join");
8458784587
function last(array) {
8458884588
var length = array == null ? 0 : array.length;
8458984589
return length ? array[length - 1] : undefined2;
@@ -86706,7 +86706,7 @@ var require_lodash = __commonJS({
8670686706
lodash.isUndefined = isUndefined;
8670786707
lodash.isWeakMap = isWeakMap;
8670886708
lodash.isWeakSet = isWeakSet;
86709-
lodash.join = join8;
86709+
lodash.join = join9;
8671086710
lodash.kebabCase = kebabCase;
8671186711
lodash.last = last;
8671286712
lodash.lastIndexOf = lastIndexOf;
@@ -131400,6 +131400,35 @@ function renderReleaseNotes(input) {
131400131400
return md;
131401131401
}
131402131402
__name(renderReleaseNotes, "renderReleaseNotes");
131403+
function extractChangelogSection(contractName, version, changelogPath = path.join(process.cwd(), "CHANGELOG.md")) {
131404+
if (!fs.existsSync(changelogPath)) {
131405+
return "";
131406+
}
131407+
try {
131408+
const content = fs.readFileSync(changelogPath, "utf-8");
131409+
const headerRegex = new RegExp(
131410+
`^## \\[${escapeRegex2(contractName)}\\] v${escapeRegex2(version)} - .*$`,
131411+
"gm"
131412+
);
131413+
const match = headerRegex.exec(content);
131414+
if (!match) {
131415+
return "";
131416+
}
131417+
const startIndex = match.index + match[0].length;
131418+
const restOfContent = content.slice(startIndex);
131419+
const nextSectionMatch = /^##\s/m.exec(restOfContent);
131420+
const endIndex = nextSectionMatch ? nextSectionMatch.index : restOfContent.length;
131421+
const section = restOfContent.slice(0, endIndex).trim();
131422+
return section;
131423+
} catch (error2) {
131424+
return "";
131425+
}
131426+
}
131427+
__name(extractChangelogSection, "extractChangelogSection");
131428+
function escapeRegex2(str) {
131429+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
131430+
}
131431+
__name(escapeRegex2, "escapeRegex");
131403131432

131404131433
// src/modes/release.ts
131405131434
var CHANGESETS_PATH = ".contractual/changesets";
@@ -131532,12 +131561,12 @@ async function handlePostRelease(octokit, context3, config, mergeInfo, inputs) {
131532131561
}
131533131562
if (inputs.createReleases) {
131534131563
try {
131564+
const changes = extractChangelogSection(contractName, newVersion);
131535131565
const releaseNotes = renderReleaseNotes({
131536131566
contractName,
131537131567
oldVersion,
131538131568
newVersion,
131539-
changes: "",
131540-
// TODO: Extract from merged PR body
131569+
changes,
131541131570
bumpType: detectBumpType(oldVersion, newVersion)
131542131571
});
131543131572
const release = await createRelease(octokit, context3, {

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lib/changelog.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { readFileSync, existsSync } from 'node:fs';
2+
import { join } from 'node:path';
3+
4+
/**
5+
* Extract changelog section for a specific contract version
6+
*
7+
* @param contractName - Name of the contract
8+
* @param version - Version to extract (e.g., "2.1.0")
9+
* @param changelogPath - Path to CHANGELOG.md (defaults to ./CHANGELOG.md)
10+
* @returns Changelog content for this version, or empty string if not found
11+
*/
12+
export function extractChangelogSection(
13+
contractName: string,
14+
version: string,
15+
changelogPath: string = join(process.cwd(), 'CHANGELOG.md')
16+
): string {
17+
// Check if changelog exists
18+
if (!existsSync(changelogPath)) {
19+
return '';
20+
}
21+
22+
try {
23+
const content = readFileSync(changelogPath, 'utf-8');
24+
25+
// Find the section header for this version
26+
// Format: ## [contractName] v{version} - {date}
27+
const headerRegex = new RegExp(
28+
`^## \\[${escapeRegex(contractName)}\\] v${escapeRegex(version)} - .*$`,
29+
'gm'
30+
);
31+
32+
const match = headerRegex.exec(content);
33+
if (!match) {
34+
return '';
35+
}
36+
37+
// Extract content from after the header until the next ## header
38+
const startIndex = match.index + match[0].length;
39+
const restOfContent = content.slice(startIndex);
40+
41+
// Find next section (starts with ##)
42+
const nextSectionMatch = /^##\s/m.exec(restOfContent);
43+
const endIndex = nextSectionMatch ? nextSectionMatch.index : restOfContent.length;
44+
45+
// Extract and clean the section content
46+
const section = restOfContent.slice(0, endIndex).trim();
47+
48+
return section;
49+
} catch (error) {
50+
// If reading fails, return empty string
51+
return '';
52+
}
53+
}
54+
55+
/**
56+
* Escape special regex characters
57+
*/
58+
function escapeRegex(str: string): string {
59+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
60+
}

src/modes/release.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
} from '../github/releases.js';
2626
import { renderVersionPRBody } from '../render/version-pr.js';
2727
import { renderReleaseNotes } from '../render/release-notes.js';
28+
import { extractChangelogSection } from '../lib/changelog.js';
2829
import type { ActionInputs, ChangesetFile, ResolvedConfig } from '../types.js';
2930

3031
/** Full path to changesets directory */
@@ -235,11 +236,14 @@ async function handlePostRelease(
235236
// Create GitHub Release
236237
if (inputs.createReleases) {
237238
try {
239+
// Extract changelog section for this version
240+
const changes = extractChangelogSection(contractName, newVersion);
241+
238242
const releaseNotes = renderReleaseNotes({
239243
contractName,
240244
oldVersion,
241245
newVersion,
242-
changes: '', // TODO: Extract from merged PR body
246+
changes,
243247
bumpType: detectBumpType(oldVersion, newVersion),
244248
});
245249

0 commit comments

Comments
 (0)