Skip to content

feat(i18n): add OpenAPI translation pipeline and localized specs#1249

Open
comfyui-wiki wants to merge 2 commits into
mainfrom
feat/openapi-i18n
Open

feat(i18n): add OpenAPI translation pipeline and localized specs#1249
comfyui-wiki wants to merge 2 commits into
mainfrom
feat/openapi-i18n

Conversation

@comfyui-wiki

Copy link
Copy Markdown
Member

Wire cloud and registry OpenAPI specs into pnpm translate with per-language YAML under openapi/, Mintlify docs.json paths per locale, and pretty-printed output for readable zh/ja/ko API reference pages.

Wire cloud and registry OpenAPI specs into pnpm translate with per-language
YAML under openapi/, Mintlify docs.json paths per locale, and pretty-printed
output for readable zh/ja/ko API reference pages.
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

OpenAPI specifications now support locale-specific translation, incremental hash tracking, optional registry refreshes, localized documentation references, synchronization checks, and dedicated translation and reformatting commands.

OpenAPI translation engine

Layer / File(s) Summary
Spec translation and incremental state
.github/scripts/i18n/openapi-translate.ts, .github/scripts/i18n/openapi-translate.test.ts, openapi/.i18n/*
Translatable summary and description fields are extracted, translated in batches, written to YAML or JSON, and tracked with per-language sidecar hashes.
Source formatting and fetching
.github/scripts/i18n/openapi-translate.ts, .github/scripts/i18n/reformat-openapi.ts
English sources can be fetched from configured URLs, while generated YAML files can be reformatted with preserved headers.

Translation CLI and configuration

Layer / File(s) Summary
OpenAPI translation phase
.github/scripts/i18n/translate-i18n.ts, .github/scripts/i18n/translation-config.json, package.json
Adds OpenAPI configuration, batch translation, retry handling, filtering, dry-run support, and --openapi-only, --no-openapi, and --fetch-openapi controls.

Locale synchronization and validation

Layer / File(s) Summary
Localized references and sync checks
.github/scripts/i18n/sync-docs-json.mjs, .github/scripts/i18n/check-i18n-sync.mjs, .github/workflows/i18n-sync-check.yml, docs.json
Locale codes are applied to OpenAPI source paths, changed English specs require corresponding localized updates, and navigation references point to locale-specific files.
Cloud API documentation links
development/cloud/openapi.mdx, */development/cloud/openapi.mdx
Cloud API front matter and download links now reference openapi/cloud.en.yaml.

Workflow documentation

Layer / File(s) Summary
OpenAPI i18n workflow docs
.cursor/skills/docs-i18n-translate/SKILL.md, .github/scripts/i18n/README.md
Documents OpenAPI localization, generated endpoint pages, sidecar metadata, synchronization, and related commands.

Sequence Diagram(s)

sequenceDiagram
  participant Translator
  participant translate_i18n as translate-i18n.ts
  participant specs as OpenAPI specs
  participant docs_json as docs.json
  Translator->>translate_i18n: Run OpenAPI translation
  translate_i18n->>specs: Read, translate, and write locale files
  specs-->>translate_i18n: Return translation state
  Translator->>docs_json: Run documentation synchronization
  docs_json->>specs: Reference locale-specific sources
Loading
🚥 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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/openapi-i18n
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/openapi-i18n

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.

@mintlify

mintlify Bot commented Jul 10, 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 Jul 10, 2026, 9:09 AM

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

@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: 9

🤖 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/i18n/check-i18n-sync.mjs:
- Around line 75-81: Consolidate the duplicated localizedOpenApiSource logic by
moving it into a shared .mjs utility usable by Node scripts, then import and use
that utility in localizedOpenApiSource within check-i18n-sync.mjs and the
corresponding sync-docs-json.mjs helper; remove the duplicate implementations
while preserving existing English and extension handling.

In @.github/scripts/i18n/openapi-translate.ts:
- Around line 237-250: Prevent dry-run executions from writing fetched OpenAPI
sources: update ensureEnglishOpenApiSource and its callers to receive dryRun,
and skip writeSpecFile when dryRun is true while still allowing fetch/parse as
needed. Alternatively, disable fetchOpenApi whenever dry-run is active, ensuring
registry files are never overwritten.
- Around line 317-321: The unchanged check should treat retained English
translations as complete instead of reprocessing them. In the logic computing
unchanged in the translation workflow, replace the value-difference requirement
with an own-property check on existingStrings for path, while preserving the
force and matching sidecar block-hash conditions.
- Around line 89-112: The current string-based path handling in
extractTranslatableStrings and parsePath loses OpenAPI key boundaries when keys
contain dots or brackets, causing setAtPath to miss translations. Replace the
path representation with a lossless segment array or JSON Pointer, update
parsePath and the corresponding setAtPath logic to preserve literal key names,
then regenerate the translation sidecars.
- Line 237: Bound the registry request in the fetch logic surrounding
fetch(spec.fetch_url) by using an AbortController with a finite timeout and
passing its signal to fetch. Ensure the timeout is cleared after completion and
translate an abort into a clear timeout error so the translation run fails
promptly.

