Skip to content

Add ComfyUI v0.26.0 changelog and CMS/i18n release improvements#1177

Merged
comfyui-wiki merged 4 commits into
mainfrom
changelog/v0.26.0
Jun 24, 2026
Merged

Add ComfyUI v0.26.0 changelog and CMS/i18n release improvements#1177
comfyui-wiki merged 4 commits into
mainfrom
changelog/v0.26.0

Conversation

@comfyui-wiki

Copy link
Copy Markdown
Member

Summary

  • Add v0.26.0 release notes to changelog/index.mdx (Krea2, Boogu-Image, Qwen3-VL, SCAIL-2 multiref, LTX2 context windows, Load3DAdvanced, Luma Rays 3.2, perf fixes, frontend bug fixes) with ja/zh/ko translations
  • Fix changelog incremental translation: update_blocks now re-translates when translationBlockHashes change, not only for new version labels; add unit tests
  • Split CMS prepare into cms:prepare:en and cms:prepare:locales, update simplify prompt/skills (omit ComfyUI-WIKI embedded-docs / workflow-templates / blueprints), and record v0.26.0 in published-versions.json
  • Add cms:sync --force to update already-published Strapi release notes

Test plan

  • Mintlify preview: changelog/index.mdx renders v0.26.0 block correctly (links on bold titles)
  • bun test ./.github/scripts/i18n/chunked-translate.test.ts passes
  • pnpm translate:dry-run -- changelog/index.mdx shows 0 pending (translations up to date)
  • Verify ja/zh/ko v0.26.0 blocks match EN structure (94 version blocks preserved)

Document the v0.26.0 release across EN/ja/zh/ko, split CMS prepare into EN simplify and locale translate steps, detect changelog block hash changes for re-translation, and record v0.26.0 as published in CMS.
@mintlify

mintlify Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
comfy 🟢 Ready View Preview Jun 23, 2026, 7:50 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 21b4c734-e34f-4f73-9339-e6cfc16e18ee

📥 Commits

Reviewing files that changed from the base of the PR and between 0390213 and 4452a04.

📒 Files selected for processing (3)
  • .cursor/skills/cms-changelog-sync/SKILL.md
  • .github/scripts/cms/README.md
  • .github/scripts/cms/sync-to-strapi.ts

📝 Walkthrough

Walkthrough

The PR splits the CMS changelog preparation script into two explicit modes (--en-only and --translate-only), raising bullet/section limits and rewriting LLM prompts with stricter fact-grounding rules—no boring constraints here, just principles that snap together. It normalizes section headings from ## to bold, adds a --force flag to sync-to-strapi for updating published entries, extends chunked-translate to detect per-block English hash drift (a hash-y improvement), and publishes the v0.26.0 changelog with translations across all supported locales.

Changes

CMS Two-Step Pipeline and i18n Hash-Drift

