Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/actions/lint-format-verify/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ runs:
pnpm format:check
pnpm knip

- name: Verify locale integrity
shell: bash
run: pnpm locale:check
Comment on lines +20 to +22

Copy link
Copy Markdown
Contributor

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

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -l 'lint-format-verify' .github/workflows | while IFS= read -r workflow; do
  printf '\n=== %s ===\n' "$workflow"
  rg -n -C 12 \
    'lint-format-verify|actions/checkout|fetch-depth|filter:' \
    "$workflow" || true
done

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2838


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '=== action ==='
cat -n .github/actions/lint-format-verify/action.yml

printf '%s\n' '=== locale updater symbols ==='
rg -n -C 8 \
  'locale:check|check|cat-file|manifest|source|translation' \
  scripts/i18n/update-locales.ts

printf '%s\n' '=== all action callers ==='
rg -n -C 8 \
  '(\./)?\.github/actions/lint-format-verify|lint-format-verify' \
  .github

printf '%s\n' '=== checkout configuration in all workflows ==='
rg -n -C 5 \
  'actions/checkout|fetch-depth|filter:|sparse-checkout|fetch-tags' \
  .github/workflows

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 50383


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

root = Path(".github/workflows")
callers = []
for path in sorted(root.glob("*")):
    if not path.is_file():
        continue
    lines = path.read_text().splitlines()
    for i, line in enumerate(lines):
        if re.search(r"uses:\s+\./\.github/actions/lint-format-verify\s*$", line):
            # Find the enclosing steps item and its preceding checkout step in the same job.
            caller = {"file": str(path), "use_line": i + 1, "checkout": None}
            job_indent = len(line) - len(line.lstrip())
            j = i - 1
            while j >= 0:
                indent = len(lines[j]) - len(lines[j].lstrip())
                if indent < job_indent and re.match(r"\s*steps:\s*$", lines[j]):
                    break
                if re.search(r"uses:\s+actions/checkout@", lines[j]):
                    checkout = {"line": j + 1, "fetch_depth": None}
                    k = j + 1
                    while k < len(lines):
                        next_indent = len(lines[k]) - len(lines[k].lstrip())
                        if lines[k].strip() and next_indent <= indent:
                            break
                        m = re.match(r"\s*fetch-depth:\s*(\S+)", lines[k])
                        if m:
                            checkout["fetch_depth"] = m.group(1)
                        k += 1
                    caller["checkout"] = checkout
                    break
                j -= 1
            callers.append(caller)

print("DIRECT_CALLERS")
for caller in callers:
    print(caller)
print(f"COUNT={len(callers)}")
PY

printf '%s\n' '=== locale:check definition ==='
rg -n -C 4 '"locale:check"|locale:check' package.json pnpm-lock.yaml scripts 2>/dev/null || true

printf '%s\n' '=== manifest files and recorded hashes ==='
fd -a -t f '.source-manifest.json|package.json' src scripts .
rg -n '"files"|"version"|\.json"|[0-9a-f]{40,64}' src/locales/.source-manifest.json 2>/dev/null | head -80 || true

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2119


Fetch the locale manifest history in both callers

Neither caller sets fetch-depth: 0. Add it to both checkout steps, or make locale:check fail when a manifest blob is unavailable. Otherwise, changed-string detection is skipped and stale translations can pass CI.

🤖 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/actions/lint-format-verify/action.yml around lines 20 - 22, Update
both checkout steps used by the locale integrity callers to set fetch-depth: 0,
ensuring locale:check can access manifest history for changed-string detection.
Preserve the existing pnpm locale:check invocation and apply the checkout
configuration consistently in both callers.


- name: Typecheck browser tests
shell: bash
run: pnpm typecheck:browser
6 changes: 6 additions & 0 deletions .github/workflows/ci-lint-format-queue.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ jobs:
steps:
- name: Checkout ref
uses: actions/checkout@v7
with:
# Blobless full history: pnpm locale:check (lint-format-verify)
# fetches the English source blobs recorded in
# src/locales/.source-manifest.json
fetch-depth: 0
filter: blob:none

- name: Setup frontend
uses: ./.github/actions/setup-frontend
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/ci-lint-format.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ jobs:
with:
ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || github.ref }}
token: ${{ !github.event.pull_request.head.repo.fork && secrets.PR_GH_TOKEN || github.token }}
# Blobless full history: pnpm locale:check (lint-format-verify)
# fetches the English source blobs recorded in
# src/locales/.source-manifest.json
fetch-depth: 0
filter: blob:none

- name: Setup frontend
uses: ./.github/actions/setup-frontend
Expand Down
21 changes: 20 additions & 1 deletion .github/workflows/i18n-update-core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ name: 'i18n: Update Core'
on:
# Manual dispatch for urgent translation updates
workflow_dispatch:
inputs:
allow_prune:
description: 'Confirm deletions larger than the prune threshold'
type: boolean
default: false
Comment on lines +7 to +11