In @.github/scripts/i18n/README.md:
- Around line 71-72: Correct the README documentation to state that generated
sidecars are written under openapi/.i18n/ and use the cloud.zh.json filename
pattern, rather than being colocated with translated specs as *.i18n.json;
update the “Sidecar metadata” guidance accordingly.
- Around line 48-50: The README’s sidecar path documentation is incorrect:
update the note describing translated OpenAPI JSON sidecars to state that they
are written under `openapi/.i18n/<basename>.json`, rather than beside each
translated specification.

In @.github/scripts/i18n/sync-docs-json.mjs:
- Around line 322-329: Consolidate the duplicated OpenAPI localization logic
into the shared i18n-config.mjs module, using one consistent name such as
localizedOpenApiSource. Remove the local implementation from sync-docs-json.mjs
and check-i18n-sync.mjs, import the shared utility there, and update
openapi-translate.ts to reuse or clearly reference the shared implementation so
all callers have a single source of truth.

In @.github/workflows/i18n-sync-check.yml:
- Around line 10-11: Replace the hardcoded OpenAPI paths in the workflow trigger
list with glob patterns covering all English YAML and JSON sources, such as
openapi/*.en.yaml and openapi/*.en.json, so new translation sources are included
automatically. Also add job-level concurrency using the i18n-sync-check-${{
github.head_ref }} group with cancel-in-progress enabled.
🪄 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: b5845f0e-482a-4786-b0bf-bf8356ed9edf

📥 Commits

Reviewing files that changed from the base of the PR and between 36378b6 and 3b6f89a.

📒 Files selected for processing (30)
  • .cursor/skills/docs-i18n-translate/SKILL.md
  • .github/scripts/i18n/README.md
  • .github/scripts/i18n/check-i18n-sync.mjs
  • .github/scripts/i18n/openapi-translate.test.ts
  • .github/scripts/i18n/openapi-translate.ts
  • .github/scripts/i18n/reformat-openapi.ts
  • .github/scripts/i18n/sync-docs-json.mjs
  • .github/scripts/i18n/translate-i18n.ts
  • .github/scripts/i18n/translation-config.json
  • .github/workflows/i18n-sync-check.yml
  • development/cloud/openapi.mdx
  • docs.json
  • ja/development/cloud/openapi.mdx
  • ko/development/cloud/openapi.mdx
  • openapi/.i18n/cloud.ja.json
  • openapi/.i18n/cloud.ko.json
  • openapi/.i18n/cloud.zh.json
  • openapi/.i18n/registry.ja.json
  • openapi/.i18n/registry.ko.json
  • openapi/.i18n/registry.zh.json
  • openapi/cloud.en.yaml
  • openapi/cloud.ja.yaml
  • openapi/cloud.ko.yaml
  • openapi/cloud.zh.yaml
  • openapi/registry.en.yaml
  • openapi/registry.ja.yaml
  • openapi/registry.ko.yaml
  • openapi/registry.zh.yaml
  • package.json
  • zh/development/cloud/openapi.mdx

Comment on lines +75 to +81
function localizedOpenApiSource(source, langCode) {
if (!source || langCode === "en") return source;
if (/\.en\.(ya?ml|json)$/i.test(source)) {
return source.replace(/\.en\.(ya?ml|json)$/i, (_, ext) => `.${langCode}.${ext}`);
}
return source.replace(/\.(ya?ml|json)$/i, (_, ext) => `.${langCode}.${ext}`);
}

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

localizedOpenApiSource duplicates the same function in openapi-translate.ts and sync-docs-json.mjs.

This is the same DRY concern raised on sync-docs-json.mjs lines 322-329. The function here is identical to the exported localizedOpenApiSource in openapi-translate.ts (line 49) and the localizeOpenApiSource in sync-docs-json.mjs (line 323). Since check-i18n-sync.mjs runs under node (per the workflow), it cannot import the .ts file directly, but it could import from a shared .mjs utility.

See the proposed consolidation in the comment on sync-docs-json.mjs.

🤖 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/check-i18n-sync.mjs around lines 75 - 81, Consolidate
the duplicated localizedOpenApiSource logic by moving it into a shared .mjs
utility usable by Node scripts, then import and use that utility in
localizedOpenApiSource within check-i18n-sync.mjs and the corresponding
sync-docs-json.mjs helper; remove the duplicate implementations while preserving
existing English and extension handling.

Comment on lines +89 to +112
const childPath = path ? `${path}.${key}` : key;
if (
TRANSLATABLE_KEYS.has(key) &&
typeof child === "string" &&
child.trim().length > 0
) {
out[childPath] = child;
} else {
Object.assign(out, extractTranslatableStrings(child, childPath));
}
}

return out;
}

function parsePath(path: string): Array<string | number> {
const parts: Array<string | number> = [];
const re = /([^.\[\]]+)|\[(\d+)\]/g;
let match: RegExpExecArray | null;
while ((match = re.exec(path)) !== null) {
if (match[1] != null) parts.push(match[1]);
else if (match[2] != null) parts.push(Number(match[2]));
}
return parts;

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 | 🟠 Major | 🏗️ Heavy lift

Use a lossless path format.

parsePath treats . and [] as syntax, but OpenAPI keys may contain them. For example, paths./v1/foo.bar.get.summary is split incorrectly, so setAtPath silently leaves that translation untranslated. Use JSON Pointer or segment arrays, then regenerate the sidecars.

Also applies to: 124-135

🧰 Tools
🪛 OpenGrep (1.23.0)

[ERROR] 108-108: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

🤖 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/openapi-translate.ts around lines 89 - 112, The current
string-based path handling in extractTranslatableStrings and parsePath loses
OpenAPI key boundaries when keys contain dots or brackets, causing setAtPath to
miss translations. Replace the path representation with a lossless segment array
or JSON Pointer, update parsePath and the corresponding setAtPath logic to
preserve literal key names, then regenerate the translation sidecars.

if (!spec.fetch_url) return;

console.log(`[openapi] Fetching ${spec.source} from ${spec.fetch_url} ...`);
const response = await fetch(spec.fetch_url);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- file info ---'
wc -l .github/scripts/i18n/openapi-translate.ts
echo '--- around target lines ---'
sed -n '200,280p' .github/scripts/i18n/openapi-translate.ts
echo '--- search timeout usage in repo ---'
rg -n "AbortSignal\.timeout|signal:\s*AbortSignal|fetch\(" .github/scripts -S

Repository: Comfy-Org/docs

Length of output: 4183


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- references to openapi-translate ---'
rg -n "openapi-translate|ensureEnglishOpenApiSource|fetchOpenApi" . -S

echo '--- workflow timeouts / job wrappers near references ---'
rg -n "timeout-minutes|timeout\s*:" .github/workflows .github -S

Repository: Comfy-Org/docs

Length of output: 192


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- github files ---'
git ls-files .github | sed -n '1,200p'

echo '--- search for script invocation patterns ---'
rg -n "openapi|i18n|bun .*openapi|scripts/i18n" .github -S

echo '--- workflows with timeouts ---'
rg -n "timeout-minutes|timeout:" .github/workflows -S

Repository: Comfy-Org/docs

Length of output: 27238


Bound the registry fetch. In .github/scripts/i18n/openapi-translate.ts:237, fetch(spec.fetch_url) can hang the whole translation run if the upstream stalls. Add an abort timeout and surface a timeout error so the job doesn’t sit there playing possum.

🤖 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/openapi-translate.ts at line 237, Bound the registry
request in the fetch logic surrounding fetch(spec.fetch_url) by using an
AbortController with a finite timeout and passing its signal to fetch. Ensure
the timeout is cleared after completion and translate an abort into a clear
timeout error so the translation run fails promptly.

Comment on lines +237 to +250
const response = await fetch(spec.fetch_url);
if (!response.ok) {
throw new Error(`Failed to fetch ${spec.fetch_url}: HTTP ${response.status}`);
}

const format = spec.fetch_format ?? "json";
let parsed: Record<string, unknown>;
if (format === "yaml") {
parsed = Bun.YAML.parse(await response.text()) as Record<string, unknown>;
} else {
parsed = (await response.json()) as Record<string, unknown>;
}

await writeSpecFile(absPath, parsed);

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 | 🟠 Major | ⚡ Quick win

Do not write fetched sources during a dry run.

--dry-run --fetch-openapi reaches this write path and overwrites openapi/registry.en.yaml. Pass dryRun into ensureEnglishOpenApiSource and skip the refresh write, or suppress fetchOpenApi when dry-run is active.

🤖 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/openapi-translate.ts around lines 237 - 250, Prevent
dry-run executions from writing fetched OpenAPI sources: update
ensureEnglishOpenApiSource and its callers to receive dryRun, and skip
writeSpecFile when dryRun is true while still allowing fetch/parse as needed.
Alternatively, disable fetchOpenApi whenever dry-run is active, ensuring
registry files are never overwritten.

Comment on lines +317 to +321
const unchanged =
!options.force &&
sidecar?.blockHashes?.[path] === hash &&
existingStrings[path] &&
existingStrings[path] !== enText;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Treat successfully retained English values as complete.

The existingStrings[path] !== enText check makes values that legitimately remain identical to English pending forever, even after their sidecar hash is recorded. This repeats model calls on every run. Check for an own output entry instead of requiring a different value.

🤖 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/openapi-translate.ts around lines 317 - 321, The
unchanged check should treat retained English translations as complete instead
of reprocessing them. In the logic computing unchanged in the translation
workflow, replace the value-difference requirement with an own-property check on
existingStrings for path, while preserving the force and matching sidecar
block-hash conditions.

Comment on lines +48 to +50
pnpm translate -- --openapi-only # OpenAPI specs only
pnpm translate -- --no-openapi # skip OpenAPI specs
pnpm translate -- --fetch-openapi # refresh vendored specs from fetch_url

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== files ==\n'
git ls-files '.github/scripts/i18n/README.md' 'SKILL.md' 'package.json' 'pnpm-workspace.yaml' '.github/scripts/i18n/*' | sed 's#^`#-` #'

printf '\n== search translate/openapi refs ==\n'
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' --glob '!coverage' \
  'translate:openapi|openapi-only|no-openapi|fetch-openapi|openapi/.i18n|vendored specs|fetch_url|sidecar' \
  .github/scripts/i18n README.md SKILL.md package.json . 2>/dev/null || true

printf '\n== package scripts ==\n'
python3 - <<'PY'
import json, pathlib
for p in ['package.json', 'pnpm-workspace.yaml']:
    path = pathlib.Path(p)
    if path.exists():
        print(f'--- {p} ---')
        if p.endswith('.json'):
            data = json.loads(path.read_text())
            scripts = data.get('scripts', {})
            for k,v in scripts.items():
                if 'translate' in k or 'translate' in str(v) or 'openapi' in str(v):
                    print(k, '=>', v)
        else:
            print(path.read_text())
PY

printf '\n== README excerpt ==\n'
sed -n '1,140p' .github/scripts/i18n/README.md

printf '\n== SKILL excerpt ==\n'
sed -n '1,220p' SKILL.md

Repository: Comfy-Org/docs

Length of output: 19010


Correct the sidecar path note. Lines 67-72 describe the JSON sidecar as living beside each translated spec, but it is written under openapi/.i18n/<basename>.json.

🤖 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/README.md around lines 48 - 50, The README’s sidecar
path documentation is incorrect: update the note describing translated OpenAPI
JSON sidecars to state that they are written under
`openapi/.i18n/<basename>.json`, rather than beside each translated
specification.

Comment on lines +71 to +72
Sidecar metadata lives beside each translated spec as `*.i18n.json` (block hashes
for incremental sync). Commit translated specs and sidecars with MDX translations.

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 | 🟡 Minor | ⚡ Quick win

Correct the generated sidecar path and filename.

openapi-translate.ts writes sidecars under openapi/.i18n/, for example openapi/.i18n/cloud.zh.json. They are not beside the translated spec and are not named cloud.zh.i18n.json.

Suggested correction
-Sidecar metadata lives beside each translated spec as `*.i18n.json` (block hashes
-for incremental sync). Commit translated specs and sidecars with MDX translations.
+Sidecar metadata lives under `openapi/.i18n/` as `<spec>.<lang>.json` (block hashes
+for incremental sync). Commit translated specs and sidecars with MDX translations.
📝 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
Sidecar metadata lives beside each translated spec as `*.i18n.json` (block hashes
for incremental sync). Commit translated specs and sidecars with MDX translations.
Sidecar metadata lives under `openapi/.i18n/` as `<spec>.<lang>.json` (block hashes
for incremental sync). Commit translated specs and sidecars with MDX translations.
🤖 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/README.md around lines 71 - 72, Correct the README
documentation to state that generated sidecars are written under openapi/.i18n/
and use the cloud.zh.json filename pattern, rather than being colocated with
translated specs as *.i18n.json; update the “Sidecar metadata” guidance
accordingly.

Comment on lines +322 to +329
/** @param {string} source @param {string} langCode */
export function localizeOpenApiSource(source, langCode) {
if (!source || langCode === "en") return source;
if (/\.en\.(ya?ml|json)$/i.test(source)) {
return source.replace(/\.en\.(ya?ml|json)$/i, (_, ext) => `.${langCode}.${ext}`);
}
return source.replace(/\.(ya?ml|json)$/i, (_, ext) => `.${langCode}.${ext}`);
}

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

