[PR #3364] fix(custom-nodes-manager): show CNR update badge only when the registry version is actually newer #3234

Open
opened 2026-10-28 21:16:18 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/Comfy-Org/ComfyUI-Manager/pull/3364
Author: @zhaoruizhe81
Created: 10/10/2026
Status: 🔄 Open

Base: main ← Head: fix/cnr-version-semantic-compare


📝 Commits (1)

  • 22f8e9b fix(custom-nodes-manager): show CNR update badge only when the registry version is actually newer

📊 Changes

2 files changed (+176 additions, -1 deletions)

View changed files

📝 js/custom-nodes-manager.js (+29 -1)
➕ tests/test_version_badge_semver.py (+147 -0)

📄 Description

What

The Custom Nodes Manager's Version column decided whether to render the
[↑x.y.z] update badge with a bare string inequality
(js/custom-nodes-manager.js:755):

if(rowItem.cnr_latest && version != rowItem.cnr_latest) {

String comparison says "1.47.0" != "1.78.1", so a node installed at
1.78.1 was shown as updatable to 1.47.0 (#3272). The backend has been
comparing correctly all along — is_updatable in glob/manager_core.py
uses packaging versions via safe_version.

This PR adds a small module-level helper, compareVersionSpecs(a, b), that
compares dot-separated numeric specs (returns 1 / -1 / 0, or null when
either side is not fully numeric), and gates the ↑ badge on the registry
version being provably newer (cmp === 1). The nightly branch is
untouched. When the helper cannot parse a spec it returns null and the
formatter keeps the legacy string behavior, so exotic version strings behave
exactly as before.

Two side effects worth noting:

  • glob/manager_core.py:895 injects cnr_latest = '0.0.0' when the registry
    has no latest_version. Under the old string compare that rendered a
    nonsensical [↑0.0.0] badge; under the new compare it correctly renders none.
  • installNodeWithVersion (line 1361) uses cnr_latest != active_version to decide whether to offer latest in the version
    selector. Intentionally left unchanged: for an install that is newer
    than the registry (exactly #3272's case), that entry is the user's
    downgrade path back to the registry's active version. Making it
    semver-aware would silently remove that option — happy to follow up
    separately if maintainers want it.

Also adds tests/test_version_badge_semver.py, following the existing
tests/js_lift.py lift-and-execute pattern used by
test_pack_column_escaping.py / test_grid_highlight_escaping.py.

Why

#3272, confirmed in the comments: the semantic-version comparison problem is
valid (the example node additionally has a separate registry-status issue
tracked in registry-backend#233, which this PR does not address). A locally
newer install must not be flagged as outdated.

How verified

1. Lifted the shipped formatter verbatim (the tests/js_lift.py approach)
and executed it in node, before and after the patch
— same 9-case matrix
both sides:

Before (git show main:js/custom-nodes-manager.js), 3 failures — exactly the
reported bug plus two siblings:

FAIL  1.78.1 vs 1.47.0  ->  <div>1.78.1</div><div>[↑1.47.0]</div>   (issue #3272: locally newer must NOT be flagged)
FAIL  1.78.1 vs 0.0.0   ->  <div>1.78.1</div><div>[↑0.0.0]</div>    (backend 'no latest_version' sentinel: no badge)
FAIL  1.10.0 vs 1.2     ->  <div>1.10.0</div><div>[↑1.2]</div>      (numeric compare: no badge)

After the patch, all 9 pass — 1.78.1/1.47.0 no badge; 1.0.0/1.47.0 badge
kept; equal versions no badge; the 0.0.0 sentinel no badge; 1.2 vs
1.10.0 compared numerically both ways; the nightly branch output
byte-identical; unparseable specs (1.2.3rc1) keep legacy behavior.

2. The new test file reproduces RED -> GREEN:

MANAGER_JS_DIR=<dir populated from git show main:js/...> \
    python -m pytest tests/test_version_badge_semver.py   # 3 failed
python -m pytest tests/test_version_badge_semver.py       # 3 passed

3. Existing tests and lint are untouched: python -m pytest tests/ →
239 passed, 80 skipped (the skips are the E2E_ROOT-gated e2e suite); the
js_lift suites (test_pack_column_escaping.py,
test_grid_highlight_escaping.py) pass unchanged; ruff check . clean.

Fixes #3272


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/Comfy-Org/ComfyUI-Manager/pull/3364 **Author:** [@zhaoruizhe81](https://github.com/zhaoruizhe81) **Created:** 10/10/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `fix/cnr-version-semantic-compare` --- ### 📝 Commits (1) - [`22f8e9b`](https://github.com/Comfy-Org/ComfyUI-Manager/commit/22f8e9bfacfae5392438c2702054ddc65cb37691) fix(custom-nodes-manager): show CNR update badge only when the registry version is actually newer ### 📊 Changes **2 files changed** (+176 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `js/custom-nodes-manager.js` (+29 -1) ➕ `tests/test_version_badge_semver.py` (+147 -0) </details> ### 📄 Description ## What The Custom Nodes Manager's Version column decided whether to render the `[↑x.y.z]` update badge with a bare string inequality (`js/custom-nodes-manager.js:755`): ```js if(rowItem.cnr_latest && version != rowItem.cnr_latest) { ``` String comparison says `"1.47.0" != "1.78.1"`, so a node installed at **1.78.1** was shown as updatable to **1.47.0** (#3272). The backend has been comparing correctly all along — `is_updatable` in `glob/manager_core.py` uses `packaging` versions via `safe_version`. This PR adds a small module-level helper, `compareVersionSpecs(a, b)`, that compares dot-separated numeric specs (returns 1 / -1 / 0, or `null` when either side is not fully numeric), and gates the `↑` badge on the registry version being **provably newer** (`cmp === 1`). The `nightly` branch is untouched. When the helper cannot parse a spec it returns `null` and the formatter keeps the legacy string behavior, so exotic version strings behave exactly as before. Two side effects worth noting: - `glob/manager_core.py:895` injects `cnr_latest = '0.0.0'` when the registry has no `latest_version`. Under the old string compare that rendered a nonsensical `[↑0.0.0]` badge; under the new compare it correctly renders none. - `installNodeWithVersion` (line 1361) uses `cnr_latest != active_version` to decide whether to offer `latest` in the version selector. **Intentionally left unchanged**: for an install that is newer than the registry (exactly #3272's case), that entry is the user's downgrade path back to the registry's active version. Making it semver-aware would silently remove that option — happy to follow up separately if maintainers want it. Also adds `tests/test_version_badge_semver.py`, following the existing `tests/js_lift.py` lift-and-execute pattern used by `test_pack_column_escaping.py` / `test_grid_highlight_escaping.py`. ## Why #3272, confirmed in the comments: the semantic-version comparison problem is valid (the example node additionally has a separate registry-status issue tracked in registry-backend#233, which this PR does not address). A locally newer install must not be flagged as outdated. ## How verified **1. Lifted the shipped formatter verbatim (the `tests/js_lift.py` approach) and executed it in node, before and after the patch** — same 9-case matrix both sides: Before (`git show main:js/custom-nodes-manager.js`), 3 failures — exactly the reported bug plus two siblings: ``` FAIL 1.78.1 vs 1.47.0 -> <div>1.78.1</div><div>[↑1.47.0]</div> (issue #3272: locally newer must NOT be flagged) FAIL 1.78.1 vs 0.0.0 -> <div>1.78.1</div><div>[↑0.0.0]</div> (backend 'no latest_version' sentinel: no badge) FAIL 1.10.0 vs 1.2 -> <div>1.10.0</div><div>[↑1.2]</div> (numeric compare: no badge) ``` After the patch, all 9 pass — 1.78.1/1.47.0 no badge; 1.0.0/1.47.0 badge kept; equal versions no badge; the `0.0.0` sentinel no badge; `1.2` vs `1.10.0` compared numerically both ways; the `nightly` branch output byte-identical; unparseable specs (`1.2.3rc1`) keep legacy behavior. **2. The new test file reproduces RED -> GREEN:** ``` MANAGER_JS_DIR=<dir populated from git show main:js/...> \ python -m pytest tests/test_version_badge_semver.py # 3 failed python -m pytest tests/test_version_badge_semver.py # 3 passed ``` **3. Existing tests and lint are untouched:** `python -m pytest tests/` → 239 passed, 80 skipped (the skips are the `E2E_ROOT`-gated e2e suite); the js_lift suites (`test_pack_column_escaping.py`, `test_grid_highlight_escaping.py`) pass unchanged; `ruff check .` clean. Fixes #3272 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Comfy-Org/ComfyUI-Manager#3234
No description provided.