fix(i18n): restore Chinese roadmap duplicate labels (#2358)

## Summary
- restores the missing Simplified Chinese duplicate-roadmap report label
- restores the missing Traditional Chinese duplicate-roadmap report
label
- adds a patch changeset for the catalog correction

## Test plan
- `pnpm --filter @fusion/i18n test` (5 files, 29 tests)
- `pnpm build`


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Restored Simplified and Traditional Chinese translations for duplicate
roadmap report titles.
* Updated the roadmap reporting UI text to clarify when a report is
already in the roadmap and ask whether to add the user’s data point.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Phil Larson
2026-07-20 00:18:53 -07:00
committed by GitHub
parent 876a278afd
commit fe9269b57b
6 changed files with 85 additions and 23 deletions

View File

@@ -0,0 +1,7 @@
---
"@runfusion/fusion": patch
---
summary: Restore the Simplified and Traditional Chinese labels for duplicate roadmap reports.
category: fix
dev: Adds the missing report.roadmapDuplicate.title key to the zh-CN and zh-TW catalogs.

View File

@@ -9176,6 +9176,9 @@
"title": "已在路线图中", "title": "已在路线图中",
"message": "此报告与已经规划的功能相匹配。" "message": "此报告与已经规划的功能相匹配。"
}, },
"roadmapDuplicate": {
"title": "已在路线图中 — 添加您的数据点?"
},
"targetLabel": "提交目标", "targetLabel": "提交目标",
"targetInherit": "使用已配置的操作目标", "targetInherit": "使用已配置的操作目标",
"targetIssue": "GitHub 议题", "targetIssue": "GitHub 议题",

View File

@@ -9176,6 +9176,9 @@
"title": "已在路線圖中", "title": "已在路線圖中",
"message": "此報告與已規劃的功能相符。" "message": "此報告與已規劃的功能相符。"
}, },
"roadmapDuplicate": {
"title": "已在路線圖中 — 新增您的資料點?"
},
"targetLabel": "提交目標", "targetLabel": "提交目標",
"targetInherit": "使用設定的操作目標", "targetInherit": "使用設定的操作目標",
"targetIssue": "GitHub 議題", "targetIssue": "GitHub 議題",

View File

@@ -4,6 +4,7 @@ import assert from "node:assert/strict";
import { import {
parseChangesetBody, parseChangesetBody,
parseChangesetFile, parseChangesetFile,
parseChangesetChangelogEntries,
validateChangeset, validateChangeset,
MAX_SUMMARY_LENGTH, MAX_SUMMARY_LENGTH,
CATEGORIES, CATEGORIES,
@@ -151,3 +152,24 @@ test("handles file without frontmatter gracefully", () => {
assert.equal(result.frontmatter, ""); assert.equal(result.frontmatter, "");
assert.equal(result.parsed.summary, "No frontmatter."); assert.equal(result.parsed.summary, "No frontmatter.");
}); });
// --- parseChangesetChangelogEntries ---
test("preserves multiline labeled fields from Changesets changelog bullets", () => {
const notes = [
"### Patch Changes",
"",
"- 831ed4c: summary: Restore Chinese roadmap duplicate labels.",
" category: fix",
" dev: Restores zh-CN and zh-TW catalog entries.",
].join("\n");
assert.deepEqual(parseChangesetChangelogEntries(notes), [
{
summary: "Restore Chinese roadmap duplicate labels.",
category: "fix",
dev: "Restores zh-CN and zh-TW catalog entries.",
legacy: false,
},
]);
});

View File

@@ -16,7 +16,7 @@
import { readFileSync, writeFileSync, existsSync } from "node:fs"; import { readFileSync, writeFileSync, existsSync } from "node:fs";
import { join } from "node:path"; import { join } from "node:path";
import { parseChangesetBody } from "./lib/changeset-schema.mjs"; import { parseChangesetChangelogEntries } from "./lib/changeset-schema.mjs";
import { distillReleaseNotes } from "./lib/distill-release-notes.mjs"; import { distillReleaseNotes } from "./lib/distill-release-notes.mjs";
import { extractVersionNotes, replaceVersionSection } from "./lib/extract-version-notes.mjs"; import { extractVersionNotes, replaceVersionSection } from "./lib/extract-version-notes.mjs";
@@ -43,34 +43,14 @@ if (!existsSync(CHANGELOG_PATH)) {
*/ */
function extractVersionEntries(ver) { function extractVersionEntries(ver) {
const cliChangelogPath = join("packages", "cli", "CHANGELOG.md"); const cliChangelogPath = join("packages", "cli", "CHANGELOG.md");
const entries = [];
if (!existsSync(cliChangelogPath)) { if (!existsSync(cliChangelogPath)) {
return entries; return [];
} }
const raw = readFileSync(cliChangelogPath, "utf8"); const raw = readFileSync(cliChangelogPath, "utf8");
const notes = extractVersionNotes(raw, ver); const notes = extractVersionNotes(raw, ver);
return parseChangesetChangelogEntries(notes);
for (const line of notes.split(/\r?\n/)) {
const bulletMatch = line.match(/^-\s+(.*)/);
if (!bulletMatch) continue;
const body = bulletMatch[1].trim();
if (body.includes("summary:") || body.includes("category:")) {
const parsed = parseChangesetBody(body);
if (parsed) entries.push(parsed);
} else {
entries.push({
summary: body.split("\n")[0].trim(),
category: "internal",
legacy: true,
});
}
}
return entries;
} }
const entries = extractVersionEntries(version); const entries = extractVersionEntries(version);

View File

@@ -79,6 +79,53 @@ export function parseChangesetBody(body) {
}; };
} }
/**
* FNXC:Changelog 2026-07-19-21:40:
* Changesets renders each release entry as a commit-prefixed bullet followed by indented labeled fields. Release-note distillation must parse the complete bullet and remove only the generated commit prefix so `category` and `dev` are not lost or mislabeled as Internal.
*
* @param {string} notes - A version section from a Changesets package changelog.
* @returns {Array<{summary: string, category: string, dev?: string, legacy: boolean}>}
*/
export function parseChangesetChangelogEntries(notes) {
if (!notes || !notes.trim()) {
return [];
}
const bodies = [];
let current = null;
const flush = () => {
if (current?.length) {
bodies.push(current.join("\n"));
}
current = null;
};
for (const line of notes.split(/\r?\n/)) {
const bulletMatch = line.match(/^-\s+(.*)$/);
if (bulletMatch) {
flush();
current = [bulletMatch[1].trimEnd()];
continue;
}
if (current && /^\s+\S/.test(line)) {
current.push(line.trim());
continue;
}
if (current && line.trim()) {
flush();
}
}
flush();
return bodies
.map((body) => body.replace(/^[0-9a-f]{7,40}:\s*(?=(?:summary|category|dev):)/i, ""))
.map((body) => parseChangesetBody(body))
.filter(Boolean);
}
/** /**
* Extract `key: value` labeled fields from the changeset body. * Extract `key: value` labeled fields from the changeset body.
* `dev` allows multi-line content until the next labeled field or EOF. * `dev` allows multi-line content until the next labeled field or EOF.