Consolidate duplicated localizeOpenApiSource to avoid drift and naming inconsistency.

This function is identical in logic to localizedOpenApiSource in openapi-translate.ts (line 49, exported) and check-i18n-sync.mjs (line 75, local). The name differs (localize vs localized), which could cause confusion when cross-referencing. If the regex or suffix convention changes, all three copies must be updated in sync.

Consider extracting this into the shared i18n-config.mjs module (already imported by other scripts) and importing it in both .mjs files. The TypeScript copy in openapi-translate.ts can re-export from the shared module or remain standalone with a comment linking the two.

When it comes to DRY, don't be shy — a single source of truth keeps the bugs from multiplying.

♻️ Proposed shared utility in i18n-config.mjs
# In i18n-config.mjs, add:

+export function localizedOpenApiSource(source, langCode) {
+  if (!source || langCode === "en") return source;
+  if (/\.en\.(ya?ml|json)$/i.test(source)) {
+    return source.replace(/\.en\.(ya?ml|json)$/i, (_, ext) => `.${langCode}.${ext}`);
+  }
+  return source.replace(/\.(ya?ml|json)$/i, (_, ext) => `.${langCode}.${ext}`);
+}
# In sync-docs-json.mjs:

-import { ... } from "./i18n-config.mjs";
+import { ..., localizedOpenApiSource } from "./i18n-config.mjs";