Copy link
Copy Markdown
Contributor

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

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

file=.github/workflows/i18n-update-core.yaml
rg -n -C2 \
  'workflow_dispatch|allow_prune|github\.head_ref|github\.ref_name|git (fetch|checkout|push)' \
  "$file"

if rg -n 'git (fetch|checkout|push).*github\.head_ref' "$file"; then
  echo "Manual dispatch still uses the pull-request-only head_ref." >&2
  exit 1
fi

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1937


🏁 Script executed:

sed -n '1,120p' .github/workflows/i18n-update-core.yaml

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 3706


🌐 Web query:

GitHub Actions workflow_dispatch github.head_ref github.ref_name manual dispatch branch tag documentation

💡 Result:

When manually triggering a workflow via the workflow_dispatch event, you can specify a target branch or tag using the GitHub UI, GitHub CLI, or REST API [1][2]. The following clarifies the behavior of relevant GitHub context properties in this context: 1. github.ref_name: This context property correctly identifies the branch or tag name that was selected when the workflow was manually triggered [3][4]. It is the recommended property to use for referencing the current branch or tag in workflow_dispatch runs [4]. 2. github.head_ref: This property is only defined for pull_request and pull_request_target events [5][6][7]. It will be empty (undefined) for workflow_dispatch runs [4]. If you write a workflow that handles both pull_request and workflow_dispatch events, you should avoid relying on github.head_ref without providing a fallback (e.g., using ${{ github.head_ref || github.ref_name }}) to prevent errors [8]. In summary, for manual dispatches, github.ref_name provides the desired branch/tag context, while github.head_ref is not applicable [4][7].

Citations:


🏁 Script executed:

python3 - <<'PY'
from pathlib import Path
import re

p = Path(".github/workflows/i18n-update-core.yaml")
text = p.read_text()

manual_job = "github.event_name == 'workflow_dispatch'" in text
head_ref_commands = re.findall(r"git\s+(?:fetch|checkout|push)[^\n]*github\.head_ref", text)
ref_name_present = "github.ref_name" in text

print({
    "manual_dispatch_enables_job": manual_job,
    "commit_commands_using_head_ref": head_ref_commands,
    "ref_name_present": ref_name_present,
})
PY

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 418


Use the selected branch for manual dispatches.

Manual runs leave github.head_ref empty, so the fetch, checkout, and push commands do not target a branch. Use ${{ github.head_ref || github.ref_name }} and reject tag refs before pushing.

🤖 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-update-core.yaml around lines 7 - 11, Update the
workflow’s manual-dispatch branch handling to use `${{ github.head_ref ||
github.ref_name }}` for fetch, checkout, and push operations. Add validation
that rejects tag refs before any push occurs, while preserving the existing
branch behavior for pull-request runs.

Source: MCP tools

# Trigger on PRs to main and to release branches (core/x.y, cloud/x.y).
# Release branches need this so translations for backported locale keys are
# regenerated and baked into the version-bump PR, mirroring main. Additional
Expand All @@ -22,6 +27,10 @@ jobs:
uses: actions/checkout@v7
with:
token: ${{ secrets.PR_GH_TOKEN }}
# Blobless full history: the locale pipeline lazily fetches the
# English source blobs recorded in src/locales/.source-manifest.json
fetch-depth: 0
filter: blob:none

# Setup playwright environment
- name: Setup ComfyUI Frontend
Expand All @@ -46,7 +55,12 @@ jobs:
env:
PLAYWRIGHT_TEST_URL: http://localhost:5173
- name: Update translations
run: pnpm locale && pnpm format
id: translate
# continue-on-error so completed entry files (written and recorded in
# the manifest even when another file fails) still get committed; the
# final step re-surfaces the failure
continue-on-error: true
run: pnpm locale ${{ inputs.allow_prune == true && '--allow-prune' || '' }} && pnpm format
Comment on lines +58 to +63

Copy link
Copy Markdown
Contributor

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:

#!/usr/bin/env bash
set -euo pipefail

file=.github/workflows/i18n-update-core.yaml
rg -n -C2 \
  'id: translate|continue-on-error|pnpm locale|pnpm format|steps\.translate\.outcome' \
  "$file"

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1026


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

file=.github/workflows/i18n-update-core.yaml
sed -n '1,100p' "$file"
printf '\n--- package scripts ---\n'
rg -n -C2 '"(locale|format)"|locale|format' package.json pnpm-workspace.yaml 2>/dev/null || true

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 4582


🏁 Script executed:

#!/usr/bin/env bash
set -u

