test: cover installer npm freshness policy

This commit is contained in:
Peter Steinberger
2026-05-19 00:15:45 +01:00
parent 0903fa61d0
commit df8505b09d
2 changed files with 107 additions and 0 deletions

View File

@@ -13,6 +13,10 @@ UPDATE_BASELINE_VERSION="${OPENCLAW_INSTALL_UPDATE_BASELINE:-latest}"
UPDATE_BASELINE_TAG_URL="${OPENCLAW_INSTALL_UPDATE_BASELINE_TAG_URL:-}"
UPDATE_EXPECT_VERSION="${OPENCLAW_INSTALL_UPDATE_EXPECT_VERSION:-}"
UPDATE_TAG_URL="${OPENCLAW_INSTALL_UPDATE_TAG_URL:-}"
FRESHNESS_VERSION="${OPENCLAW_INSTALL_FRESHNESS_VERSION:-latest}"
# npm min-release-age is days; 10000 keeps the control failure independent of normal release cadence.
FRESHNESS_MIN_RELEASE_AGE="${OPENCLAW_INSTALL_FRESHNESS_MIN_RELEASE_AGE:-10000}"
FRESHNESS_NPM_VERSION="${OPENCLAW_INSTALL_FRESHNESS_NPM_VERSION:-11.14.1}"
HEARTBEAT_INTERVAL="${OPENCLAW_INSTALL_SMOKE_HEARTBEAT_INTERVAL:-60}"
INSTALL_COMMAND_TIMEOUT="${OPENCLAW_INSTALL_SMOKE_COMMAND_TIMEOUT:-900}"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
@@ -391,6 +395,75 @@ run_npm_global_smoke() {
echo "OK"
}
run_freshness_smoke() {
local freshness_spec="${PACKAGE_NAME}@${FRESHNESS_VERSION}"
local expected_version
local current_npm_version
local policy_home
local plain_stdout_file
local plain_stderr_file
local plain_status
policy_home="$(mktemp -d)"
plain_stdout_file="$(mktemp)"
plain_stderr_file="$(mktemp)"
printf "min-release-age=%s\n" "$FRESHNESS_MIN_RELEASE_AGE" >"${policy_home}/.npmrc"
current_npm_version="$(npm --version 2>/dev/null || true)"
if [[ "$current_npm_version" != "$FRESHNESS_NPM_VERSION" ]]; then
echo "==> Install npm with min-release-age support: npm@$FRESHNESS_NPM_VERSION"
npm_install_global "install npm freshness-capable release" "npm@${FRESHNESS_NPM_VERSION}"
fi
expected_version="$(quiet_npm view "$freshness_spec" version 2>/dev/null || true)"
if [[ -z "$expected_version" ]]; then
echo "ERROR: failed to resolve $freshness_spec" >&2
return 1
fi
echo "package=$PACKAGE_NAME version=$FRESHNESS_VERSION resolved=$expected_version npm=$(npm --version) min_release_age=$FRESHNESS_MIN_RELEASE_AGE"
echo "==> Verify user npm freshness policy blocks plain npm install"
set +e
HOME="$policy_home" NPM_CONFIG_USERCONFIG="${policy_home}/.npmrc" \
timeout --foreground "${INSTALL_COMMAND_TIMEOUT}s" \
npm \
--loglevel=error \
--logs-max=0 \
--no-update-notifier \
--no-fund \
--no-audit \
--no-progress \
install -g "$freshness_spec" \
>"$plain_stdout_file" 2>"$plain_stderr_file"
plain_status=$?
set -e
if [[ "$plain_status" -eq 0 ]]; then
echo "ERROR: plain npm install unexpectedly succeeded under min-release-age policy" >&2
return 1
fi
if ! grep -Eiq "No matching version|No versions available|ETARGET|ENOVERSIONS|notarget|min-release-age|minimum release age|before" \
"$plain_stdout_file" "$plain_stderr_file"; then
echo "ERROR: plain npm install failed without expected freshness evidence" >&2
cat "$plain_stdout_file"
cat "$plain_stderr_file" >&2
return 1
fi
echo "==> Run installer with same npm freshness policy"
env \
HOME="$policy_home" \
NPM_CONFIG_USERCONFIG="${policy_home}/.npmrc" \
OPENCLAW_NO_ONBOARD=1 \
OPENCLAW_NO_PROMPT=1 \
bash -c 'curl -fsSL "$1" | bash -s -- --install-method npm --version "$2" --no-prompt --no-onboard' \
_ "$INSTALL_URL" "$FRESHNESS_VERSION"
echo "==> Verify installed version"
print_install_audit "freshness install"
verify_installed_cli "$PACKAGE_NAME" "$expected_version"
echo "OK"
}
case "$SMOKE_MODE" in
install)
run_install_smoke
@@ -401,6 +474,9 @@ case "$SMOKE_MODE" in
npm-global)
run_npm_global_smoke
;;
freshness)
run_freshness_smoke
;;
*)
echo "ERROR: unsupported OPENCLAW_INSTALL_SMOKE_MODE=$SMOKE_MODE" >&2
exit 1