-export function localizeOpenApiSource(source, langCode) {
-  if (!source || langCode === "en") return source;
-  if (/\.en\.(ya?ml|json)$/i.test(source)) {
-    return source.replace(/\.en\.(ya?ml|json)$/i, (_, ext) => `.${langCode}.${ext}`);
-  }
-  return source.replace(/\.(ya?ml|json)$/i, (_, ext) => `.${langCode}.${ext}`);
-}
# In check-i18n-sync.mjs:

+import { localizedOpenApiSource } from "./i18n-config.mjs";

-function localizedOpenApiSource(source, langCode) {
-  if (!source || langCode === "en") return source;
-  if (/\.en\.(ya?ml|json)$/i.test(source)) {
-    return source.replace(/\.en\.(ya?ml|json)$/i, (_, ext) => `.${langCode}.${ext}`);
-  }
-  return source.replace(/\.(ya?ml|json)$/i, (_, ext) => `.${langCode}.${ext}`);
-}
🤖 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/sync-docs-json.mjs around lines 322 - 329, Consolidate
the duplicated OpenAPI localization logic into the shared i18n-config.mjs
module, using one consistent name such as localizedOpenApiSource. Remove the
local implementation from sync-docs-json.mjs and check-i18n-sync.mjs, import the
shared utility there, and update openapi-translate.ts to reuse or clearly
reference the shared implementation so all callers have a single source of
truth.

Comment on lines +10 to +11
- 'openapi/cloud.en.yaml'
- 'openapi/registry.en.yaml'

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 | 💤 Low value

Consider a glob pattern for OpenAPI path triggers to reduce future maintenance.

Hardcoding openapi/cloud.en.yaml and openapi/registry.en.yaml means any new OpenAPI source file added to translation-config.json also requires updating this workflow. A glob like openapi/*.en.yaml and openapi/*.en.json would auto-cover new English sources.

The zizmor hint about missing job-level concurrency limits is also worth addressing (e.g., concurrency: { group: i18n-sync-check-${{ github.head_ref }}, cancel-in-progress: true }), though that's pre-existing and not introduced by this PR.

🧰 Tools
🪛 zizmor (1.26.1)

[warning] 3-11: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting

(concurrency-limits)

🤖 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/workflows/i18n-sync-check.yml around lines 10 - 11, Replace the
hardcoded OpenAPI paths in the workflow trigger list with glob patterns covering
all English YAML and JSON sources, such as openapi/*.en.yaml and
openapi/*.en.json, so new translation sources are included automatically. Also
add job-level concurrency using the i18n-sync-check-${{ github.head_ref }} group
with cancel-in-progress enabled.

Source: Linters/SAST tools

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