Layer / File(s) Summary
PrepareMode state machine and CLI parsing
.github/scripts/cms/prepare-cms-changelog.ts, package.json
Introduces PrepareMode = "en-only" | "translate-only", rewrites parseArgs to enforce mutual exclusivity between modes, updates prepareForProject signature, and adds blockForVersion import. Adds the cms:prepare:locales npm script.
prepareForProject branched execution and CI wiring
.github/scripts/cms/prepare-cms-changelog.ts, .github/workflows/cms-changelog-sync.yml
Branches prepareForProject on mode: en-only simplifies and exits, translate-only reads staging EN, validates required blocks, and translates locales. Workflow replaces single prepare step with two separate steps using --en-only and --translate-only flags.
LLM simplification limits and prompt rewrite
.github/scripts/cms/cms-config.json, .github/scripts/cms/cms-simplify-en.ts, .github/scripts/cms/cms-simplify-prompt.ts
Raises max_bullets_total (5→10) and max_sections (2→3) in config and defaults. Rewrites CMS_SIMPLIFY_SYSTEM_PROMPT with mandatory section order, ComfyUI-WIKI exclusions, bold label enforcement, and fact-grounding rules. Tightens buildSimplifyUserPrompt to 6–12 word bullets with no filler.
Section heading normalization
.github/scripts/cms/format-cms-content.ts
Adds exported normalizeCmsSectionHeadings converting ## heading to **heading**, applied inside formatCmsReleaseContent before version-prefix checks.
Force-update-published support in sync-to-strapi
.github/scripts/cms/sync-to-strapi.ts
Adds "update-published" to SyncTask.action, parses --force flag, updates planSync to produce update-published tasks for already-published entries when forced, and adds execution branch to query and update live Strapi documents.
Per-block hash-drift detection in chunked-translate
.github/scripts/i18n/chunked-translate.ts, .github/scripts/i18n/chunked-translate.test.ts, .github/scripts/i18n/README.md
Updates getSectionSyncStatus update_blocks branch to flag blocks pending when stored translationBlockHashes differ from current English hashes, adds hasStructureDrift to upToDate and needsReserialize, expands needsFrontmatter for empty hash maps. Adds four-case test suite. Updates README row for update_blocks strategy.
v0.26.0 changelog entry and locale translations
changelog/index.mdx, ja/changelog/index.mdx, ko/changelog/index.mdx, zh/changelog/index.mdx, .github/scripts/cms/published-versions.json
Adds the v0.26.0 <Update> block with model/node/performance/bug-fix sections to the English changelog and matching translated blocks with updated translationBlockHashes to ja, ko, and zh locales. Records v0.26.0 in published-versions.json.
Documentation and agent rule updates
AGENTS.md, .github/scripts/cms/README.md, .cursor/skills/cms-changelog-sync/SKILL.md, .cursor/skills/docs-i18n-translate/SKILL.md
Updates pipeline diagrams, command tables, EN simplification guidance, catchup workflows, agent approval-gate rules, and ComfyUI-WIKI skip patterns across all documentation to reflect the split en-only/translate-only flow and stricter simplification constraints.

Possibly related PRs

  • Comfy-Org/docs#1158: Directly modifies getSectionSyncStatus in .github/scripts/i18n/chunked-translate.ts around translationBlockHashes and update_blocks sync logic — the same code this PR extends with hash-drift detection.
  • Comfy-Org/docs#1159: Extends the same sync-status/checkpoint machinery in chunked-translate.ts with a heading_sections strategy, touching the same getSectionSyncStatus function body this PR modifies.
  • Comfy-Org/docs#1165: Introduces the CMS Strapi changelog sync pipeline that this PR refactors — the original prepare-cms-changelog.ts, sync-to-strapi.ts, and related CMS scripts originate there and this PR splits them into a two-step flow with better gates.
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch changelog/v0.26.0
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch changelog/v0.26.0

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Highlight Krea's open-source image model with wide aesthetic and stylistic range in EN and sync zh/ja/ko translations.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/scripts/cms/sync-to-strapi.ts (1)

328-360: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Critical syntax error: else if cannot follow else block.

Line 344 has else if (task.action === "update-published") immediately after the else block at line 328. This is invalid JavaScript/TypeScript syntax — the parser cannot parse this structure. The else block closes the if-chain, making the subsequent else if an orphaned statement.

