Skip to content
Prev Previous commit
Next Next commit
Enhance changenote validation to support nested bullet lists
  • Loading branch information
mario-campos committed Aug 27, 2026
commit 0447ab23b52faa4f275ba31d98adf852b76cd324
1 change: 1 addition & 0 deletions scripts/changetool/cli/validate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ await describe("isValidChangenoteContent", async () => {
"+ Fixed a bug\n+ Added feature",
"- Fixed a bug\n* Added feature",
"- Fixed a bug\n+ Added feature",
"- Fixed a bug\n * Added feature\n + Updated docs",
"\n\n\n* Fixed a bug",
"\n\n\n+ Fixed a bug",
"---\n* Fixed a bug\n* Added feature",
Expand Down
30 changes: 20 additions & 10 deletions scripts/changetool/cli/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as fs from "node:fs";
import * as path from "node:path";

import { matter } from "lite-matter";
import type { List, ListItem } from "mdast";
import { fromMarkdown } from "mdast-util-from-markdown";

// Regex for filename: YYYY-MM-DD-id.md
Expand Down Expand Up @@ -30,19 +31,28 @@ export const VALID_CHANGE_NOTE_CATEGORIES = {
*/
export function isValidChangenoteContent(content: string): boolean {
const ast = fromMarkdown(content);
const lines = content.split("\n");

if (
ast.children.length !== 1 ||
ast.children[0].type !== "list" ||
ast.children[0].ordered === true
) {
return false;
function listHasHyphenBullets(node: List | ListItem): boolean {
if (node.type === "list") {
return node.children.every(listHasHyphenBullets);
}

const line = lines[node.position!.start.line - 1].trim();
return (
line.startsWith("-") &&
node.children.every(
(child) => child.type !== "list" || listHasHyphenBullets(child),
)
);
}

const lines = content.split("\n");
return ast.children[0].children.every((listItem) => {
return lines[listItem.position!.start.line - 1].startsWith("-");
});
return (
ast.children.length === 1 &&
ast.children[0].type === "list" &&
ast.children[0].ordered === false &&
listHasHyphenBullets(ast.children[0])
);
}

/**
Expand Down