View File

@@ -149,6 +149,11 @@ SKIP_SMOKE_IMAGE_BUILD="${OPENCLAW_INSTALL_SMOKE_SKIP_IMAGE_BUILD:-0}"
SKIP_NONROOT_IMAGE_BUILD="${OPENCLAW_INSTALL_NONROOT_SKIP_IMAGE_BUILD:-0}"
SKIP_UPDATE="${OPENCLAW_INSTALL_SMOKE_SKIP_UPDATE:-0}"
SKIP_NPM_GLOBAL="${OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL:-0}"
SKIP_FRESHNESS="${OPENCLAW_INSTALL_SMOKE_SKIP_FRESHNESS:-0}"
FRESHNESS_INSTALL_URL="${OPENCLAW_INSTALL_SMOKE_FRESHNESS_INSTALL_URL:-file:///tmp/openclaw-install.sh}"
# npm min-release-age is days; 10000 keeps the control failure independent of normal release cadence.
FRESHNESS_MIN_RELEASE_AGE="${OPENCLAW_INSTALL_FRESHNESS_MIN_RELEASE_AGE:-10000}"
FRESHNESS_NPM_VERSION="${OPENCLAW_INSTALL_FRESHNESS_NPM_VERSION:-11.14.1}"
UPDATE_BASELINE_VERSION="${OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE:-latest}"
UPDATE_PACKAGE_SPEC="${OPENCLAW_INSTALL_SMOKE_UPDATE_PACKAGE_SPEC:-}"
UPDATE_DIST_IMAGE="${OPENCLAW_INSTALL_SMOKE_UPDATE_DIST_IMAGE:-}"
@@ -169,6 +174,7 @@ UPDATE_TAG_URL=""
UPDATE_DOCKER_HOST_ARGS=()
NPM_CACHE_DIR="${OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR:-}"
NPM_CACHE_OWNED=0
NPM_CACHE_PREPARED=0
NPM_CACHE_DOCKER_ARGS=()
remove_owned_npm_cache() {
@@ -334,6 +340,9 @@ prepare_update_host_access() {
}
prepare_npm_cache() {
if [[ "$NPM_CACHE_PREPARED" == "1" ]]; then
return
fi
if [[ -z "$NPM_CACHE_DIR" ]]; then
NPM_CACHE_DIR="$(mktemp -d)"
NPM_CACHE_OWNED=1
@@ -345,6 +354,7 @@ prepare_npm_cache() {
-e npm_config_cache=/npm-cache
-e NPM_CONFIG_CACHE=/npm-cache
)
NPM_CACHE_PREPARED=1
}
start_update_server() {
@@ -447,6 +457,27 @@ else
fi
fi
if [[ "$SKIP_FRESHNESS" == "1" ]]; then
echo "==> Skip installer npm freshness smoke (OPENCLAW_INSTALL_SMOKE_SKIP_FRESHNESS=1)"
else
prepare_npm_cache
echo "==> Run installer npm freshness smoke"
docker run --rm -t \
--platform "$SMOKE_PLATFORM" \
"${NPM_CACHE_DOCKER_ARGS[@]}" \
-v "$ROOT_DIR/scripts/install.sh:/tmp/openclaw-install.sh:ro" \
-e OPENCLAW_INSTALL_URL="$FRESHNESS_INSTALL_URL" \
-e OPENCLAW_INSTALL_PACKAGE="$PACKAGE_NAME" \
-e OPENCLAW_INSTALL_SMOKE_MODE=freshness \
-e OPENCLAW_INSTALL_FRESHNESS_VERSION="${OPENCLAW_INSTALL_FRESHNESS_VERSION:-latest}" \
-e OPENCLAW_INSTALL_FRESHNESS_MIN_RELEASE_AGE="$FRESHNESS_MIN_RELEASE_AGE" \
-e OPENCLAW_INSTALL_FRESHNESS_NPM_VERSION="$FRESHNESS_NPM_VERSION" \
-e OPENCLAW_NO_ONBOARD=1 \
-e OPENCLAW_NO_PROMPT=1 \
-e DEBIAN_FRONTEND=noninteractive \
"$SMOKE_IMAGE"
fi
LATEST_VERSION="${LATEST_VERSION:-}"
if [[ "$SKIP_NONROOT" == "1" ]]; then