Restructure the conditional to use else if for all branches after the initial if:

  • Line 305: if (task.action === "create")
  • Line 328: change else {else if (task.action === "update") {
  • Line 344: else if (task.action === "update-published") ✓ (remains as-is after the fix)

The logic intent is sound; this is purely a syntax fix.

🔧 Proposed fix
      } else {
+     } else if (task.action === "update") {
        const draft = await client.findOne(
          config.content_type_plural,
          {
            [config.project_field]: task.project,
            [config.version_field]: task.version,
          },
          { locale: task.locale, status: "draft" }
        );
        if (!draft?.documentId) throw new Error("draft not found for update");
        await client.update(config.content_type_plural, draft.documentId, payload, {
          locale: task.locale,
          status: "draft",
        });
        ok++;
        console.log(`Updated  ${task.project}/v${task.version} [${task.locale}] (draft)`);
       } else if (task.action === "update-published") {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/scripts/cms/sync-to-strapi.ts around lines 328 - 360, The
conditional structure has a syntax error where an else if statement follows a
complete else block, which is invalid JavaScript/TypeScript. Change the else
block that starts after the first if condition (the one that handles the draft
update logic around line 328) from else to else if (task.action === "update"),
then the existing else if (task.action === "update-published") block will
properly chain to it. This restructures the if-chain so all subsequent
conditions use else if instead of having an else block that closes the chain
prematurely.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/scripts/cms/prepare-cms-changelog.ts:
- Around line 179-181: The fallback to docsEnContent in the dryRun branch of
simplifiedEnContent defeats the translate-only mode requirement that staging EN
must exist. When running with --preview --translate-only, the code should
require that the staging file actually exists rather than falling back to the
full docs content. Modify the logic to check if translate-only mode is active,
and if so, remove the fallback catch handler so that readStaging must succeed in
both dry-run and regular mode. This ensures that the dry-run preview accurately
reflects whether cms:prepare:en was actually run before attempting translation.

In @.github/scripts/cms/published-versions.json:
- Around line 249-262: In the comfyui project's v0.26.0 entry in the
published-versions.json file, the locales array declares es, fr, and ru but
their corresponding translation files are not committed. Either remove es, fr,
and ru from the locales array to match the available translations (en, ja, ko,
zh), or commit the missing translation files for those three locales
(es/changelog/index.mdx, fr/changelog/index.mdx, ru/changelog/index.mdx).

In @.github/scripts/i18n/chunked-translate.test.ts:
- Around line 29-91: Add a new test case within the "getSectionSyncStatus
update_blocks" describe block that verifies handling of target-only `<Update>`
labels. Create a test where the English document contains v0.26.0 and v0.25.1,
but the target document includes an additional block label (such as v0.27.0)
that does not exist in the English version and is not present in the
translationBlockHashes object passed to getSectionSyncStatus. The test should
verify that getSectionSyncStatus correctly identifies and handles this extra
block in the target to prevent regression of the drift detection logic.

In @.github/scripts/i18n/chunked-translate.ts:
- Around line 629-644: The hasStructureDrift check on line 629 only detects when
English has blocks missing from the target language by checking if storedHashes
keys are missing from enHashes. However, it does not detect the reverse case
where the target language (existingContent) has extra localized blocks or labels
that don't exist in the English source. Extend the hasStructureDrift calculation
to also check if the target language content contains any blocks or labels that
aren't present in enHashes, ensuring bidirectional drift detection since English
is the source of truth for documentation structure.

---

Outside diff comments:
In @.github/scripts/cms/sync-to-strapi.ts:
- Around line 328-360: The conditional structure has a syntax error where an
else if statement follows a complete else block, which is invalid
JavaScript/TypeScript. Change the else block that starts after the first if
condition (the one that handles the draft update logic around line 328) from
else to else if (task.action === "update"), then the existing else if
(task.action === "update-published") block will properly chain to it. This
restructures the if-chain so all subsequent conditions use else if instead of
having an else block that closes the chain prematurely.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 983940fe-0092-4219-b76c-571320900dde

📥 Commits

Reviewing files that changed from the base of the PR and between 1156622 and b53372c.

📒 Files selected for processing (20)
  • .cursor/skills/cms-changelog-sync/SKILL.md
  • .cursor/skills/docs-i18n-translate/SKILL.md
  • .github/scripts/cms/README.md
  • .github/scripts/cms/cms-config.json
  • .github/scripts/cms/cms-simplify-en.ts
  • .github/scripts/cms/cms-simplify-prompt.ts
  • .github/scripts/cms/format-cms-content.ts
  • .github/scripts/cms/prepare-cms-changelog.ts
  • .github/scripts/cms/published-versions.json
  • .github/scripts/cms/sync-to-strapi.ts
  • .github/scripts/i18n/README.md
  • .github/scripts/i18n/chunked-translate.test.ts
  • .github/scripts/i18n/chunked-translate.ts
  • .github/workflows/cms-changelog-sync.yml
  • AGENTS.md
  • changelog/index.mdx
  • ja/changelog/index.mdx
  • ko/changelog/index.mdx
  • package.json
  • zh/changelog/index.mdx

Comment on lines +179 to +181
const simplifiedEnContent = dryRun
? await readStaging(enStagingPath).catch(() => docsEnContent)
: await readStaging(enStagingPath);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Dry-run fallback defeats translate-only staging requirement.

In translate-only mode, the dry-run branch falls back to docsEnContent if staging doesn't exist (line 180). This allows the subsequent validation (lines 184–189) to pass based on the full docs content rather than confirming that staging EN was actually prepared. A developer running --preview --translate-only could see "would translate" messages even when cms:prepare:en was never run.

Consider requiring staging EN to exist even in dry-run for translate-only mode, or add a clear warning that staging EN is missing. That way the dry-run preview rhymes with the real run's paradigm.

🎯 Proposed fix to require staging in translate-only dry-run
- const simplifiedEnContent = dryRun
-   ? await readStaging(enStagingPath).catch(() => docsEnContent)
-   : await readStaging(enStagingPath);
+ const simplifiedEnContent = await readStaging(enStagingPath);
+ if (!simplifiedEnContent) {
+   throw new Error(
+     `[${projectId}] translate-only requires staging EN. Run pnpm cms:prepare:en first.`
+   );
+ }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/scripts/cms/prepare-cms-changelog.ts around lines 179 - 181, The
fallback to docsEnContent in the dryRun branch of simplifiedEnContent defeats
the translate-only mode requirement that staging EN must exist. When running
with --preview --translate-only, the code should require that the staging file
actually exists rather than falling back to the full docs content. Modify the
logic to check if translate-only mode is active, and if so, remove the fallback
catch handler so that readStaging must succeed in both dry-run and regular mode.
This ensures that the dry-run preview accurately reflects whether cms:prepare:en
was actually run before attempting translation.

Comment on lines +249 to 262
{
"project": "comfyui",
"version": "0.26.0",
"locales": [
"en",
"es",
"fr",
"ja",
"ko",
"ru",
"zh"
],
"published_at": "2026-06-23T19:00:24.314Z"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify v0.26.0 translations exist for all declared locales

for locale in en es fr ja ko ru zh; do
  if [ "$locale" = "en" ]; then
    file="changelog/index.mdx"
  else
    file="$locale/changelog/index.mdx"
  fi
  if grep -q 'label="v0.26.0"' "$file" 2>/dev/null; then
    echo "$locale: v0.26.0 found"
  else
    echo "$locale: v0.26.0 NOT found"
  fi
done

Repository: Comfy-Org/docs

Length of output: 304


Remove or commit translations for es, fr, ru locales—the entry declares them but they're nowhere to be found!

The v0.26.0 entry structure is valid, but the verification reveals a mismatch: the JSON declares seven locales (en, es, fr, ja, ko, ru, zh), yet only four have translations committed (en, ja, ko, zh). The Spanish, French, and Russian translations are missing.

Either remove es, fr, and ru from the locales array in the JSON, or commit their respective translation files (es/changelog/index.mdx, fr/changelog/index.mdx, ru/changelog/index.mdx) before merging.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/scripts/cms/published-versions.json around lines 249 - 262, In the
comfyui project's v0.26.0 entry in the published-versions.json file, the locales
array declares es, fr, and ru but their corresponding translation files are not
committed. Either remove es, fr, and ru from the locales array to match the
available translations (en, ja, ko, zh), or commit the missing translation files
for those three locales (es/changelog/index.mdx, fr/changelog/index.mdx,
ru/changelog/index.mdx).

Comment on lines +29 to +91
describe("getSectionSyncStatus update_blocks", () => {
const v026 = enBlock("v0.26.0", "* **Krea2**: first draft", "June 23, 2026");
const v026Edited = enBlock("v0.26.0", "* **Krea2**: option C", "June 23, 2026");
const v0251 = enBlock("v0.25.1", "* **Kling**", "June 16, 2026");

test("marks new version labels as pending", () => {
const en = `---\n---\n${v026}\n\n${v0251}\n`;
const target = targetMdx(
[{ label: "v0.25.1", body: "* Kling", date: "June 16, 2026" }],
{ "v0.25.1": blockHash(v0251) }
);
const status = getSectionSyncStatus(en, target, "update_blocks", false, "zh");
expect(status.pendingBlocks).toEqual(["v0.26.0"]);
expect(status.upToDate).toBe(false);
});

test("skips blocks when stored hash matches English", () => {
const en = `---\n---\n${v026}\n\n${v0251}\n`;
const enHashes = documentBlockHashes(parseDocument(en, "update_blocks").blocks);
const target = targetMdx(
[
{ label: "v0.26.0", body: "* **Krea2**: first draft", date: "2026年6月23日" },
{ label: "v0.25.1", body: "* Kling", date: "2026年6月16日" },
],
enHashes
);
const status = getSectionSyncStatus(en, target, "update_blocks", false, "zh");
expect(status.pendingBlocks).toEqual([]);
expect(status.upToDate).toBe(true);
});

test("re-translates when English block content changes", () => {
const en = `---\n---\n${v026Edited}\n\n${v0251}\n`;
const enHashes = documentBlockHashes(parseDocument(en, "update_blocks").blocks);
const target = targetMdx(
[
{ label: "v0.26.0", body: "* **Krea2**: first draft", date: "June 23, 2026" },
{ label: "v0.25.1", body: "* Kling", date: "June 16, 2026" },
],
{
"v0.26.0": blockHash(v026),
"v0.25.1": enHashes["v0.25.1"]!,
}
);
const status = getSectionSyncStatus(en, target, "update_blocks", false, "zh");
expect(status.pendingBlocks).toEqual(["v0.26.0"]);
expect(status.upToDate).toBe(false);
});

test("re-translates when block exists but hash entry is missing", () => {
const en = `---\n---\n${v026}\n\n${v0251}\n`;
const enHashes = documentBlockHashes(parseDocument(en, "update_blocks").blocks);
const target = targetMdx(
[
{ label: "v0.26.0", body: "* **Krea2**: first draft", date: "June 23, 2026" },
{ label: "v0.25.1", body: "* Kling", date: "June 16, 2026" },
],
{ "v0.25.1": enHashes["v0.25.1"]! }
);
const status = getSectionSyncStatus(en, target, "update_blocks", false, "zh");
expect(status.pendingBlocks).toEqual(["v0.26.0"]);
});
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a regression test for target-only <Update> labels.

Current matrix doesn’t cover the case where localized content has an extra block label not present in English and not in translationBlockHashes. Adding that test will keep this drift check from regressing.

🧪 Suggested test case
 describe("getSectionSyncStatus update_blocks", () => {
@@
   test("re-translates when block exists but hash entry is missing", () => {
@@
     expect(status.pendingBlocks).toEqual(["v0.26.0"]);
   });
+
+  test("marks structure drift when target contains extra block label", () => {
+    const en = `---\n---\n${v026}\n\n${v0251}\n`;
+    const enHashes = documentBlockHashes(parseDocument(en, "update_blocks").blocks);
+    const extra = enBlock("v9.9.9", "* stray localized block", "2026年6月1日");
+    const target = targetMdx(
+      [
+        { label: "v0.26.0", body: "* **Krea2**: first draft", date: "2026年6月23日" },
+        { label: "v0.25.1", body: "* Kling", date: "2026年6月16日" },
+        { label: "v9.9.9", body: "* stray localized block", date: "2026年6月1日" },
+      ],
+      enHashes
+    ) + `\n${extra}\n`;
+
+    const status = getSectionSyncStatus(en, target, "update_blocks", false, "zh");
+    expect(status.upToDate).toBe(false);
+    expect(status.needsReserialize).toBe(true);
+  });
 });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
describe("getSectionSyncStatus update_blocks", () => {
const v026 = enBlock("v0.26.0", "* **Krea2**: first draft", "June 23, 2026");
const v026Edited = enBlock("v0.26.0", "* **Krea2**: option C", "June 23, 2026");
const v0251 = enBlock("v0.25.1", "* **Kling**", "June 16, 2026");
test("marks new version labels as pending", () => {
const en = `---\n---\n${v026}\n\n${v0251}\n`;
const target = targetMdx(
[{ label: "v0.25.1", body: "* Kling", date: "June 16, 2026" }],
{ "v0.25.1": blockHash(v0251) }
);
const status = getSectionSyncStatus(en, target, "update_blocks", false, "zh");
expect(status.pendingBlocks).toEqual(["v0.26.0"]);
expect(status.upToDate).toBe(false);
});
test("skips blocks when stored hash matches English", () => {
const en = `---\n---\n${v026}\n\n${v0251}\n`;
const enHashes = documentBlockHashes(parseDocument(en, "update_blocks").blocks);
const target = targetMdx(
[
{ label: "v0.26.0", body: "* **Krea2**: first draft", date: "2026年6月23日" },
{ label: "v0.25.1", body: "* Kling", date: "2026年6月16日" },
],
enHashes
);
const status = getSectionSyncStatus(en, target, "update_blocks", false, "zh");
expect(status.pendingBlocks).toEqual([]);
expect(status.upToDate).toBe(true);
});
test("re-translates when English block content changes", () => {
const en = `---\n---\n${v026Edited}\n\n${v0251}\n`;
const enHashes = documentBlockHashes(parseDocument(en, "update_blocks").blocks);
const target = targetMdx(
[
{ label: "v0.26.0", body: "* **Krea2**: first draft", date: "June 23, 2026" },
{ label: "v0.25.1", body: "* Kling", date: "June 16, 2026" },
],
{
"v0.26.0": blockHash(v026),
"v0.25.1": enHashes["v0.25.1"]!,
}
);
const status = getSectionSyncStatus(en, target, "update_blocks", false, "zh");
expect(status.pendingBlocks).toEqual(["v0.26.0"]);
expect(status.upToDate).toBe(false);
});
test("re-translates when block exists but hash entry is missing", () => {
const en = `---\n---\n${v026}\n\n${v0251}\n`;
const enHashes = documentBlockHashes(parseDocument(en, "update_blocks").blocks);
const target = targetMdx(
[
{ label: "v0.26.0", body: "* **Krea2**: first draft", date: "June 23, 2026" },
{ label: "v0.25.1", body: "* Kling", date: "June 16, 2026" },
],
{ "v0.25.1": enHashes["v0.25.1"]! }
);
const status = getSectionSyncStatus(en, target, "update_blocks", false, "zh");
expect(status.pendingBlocks).toEqual(["v0.26.0"]);
});
});
describe("getSectionSyncStatus update_blocks", () => {
const v026 = enBlock("v0.26.0", "* **Krea2**: first draft", "June 23, 2026");
const v026Edited = enBlock("v0.26.0", "* **Krea2**: option C", "June 23, 2026");
const v0251 = enBlock("v0.25.1", "* **Kling**", "June 16, 2026");
test("marks new version labels as pending", () => {
const en = `---\n---\n${v026}\n\n${v0251}\n`;
const target = targetMdx(
[{ label: "v0.25.1", body: "* Kling", date: "June 16, 2026" }],
{ "v0.25.1": blockHash(v0251) }
);
const status = getSectionSyncStatus(en, target, "update_blocks", false, "zh");
expect(status.pendingBlocks).toEqual(["v0.26.0"]);
expect(status.upToDate).toBe(false);
});
test("skips blocks when stored hash matches English", () => {
const en = `---\n---\n${v026}\n\n${v0251}\n`;
const enHashes = documentBlockHashes(parseDocument(en, "update_blocks").blocks);
const target = targetMdx(
[
{ label: "v0.26.0", body: "* **Krea2**: first draft", date: "2026年6月23日" },
{ label: "v0.25.1", body: "* Kling", date: "2026年6月16日" },
],
enHashes
);
const status = getSectionSyncStatus(en, target, "update_blocks", false, "zh");
expect(status.pendingBlocks).toEqual([]);
expect(status.upToDate).toBe(true);
});
test("re-translates when English block content changes", () => {
const en = `---\n---\n${v026Edited}\n\n${v0251}\n`;
const enHashes = documentBlockHashes(parseDocument(en, "update_blocks").blocks);
const target = targetMdx(
[
{ label: "v0.26.0", body: "* **Krea2**: first draft", date: "June 23, 2026" },
{ label: "v0.25.1", body: "* Kling", date: "June 16, 2026" },
],
{
"v0.26.0": blockHash(v026),
"v0.25.1": enHashes["v0.25.1"]!,
}
);
const status = getSectionSyncStatus(en, target, "update_blocks", false, "zh");
expect(status.pendingBlocks).toEqual(["v0.26.0"]);
expect(status.upToDate).toBe(false);
});
test("re-translates when block exists but hash entry is missing", () => {
const en = `---\n---\n${v026}\n\n${v0251}\n`;
const enHashes = documentBlockHashes(parseDocument(en, "update_blocks").blocks);
const target = targetMdx(
[
{ label: "v0.26.0", body: "* **Krea2**: first draft", date: "June 23, 2026" },
{ label: "v0.25.1", body: "* Kling", date: "June 16, 2026" },
],
{ "v0.25.1": enHashes["v0.25.1"]! }
);
const status = getSectionSyncStatus(en, target, "update_blocks", false, "zh");
expect(status.pendingBlocks).toEqual(["v0.26.0"]);
});
test("marks structure drift when target contains extra block label", () => {
const en = `---\n---\n${v026}\n\n${v0251}\n`;
const enHashes = documentBlockHashes(parseDocument(en, "update_blocks").blocks);
const extra = enBlock("v9.9.9", "* stray localized block", "2026年6月1日");
const target = targetMdx(
[
{ label: "v0.26.0", body: "* **Krea2**: first draft", date: "2026年6月23日" },
{ label: "v0.25.1", body: "* Kling", date: "2026年6月16日" },
{ label: "v9.9.9", body: "* stray localized block", date: "2026年6月1日" },
],
enHashes
) + `\n${extra}\n`;
const status = getSectionSyncStatus(en, target, "update_blocks", false, "zh");
expect(status.upToDate).toBe(false);
expect(status.needsReserialize).toBe(true);
});
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/scripts/i18n/chunked-translate.test.ts around lines 29 - 91, Add a
new test case within the "getSectionSyncStatus update_blocks" describe block
that verifies handling of target-only `<Update>` labels. Create a test where the
English document contains v0.26.0 and v0.25.1, but the target document includes
an additional block label (such as v0.27.0) that does not exist in the English
version and is not present in the translationBlockHashes object passed to
getSectionSyncStatus. The test should verify that getSectionSyncStatus correctly
identifies and handles this extra block in the target to prevent regression of
the drift detection logic.

Comment on lines +629 to +644
const hasStructureDrift = Object.keys(storedHashes).some((k) => !(k in enHashes));
const hasDateDrift = langCode
? hasChangelogDateDrift(enContent, existingContent, langCode)
: false;
return {
upToDate: pendingBlocks.length === 0 && !hasOrderDrift && !hasDateDrift,
upToDate:
pendingBlocks.length === 0 &&
!hasOrderDrift &&
!hasDateDrift &&
!hasStructureDrift,
pendingBlocks,
needsFrontmatter: existingDoc.blocks.length === 0,
needsReserialize: pendingBlocks.length === 0 && (hasOrderDrift || hasDateDrift),
needsFrontmatter:
existingDoc.blocks.length === 0 || Object.keys(storedHashes).length === 0,
needsReserialize:
pendingBlocks.length === 0 &&
(hasOrderDrift || hasDateDrift || hasStructureDrift),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Detect target-only block labels in structure drift (let’s hash this out before drift slips out).

Line 629 only checks translationBlockHashes keys, so extra localized <Update> labels present in body (but missing from frontmatter map) are invisible to drift detection. That can make Line 634 report upToDate: true and skip cleanup/re-serialization.

💡 Proposed fix
   if (strategy === "update_blocks") {
     const storedHashes = parseBlockHashesFromFrontmatter(existingFmBody);
     const existingLabels = new Set(existingDoc.blocks.map((b) => b.label));
@@
-    const hasStructureDrift = Object.keys(storedHashes).some((k) => !(k in enHashes));
+    const hasStructureDrift =
+      Object.keys(storedHashes).some((k) => !(k in enHashes)) ||
+      [...existingLabels].some((label) => !(label in enHashes));

Based on learnings: English is the source of truth for documentation in this repository.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/scripts/i18n/chunked-translate.ts around lines 629 - 644, The
hasStructureDrift check on line 629 only detects when English has blocks missing
from the target language by checking if storedHashes keys are missing from
enHashes. However, it does not detect the reverse case where the target language
(existingContent) has extra localized blocks or labels that don't exist in the
English source. Extend the hasStructureDrift calculation to also check if the
target language content contains any blocks or labels that aren't present in
enHashes, ensuring bidirectional drift detection since English is the source of
truth for documentation structure.

Source: Learnings

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ko/changelog/index.mdx (1)

1-3: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Remove the extra frontmatter fence at Line 2.

The second --- closes frontmatter immediately, so metadata below can be treated as body content. Tiny fence, big offense.

🛠️ Proposed fix
 ---
----
 title: "변경 로그"
 description: "ComfyUI의 최신 기능, 개선 사항 및 버그 수정을 추적하세요. 자세한 릴리스 노트는 [Github 릴리스](https://github.com/Comfy-Org/ComfyUI/releases) 페이지를 참조하세요."
 icon: "clock-rotate-left"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ko/changelog/index.mdx` around lines 1 - 3, The frontmatter section has
duplicate opening fences that cause the metadata to be treated as body content.
Remove the second `---` fence that appears immediately after the first one,
ensuring only a single opening `---` precedes the frontmatter metadata like
title, followed by a single closing `---` after all metadata declarations. This
allows the YAML frontmatter to be properly parsed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@ko/changelog/index.mdx`:
- Around line 1-3: The frontmatter section has duplicate opening fences that
cause the metadata to be treated as body content. Remove the second `---` fence
that appears immediately after the first one, ensuring only a single opening
`---` precedes the frontmatter metadata like title, followed by a single closing
`---` after all metadata declarations. This allows the YAML frontmatter to be
properly parsed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3c72d1f1-1d69-46c1-8b31-9a5cac9b9b41

📥 Commits

Reviewing files that changed from the base of the PR and between b53372c and 0390213.

📒 Files selected for processing (4)
  • changelog/index.mdx
  • ja/changelog/index.mdx
  • ko/changelog/index.mdx
  • zh/changelog/index.mdx

Align skill/README with **Section** popup format (not ##) and reorder sync update-published handling for clarity.
@comfyui-wiki
comfyui-wiki merged commit 2d6108a into main Jun 24, 2026
11 checks passed
@github-actions
github-actions Bot deleted the changelog/v0.26.0 branch June 24, 2026 01:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant