Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(npm): prevent binary unavailability during auto-upgrade - #704

Open
lizhengfeng101 wants to merge 2 commits into
mainfrom
fix/npm-upgrade-binary-gap
Open

fix(npm): prevent binary unavailability during auto-upgrade#704
lizhengfeng101 wants to merge 2 commits into
mainfrom
fix/npm-upgrade-binary-gap

Conversation

@lizhengfeng101

@lizhengfeng101 lizhengfeng101 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add a binary cache fallback to ~/.opencodereview/bin/ so ocr remains available while the background auto-upgrade runs npm i -g
  • Before upgrading, the current binary is copied to the cache; resolveNativeBinary() uses it as a last resort when the platform package binary is missing
  • After a successful upgrade, the cache is refreshed with the new binary

Problem

When the background auto-upgrade runs npm i -g, npm removes the old platform package before installing the new one. During this gap window, ocr fails with "binary not found". On Windows, the running .exe cannot be deleted, so the upgrade fails entirely and can leave a permanently broken install.

Solution

A simple binary cache mechanism:

  1. scripts/update.js copies the current binary to ~/.opencodereview/bin/ before running npm i -g
  2. scripts/platform.js adds this cache path as the third fallback in resolveNativeBinary() (after platform package → legacy path → cache → null)

This ensures ocr always has a working binary to fall back on, even during the upgrade gap window or after a failed Windows upgrade.

Closes #703

Test plan

  • make check passes
  • make test passes
  • Manual: install old version → trigger upgrade → rapidly invoke ocr version during upgrade → should always succeed via cache fallback

Add a binary cache fallback mechanism to ensure ocr remains available
while the background auto-upgrade is running npm i -g.

Before the upgrade, the current binary is copied to
~/.opencodereview/bin/ as a safety net. resolveNativeBinary() now
checks this cache path as a last resort before returning null.

This fixes:
- Unix: the gap window where binary is deleted before new one installs
- Windows: broken installs when npm i -g fails due to file locks
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

🔍 OpenCodeReview found 2 issue(s) in this PR.

  • ✅ Successfully posted inline: 2 comment(s)

Comment thread scripts/platform.js Outdated
Comment on lines +58 to +60
const cachePath = path.join(
os.homedir(), ".opencodereview", "bin", BINARY_FILENAME
);

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.

[maintainability · medium]
The cache directory path ".opencodereview" is hardcoded here and also independently defined in scripts/update.js as path.join(os.homedir(), ".opencodereview"). If either location is changed without updating the other, the cache lookup will silently fail. Consider extracting this into a shared constant exported from platform.js (e.g., CACHE_DIR) and importing it in update.js to ensure consistency.

Comment thread scripts/update.js Outdated
const lockFile = path.join(stateDir, "update.lock");
const hintFile = path.join(stateDir, "update-available");

const CACHE_BIN_DIR = path.join(stateDir, "bin");

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.

[maintainability · medium]
The cache directory path ~/.opencodereview/bin is constructed independently here and in platform.js (lines 58-59). If one location is updated but the other isn't, they will silently diverge, causing the cache to never be found or written correctly. Consider exporting CACHE_BIN_DIR (or a function like getCacheBinPath()) from platform.js and importing it here, so there's a single source of truth for the cache path.

Replace the simple binary cache with a proper staged binary mechanism:

- Add version.json metadata tracking (version, timestamp, platform)
- Add platform validation to prevent cross-platform misuse
- Add file integrity checks (exists, non-empty) in resolveStagedBinary()
- Notify users via dim stderr message when running from staged binary
- Refresh staged binary after successful upgrade for next-time protection
- Reuse STATE_DIR from platform.js to eliminate path duplication
- Always write version.json to avoid orphan binaries on disk

Resolution priority: platform package > staged binary > legacy path.
@crestonepeaks

Copy link
Copy Markdown
Contributor

@lizhengfeng101 Thanks for working on #703. We have additional Linux GitHub Actions evidence from a consumer pinned to alibaba/open-code-review@5679f44a07a17cbd88e8a7341b4f72a4a2b191cf with ocr_version: 1.9.10.

Across three independent runs, the pinned runtime installed and passed its version check before the detached updater disrupted the global package:

  • configuration completed, then the review step failed with ocr: command not found (exit 127);
  • a retry passed installation/version checking, then failed with Error: Cannot find module '../scripts/platform';
  • a later run completed installation and configuration, then failed with Error: Cannot find module '/usr/local/bin/ocr'; runner cleanup reported an orphaned npm i @alibaba-... process.

This appears broader than a missing native binary after the launcher has loaded. PR #704 still requires ../scripts/platform before its staged-binary fallback and does not protect the global ocr shim or the rest of the JavaScript package tree while npm i -g replaces them.

As a controlled comparison, we set the launcher-documented OCR_NO_UPDATE=1 at the action-step level while keeping the same action SHA and OCR 1.9.10 pin. The exact-head run then completed successfully: 2/2 selected items completed, zero failed/waived items, exit code 0, and no binary-gap error or orphan npm updater in the runner cleanup.

Would you be open to extending #704 (or a follow-up) with regression coverage for the missing shim and missing JavaScript-module cases, and considering an action-level no-update option/default when ocr_version is explicitly pinned? We are happy to help with tests or a patch if useful, and can provide additional sanitized log excerpts.

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.

ocr command becomes unavailable during npm auto-upgrade (binary gap window + Windows file lock)

2 participants