run_case() {
  local locale_status="$1"
  local format_status="$2"
  local outcome=success

  if (( locale_status == 0 )); then
    (( format_status == 0 )) || outcome=failure
  else
    outcome=failure
  fi

  printf 'pnpm locale=%s, pnpm format=%s -> steps.translate.outcome=%s\n' \
    "$locale_status" "$format_status" "$outcome"
}

run_case 0 0
run_case 0 1
run_case 1 0

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 356


Separate translation and formatting status

If pnpm locale succeeds but pnpm format fails, steps.translate.outcome is failure, so the final step incorrectly reports pnpm locale failed. Track formatting separately or record separate outcomes.

🤖 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-update-core.yaml around lines 58 - 63, Separate the
translation and formatting commands in the workflow so their outcomes are
tracked independently. Update the final failure-reporting step to distinguish a
failed pnpm locale command from a failed pnpm format command, while preserving
continue-on-error behavior for committing completed translation files.

Source: MCP tools

env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
- name: Commit updated locales
Expand All @@ -62,3 +76,8 @@ jobs:
git add src/locales/
git diff --staged --quiet || git commit -m "Update locales"
git push origin HEAD:${{ github.head_ref }}
- name: Fail if translation did not complete
if: steps.translate.outcome == 'failure'
run: |
echo "::error::pnpm locale failed; completed entry files were committed, the rest retry on the next run"
exit 1
5 changes: 5 additions & 0 deletions .github/workflows/i18n-update-custom-nodes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v7
with:
# Blobless full history: the locale pipeline lazily fetches the
# English source blobs recorded in src/locales/.source-manifest.json
fetch-depth: 0
filter: blob:none

# Setup playwright environment with custom node repository
- name: Setup ComfyUI Server (without launching)
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/i18n-update-nodes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v7
with:
# Blobless full history: the locale pipeline lazily fetches the
# English source blobs recorded in src/locales/.source-manifest.json
fetch-depth: 0
filter: blob:none
# Setup playwright environment
- name: Setup ComfyUI Server (and start)
uses: ./.github/actions/setup-comfyui-server
Expand Down
49 changes: 0 additions & 49 deletions .i18nrc.cjs

This file was deleted.

1 change: 1 addition & 0 deletions .oxfmtrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"packages/registry-types/src/comfyRegistryTypes.ts",
"public/materialdesignicons.min.css",
"src/types/generatedManagerTypes.ts",
"src/locales/**/*.json",
"**/__fixtures__/**/*.json",
"apps/website/src/content/**/*.mdx"
]
Expand Down
1 change: 0 additions & 1 deletion .oxlintrc.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"ignorePatterns": [
".i18nrc.cjs",
"**/vite.config.*.timestamp*",
"**/vitest.config.*.timestamp*",
"components.d.ts",
Expand Down
1 change: 0 additions & 1 deletion eslint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ const useVirtualListRestriction = {
export default defineConfig([
{
ignores: [
'.i18nrc.cjs',
'**/vite.config.*.timestamp*',
'**/vitest.config.*.timestamp*',
'components.d.ts',
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
"lint:unstaged": "git diff --name-only HEAD | grep -E '\\.(js|ts|vue|mts)$' | xargs -r eslint --cache",
"lint": "pnpm stylelint && oxlint src browser_tests --type-aware && eslint src --cache",
"lint:desktop": "pnpm --filter @comfyorg/desktop-ui run lint",
"locale": "lobe-i18n locale",
"locale": "tsx scripts/i18n/update-locales.ts",
"locale:check": "tsx scripts/i18n/update-locales.ts --check",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[quality] low SHOULD-FIX — locale:check is offline and cheap but isn't wired into any CI job, so drift is only caught during a release run where OPENAI_API_KEY is present and a failure blocks the release. Consider adding it to the standard PR checks; that is also where the placeholder audit from the protected-tokens.ts comment would earn its keep.

"oxlint": "oxlint src browser_tests --type-aware",
"prepare": "pnpm exec husky || true && git config blame.ignoreRevsFile .git-blame-ignore-revs || true",
"preview": "vite preview --config vite.config.mts",
Expand Down Expand Up @@ -141,7 +142,6 @@
"@comfyorg/ingest-types": "workspace:*",
"@eslint/js": "catalog:",
"@intlify/eslint-plugin-vue-i18n": "catalog:",
"@lobehub/i18n-cli": "catalog:",
"@pinia/testing": "catalog:",
"@playwright/test": "catalog:",
"@sentry/vite-plugin": "catalog:",
Expand Down Expand Up @@ -187,6 +187,7 @@
"markdown-table": "catalog:",
"mixpanel-browser": "catalog:",
"monocart-coverage-reports": "catalog:",
"openai": "catalog:",
"oxfmt": "catalog:",
"oxlint": "catalog:",
"oxlint-tsgolint": "catalog:",
Expand Down
Loading
Loading