fix(install): keep stable channel when npm install retries (#124778)

* fix(installer): keep npm channel target immutable

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(install): fail after repeated CLI package install errors

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(installer): verify npm package publication

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(install): satisfy shellcheck for entry validation

* fix(installer): link the packaged OpenClaw launcher

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* test(installer): keep retry fixture version-valid

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

---------

Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Peter Steinberger
2026-08-17 00:17:26 -07:00
committed by GitHub
parent 1027837d96
commit 2b2c11e748
5 changed files with 409 additions and 32 deletions
+8 -16
View File
@@ -1283,23 +1283,15 @@ install_openclaw() {
fix_npm_prefix_if_needed
fi
if [[ "${requested}" == "latest" ]]; then
if ! env -u NPM_CONFIG_BEFORE -u npm_config_before -u NPM_CONFIG_MIN_RELEASE_AGE -u npm_config_min_release_age -u npm_config_min-release-age "$(npm_bin)" install -g --prefix "$(node_dir)" "${npm_args[@]}" "openclaw@${resolved_requested}"; then
log "npm install openclaw@latest failed; retrying openclaw@next"
emit_json "{\"event\":\"step\",\"name\":\"openclaw\",\"status\":\"retry\",\"version\":\"next\"}"
resolved_requested="next"
if [[ -n "${REQUIRED_COMPATIBLE_VERSION:-}" ]]; then
resolved_requested="$(resolve_npm_openclaw_version next)"
if [[ -z "$resolved_requested" ]]; then
fail "Could not resolve OpenClaw next before compatibility checking."
fi
require_openclaw_version_compatible "$resolved_requested"
fi
env -u NPM_CONFIG_BEFORE -u npm_config_before -u NPM_CONFIG_MIN_RELEASE_AGE -u npm_config_min_release_age -u npm_config_min-release-age "$(npm_bin)" install -g --prefix "$(node_dir)" "${npm_args[@]}" "openclaw@${resolved_requested}"
requested="next"
local installed_entry
installed_entry="$(node_dir)/lib/node_modules/openclaw/dist/entry.js"
if ! env -u NPM_CONFIG_BEFORE -u npm_config_before -u NPM_CONFIG_MIN_RELEASE_AGE -u npm_config_min_release_age -u npm_config_min-release-age "$(npm_bin)" install -g --prefix "$(node_dir)" "${npm_args[@]}" "openclaw@${resolved_requested}" || [[ ! -f "$installed_entry" ]]; then
log "npm install openclaw@${resolved_requested} did not produce a usable package; retrying once"
if ! env -u NPM_CONFIG_BEFORE -u npm_config_before -u NPM_CONFIG_MIN_RELEASE_AGE -u npm_config_min_release_age -u npm_config_min-release-age "$(npm_bin)" install -g --prefix "$(node_dir)" "${npm_args[@]}" "openclaw@${resolved_requested}" || [[ ! -f "$installed_entry" ]]; then
emit_json '{"event":"error","message":"npm install did not produce a usable OpenClaw package"}'
log "ERROR: npm install did not produce a usable OpenClaw package"
return 1
fi
else
env -u NPM_CONFIG_BEFORE -u npm_config_before -u NPM_CONFIG_MIN_RELEASE_AGE -u npm_config_min_release_age -u npm_config_min-release-age "$(npm_bin)" install -g --prefix "$(node_dir)" "${npm_args[@]}" "openclaw@${resolved_requested}"
fi
mkdir -p "${PREFIX}/bin"
+9 -15
View File
@@ -2169,7 +2169,8 @@ fix_npm_permissions() {
ensure_openclaw_bin_link() {
local npm_root=""
npm_root="$(npm root -g 2>/dev/null || true)"
if [[ -z "$npm_root" || ! -d "$npm_root/openclaw" ]]; then
local launcher="${npm_root}/openclaw/openclaw.mjs"
if [[ -z "$npm_root" || ! -x "$launcher" ]]; then
return 1
fi
local npm_bin=""
@@ -2179,10 +2180,10 @@ ensure_openclaw_bin_link() {
fi
mkdir -p "$npm_bin"
if [[ ! -x "${npm_bin}/openclaw" ]]; then
ln -sf "$npm_root/openclaw/dist/entry.js" "${npm_bin}/openclaw"
ln -sf "$launcher" "${npm_bin}/openclaw"
ui_info "Created openclaw bin link at ${npm_bin}/openclaw"
fi
return 0
"${npm_bin}/openclaw" --version >/dev/null 2>&1
}
# Check for existing OpenClaw installation
@@ -3040,22 +3041,15 @@ install_openclaw() {
local install_spec=""
install_spec="$(resolve_package_install_spec "${package_name}" "${OPENCLAW_VERSION}")"
if ! install_openclaw_npm "${install_spec}"; then
ui_warn "npm install failed; retrying"
if ! install_openclaw_npm "${install_spec}" || ! ensure_openclaw_bin_link; then
ui_warn "npm install did not produce a usable OpenClaw package; retrying"
cleanup_npm_openclaw_paths
install_openclaw_npm "${install_spec}"
fi
if [[ "${OPENCLAW_VERSION}" == "latest" && "${package_name}" == "openclaw" ]]; then
if ! resolve_openclaw_bin &> /dev/null; then
ui_warn "npm install openclaw@latest failed; retrying openclaw@next"
cleanup_npm_openclaw_paths
install_openclaw_npm "openclaw@next"
if ! install_openclaw_npm "${install_spec}" || ! ensure_openclaw_bin_link; then
ui_error "npm install did not produce a usable OpenClaw package"
return 1
fi
fi
ensure_openclaw_bin_link || true
ui_success "OpenClaw installed"
}