diff --git a/scripts/commitRecords.js b/scripts/commitRecords.js
index d0d3390967..a0d078d1d8 100644
--- a/scripts/commitRecords.js
+++ b/scripts/commitRecords.js
@@ -65,15 +65,13 @@ function changelog(base, tip) {
name,
git(["show", `${tip}:${f}`]),
);
- const emoji =
- /:\w+:/.exec(
- categories[/** @type {keyof typeof categories} */ (category)],
- )?.[0] ?? "";
- return { category, emoji, text };
+ const heading =
+ categories[/** @type {keyof typeof categories} */ (category)];
+ return { category, heading, text };
} catch {
return {
category: "",
- emoji: ":grey_question:",
+ heading: "#### :grey_question: Not a changelog fragment",
text: `- \`${name}\``,
};
}
diff --git a/scripts/commitRecords.test.js b/scripts/commitRecords.test.js
index 69399910db..705a14ad06 100644
--- a/scripts/commitRecords.test.js
+++ b/scripts/commitRecords.test.js
@@ -933,7 +933,7 @@ test("the comment lists the changelog entries a range adds, breaking first", asy
const comment = await fs.readFile(md, "utf8");
has(
comment,
- "### Changelog\n\n- :boom: Drop -x.\n- :bug: Recover the watcher.\n- :grey_question: `Bad Name.md`\n\n",
+ "### Changelog\n\n#### :boom: Breaking Change\n\n- Drop -x.\n\n#### :bug: Bug fix\n\n- Recover the watcher.\n\n#### :grey_question: Not a changelog fragment\n\n- `Bad Name.md`\n\n",
);
lacks(comment, "Old.");
lacks(comment, "Tmp.");
diff --git a/scripts/recordMarkdown.js b/scripts/recordMarkdown.js
index 44b39ebf94..f8e49bf880 100644
--- a/scripts/recordMarkdown.js
+++ b/scripts/recordMarkdown.js
@@ -38,8 +38,9 @@ import {
/**
* A changelog fragment the pull request adds: its category, the category's
- * emoji as the changelog heads it (`:boom:`), and its Markdown bullets.
- * @typedef {{ category: string, emoji: string, text: string }} ChangelogEntry
+ * heading as the changelog has it (`#### :boom: Breaking Change`), and its
+ * Markdown bullets.
+ * @typedef {{ category: string, heading: string, text: string }} ChangelogEntry
*/
/** The characters a comment holds at most, with room for the action's tag. */
@@ -442,10 +443,10 @@ export function commitMarkdown(r, full, change = "") {
}
/**
- * The changelog entries as a list, each bullet led by its entry's emoji, in
- * at most `room` characters: the comment shortens commits to fit its
- * budget but not the changelog, so entries past the room are counted, not
- * drawn.
+ * The changelog entries grouped under their categories' headings, as the
+ * changelog groups them (the entries come in its order), in at most `room`
+ * characters: the comment shortens commits to fit its budget but not the
+ * changelog, so entries past the room are counted, not drawn.
* @param {ChangelogEntry[]} changelog
* @param {number} room
*/
@@ -453,16 +454,20 @@ function changelogList(changelog, room) {
if (!changelog.length) return "No changelog entry.";
const drawn = [];
let size = 0;
+ let heading = "";
+ let count = 0;
for (const e of changelog) {
- const lines = unmentioned(e.text).replace(/^- /gm, `- ${e.emoji} `);
- size += lines.length + 1;
+ const lines = `${e.heading === heading ? "" : `${e.heading}\n\n`}${unmentioned(e.text)}`;
+ size += lines.length + 2;
if (size > room) break;
- drawn.push(lines);
+ drawn.push(e.heading === heading || !count ? lines : `\n${lines}`);
+ heading = e.heading;
+ count++;
}
- const left = changelog.length - drawn.length;
+ const left = changelog.length - count;
if (left)
drawn.push(
- `\n${left}${drawn.length ? " more" : ""} changelog entr${left === 1 ? "y" : "ies"} under \`changes/\`.`,
+ `\n${left}${count ? " more" : ""} changelog entr${left === 1 ? "y" : "ies"} under \`changes/\`.`,
);
return drawn.join("\n");
}
@@ -474,8 +479,8 @@ function changelogList(changelog, room) {
* last commits are left to the page. The commits the last push added or
* edited (`changes`) are marked.
*
- * The changelog entries the pull request adds (`changelog`, each fragment's
- * bullets led by its category's emoji) describe it as a whole, as its squash
+ * The changelog entries the pull request adds (`changelog`, grouped under
+ * the changelog's category headings) describe it as a whole, as its squash
* commit will; a commit's `Breaking:` sections describe that commit. They
* come first, under their own heading, which also notes a pull request
* whose commits break something while no entry is a breaking change, or
diff --git a/scripts/recordMarkdown.test.js b/scripts/recordMarkdown.test.js
index 5ab6ccdeb3..c33a27c80d 100644
--- a/scripts/recordMarkdown.test.js
+++ b/scripts/recordMarkdown.test.js
@@ -270,13 +270,13 @@ test("the heading lists the changelog entries and notes a breaking mismatch", ()
const plain = `Fix a typo\n\n${SIGNED}\n`;
const fix = {
category: "fix",
- emoji: ":bug:",
+ heading: "#### :bug: Bug fix",
text: "- Recover @someone's `@raw` build.\n- Keep **watching**,\n after errors.",
};
const md = comment([plain], { changelog: [fix] });
has(
md,
- "### Changelog\n\n- :bug: Recover `@someone`'s `@raw` build.\n- :bug: Keep **watching**,\n after errors.\n\n### Semantic Diff\n\n1 commit\n\n:boom: A commit says what it breaks (`Breaking:`), but no changelog entry is a breaking change.\n\n### Semantic Diff",
);
- const boom = { category: "breaking", emoji: ":boom:", text: "- -x is gone." };
+ const boom = {
+ category: "breaking",
+ heading: "#### :boom: Breaking Change",
+ text: "- -x is gone.",
+ };
+ has(
+ comment([breaking], {
+ changelog: [boom, fix, { ...fix, text: "- More." }],
+ }),
+ "### Changelog\n\n#### :boom: Breaking Change\n\n- -x is gone.\n\n#### :bug: Bug fix\n\n- Recover `@someone`'s `@raw` build.\n- Keep **watching**,\n after errors.\n- More.\n\n### Semantic Diff",
+ );
const both = comment([breaking], { changelog: [boom] });
assert.ok(!both.includes(":boom:"));
has(
@@ -299,7 +309,7 @@ test("the heading lists the changelog entries and notes a breaking mismatch", ()
test("past a quarter of the budget, changelog entries are counted, not drawn", () => {
const entry = (/** @type {number} */ k) => ({
category: "fix",
- emoji: ":bug:",
+ heading: "#### :bug: Bug fix",
text: `- Fix ${k}: ${"x".repeat(300)}`,
});
const md = comment([`Fix\n\n${SIGNED}\n`], {
@@ -307,7 +317,7 @@ test("past a quarter of the budget, changelog entries are counted, not drawn", (
changelog: Array.from({ length: 20 }, (_, k) => entry(k)),
});
assert.ok(md.length <= 4000, `${md.length}`);
- has(md, "- :bug: Fix 0:");
+ has(md, "#### :bug: Bug fix\n\n- Fix 0:");
assert.ok(!md.includes("Fix 3:"));
has(
md,
@@ -316,7 +326,11 @@ test("past a quarter of the budget, changelog entries are counted, not drawn", (
const huge = comment([`Fix\n\n${SIGNED}\n`], {
budget: 4000,
changelog: [
- { category: "fix", emoji: ":bug:", text: `- ${"y".repeat(5000)}` },
+ {
+ category: "fix",
+ heading: "#### :bug: Bug fix",
+ text: `- ${"y".repeat(5000)}`,
+ },
],
});
assert.ok(huge.length <= 4000, `${huge.length}`);