mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-28 13:26:04 -06:00
fix(release): stage Codex for npm onboarding candidates (#130360)
* fix(release): stage Codex for npm onboarding candidates * refactor(release): share candidate registry lifecycle
This commit is contained in:
@@ -6,12 +6,13 @@ set -euo pipefail
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
source "$ROOT_DIR/scripts/lib/docker-e2e-image.sh"
|
||||
source "$ROOT_DIR/scripts/lib/docker-e2e-package.sh"
|
||||
source "$ROOT_DIR/scripts/e2e/lib/prepublish-plugin-registry.sh"
|
||||
|
||||
IMAGE_NAME="$(docker_e2e_resolve_image "openclaw-codex-on-demand-e2e" OPENCLAW_CODEX_ON_DEMAND_E2E_IMAGE)"
|
||||
DOCKER_TARGET="${OPENCLAW_CODEX_ON_DEMAND_DOCKER_TARGET:-bare}"
|
||||
HOST_BUILD="${OPENCLAW_CODEX_ON_DEMAND_HOST_BUILD:-1}"
|
||||
PACKAGE_TGZ="${OPENCLAW_CURRENT_PACKAGE_TGZ:-}"
|
||||
PREPUBLISH_PLUGIN_REGISTRY_ARGS=()
|
||||
OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DOCKER_ARGS=()
|
||||
AUTO_PREPUBLISH_PLUGIN_REGISTRY_ROOT=""
|
||||
run_log=""
|
||||
|
||||
@@ -20,33 +21,9 @@ run_log=""
|
||||
# the Codex assertions instead of failing as a silent package-install timeout.
|
||||
export OPENCLAW_E2E_NPM_INSTALL_TIMEOUT="${OPENCLAW_E2E_NPM_INSTALL_TIMEOUT:-1200s}"
|
||||
|
||||
configure_prepublish_plugin_registry() {
|
||||
local registry_dir="$1"
|
||||
local resolved_registry_dir
|
||||
resolved_registry_dir="$(cd "$registry_dir" && pwd)"
|
||||
local manifest="$resolved_registry_dir/prepublish-plugin-registry.json"
|
||||
if [ ! -f "$manifest" ]; then
|
||||
echo "Prepublish plugin registry manifest is missing." >&2
|
||||
exit 1
|
||||
fi
|
||||
local source_sha="${OPENCLAW_DOCKER_E2E_SELECTED_SHA:-}"
|
||||
local candidate_version="${OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_CANDIDATE_VERSION:-}"
|
||||
local manifest_sha256="${OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_MANIFEST_SHA256:-}"
|
||||
source_sha="${source_sha:-$(node -e 'process.stdout.write(require(process.argv[1]).sourceSha)' "$manifest")}"
|
||||
candidate_version="${candidate_version:-$(node -e 'process.stdout.write(require(process.argv[1]).candidateVersion)' "$manifest")}"
|
||||
if [ -z "$manifest_sha256" ]; then
|
||||
manifest_sha256="$(node -e 'const fs=require("node:fs"),crypto=require("node:crypto");process.stdout.write(crypto.createHash("sha256").update(fs.readFileSync(process.argv[1])).digest("hex"))' "$manifest")"
|
||||
fi
|
||||
PREPUBLISH_PLUGIN_REGISTRY_ARGS=(
|
||||
-e OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DIR=/tmp/openclaw-prepublish-plugin-registry
|
||||
-e OPENCLAW_DOCKER_E2E_SELECTED_SHA="$source_sha"
|
||||
-e OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_CANDIDATE_VERSION="$candidate_version"
|
||||
-e OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_MANIFEST_SHA256="$manifest_sha256"
|
||||
-v "$resolved_registry_dir:/tmp/openclaw-prepublish-plugin-registry:ro"
|
||||
)
|
||||
}
|
||||
if [ -n "${OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DIR:-}" ]; then
|
||||
configure_prepublish_plugin_registry "$OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DIR"
|
||||
openclaw_prepublish_plugin_registry_configure_docker_args \
|
||||
"$OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DIR"
|
||||
fi
|
||||
|
||||
cleanup() {
|
||||
@@ -88,7 +65,7 @@ if [ -z "${OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DIR:-}" ] &&
|
||||
OPENCLAW_DOCKER_ALL_LOG_DIR="$AUTO_PREPUBLISH_PLUGIN_REGISTRY_ROOT" \
|
||||
OPENCLAW_DOCKER_ALL_TIMINGS=0 \
|
||||
node "$ROOT_DIR/scripts/test-docker-all.mjs" --prepare-plugin-registry >/dev/null
|
||||
configure_prepublish_plugin_registry \
|
||||
openclaw_prepublish_plugin_registry_configure_docker_args \
|
||||
"$AUTO_PREPUBLISH_PLUGIN_REGISTRY_ROOT/prepublish-plugin-registry"
|
||||
fi
|
||||
|
||||
@@ -100,7 +77,7 @@ echo "Running Codex on-demand Docker E2E..."
|
||||
if ! docker_e2e_run_with_harness \
|
||||
-e COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \
|
||||
-e "OPENCLAW_TEST_STATE_SCRIPT_B64=$OPENCLAW_TEST_STATE_SCRIPT_B64" \
|
||||
${PREPUBLISH_PLUGIN_REGISTRY_ARGS[@]+"${PREPUBLISH_PLUGIN_REGISTRY_ARGS[@]}"} \
|
||||
"${OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DOCKER_ARGS[@]}" \
|
||||
"${DOCKER_E2E_PACKAGE_ARGS[@]}" \
|
||||
-i "$IMAGE_NAME" bash -s >"$run_log" 2>&1 <<'EOF'; then
|
||||
set -euo pipefail
|
||||
@@ -135,16 +112,8 @@ cleanup_inner() {
|
||||
trap cleanup_inner EXIT
|
||||
|
||||
configure_plugin_registry() {
|
||||
[ -n "${OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DIR:-}" ] || return 0
|
||||
local registry_root="/tmp/openclaw-codex-registry"
|
||||
OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_REQUIRED_PACKAGES_JSON='["@openclaw/codex"]' \
|
||||
openclaw_prepublish_plugin_registry_start \
|
||||
"$OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DIR" \
|
||||
"${OPENCLAW_DOCKER_E2E_SELECTED_SHA:?missing selected SHA}" \
|
||||
"${OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_CANDIDATE_VERSION:?missing candidate version}" \
|
||||
"${OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_MANIFEST_SHA256:?missing manifest SHA-256}" \
|
||||
"$registry_root" \
|
||||
plugin_registry_pid
|
||||
openclaw_prepublish_plugin_registry_start_mounted \
|
||||
/tmp/openclaw-codex-registry plugin_registry_pid '["@openclaw/codex"]'
|
||||
}
|
||||
|
||||
mkdir -p "$NPM_CONFIG_PREFIX" "$XDG_CACHE_HOME" "$NPM_CONFIG_CACHE"
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
openclaw_prepublish_plugin_registry_configure_docker_args() {
|
||||
local registry_dir="$1"
|
||||
local resolved_registry_dir
|
||||
resolved_registry_dir="$(cd "$registry_dir" && pwd)"
|
||||
local manifest="$resolved_registry_dir/prepublish-plugin-registry.json"
|
||||
if [ ! -f "$manifest" ]; then
|
||||
echo "Prepublish plugin registry manifest is missing." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
local source_sha="${OPENCLAW_DOCKER_E2E_SELECTED_SHA:-}"
|
||||
local candidate_version="${OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_CANDIDATE_VERSION:-}"
|
||||
local manifest_sha256="${OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_MANIFEST_SHA256:-}"
|
||||
source_sha="${source_sha:-$(node -e 'process.stdout.write(require(process.argv[1]).sourceSha)' "$manifest")}"
|
||||
candidate_version="${candidate_version:-$(node -e 'process.stdout.write(require(process.argv[1]).candidateVersion)' "$manifest")}"
|
||||
if [ -z "$manifest_sha256" ]; then
|
||||
manifest_sha256="$(node -e 'const fs=require("node:fs"),crypto=require("node:crypto");process.stdout.write(crypto.createHash("sha256").update(fs.readFileSync(process.argv[1])).digest("hex"))' "$manifest")"
|
||||
fi
|
||||
|
||||
OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DOCKER_ARGS=(
|
||||
-e OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DIR=/tmp/openclaw-prepublish-plugin-registry
|
||||
-e OPENCLAW_DOCKER_E2E_SELECTED_SHA="$source_sha"
|
||||
-e OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_CANDIDATE_VERSION="$candidate_version"
|
||||
-e OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_MANIFEST_SHA256="$manifest_sha256"
|
||||
-v "$resolved_registry_dir:/tmp/openclaw-prepublish-plugin-registry:ro"
|
||||
)
|
||||
}
|
||||
|
||||
openclaw_prepublish_plugin_registry_start() {
|
||||
local artifact_dir="$1" source_sha="$2" candidate_version="$3"
|
||||
local manifest_sha256="$4" registry_root="$5" pid_variable="$6"
|
||||
@@ -90,3 +118,19 @@ NODE
|
||||
export npm_config_registry="$NPM_CONFIG_REGISTRY"
|
||||
printf -v "$pid_variable" "%s" "$server_pid"
|
||||
}
|
||||
|
||||
openclaw_prepublish_plugin_registry_start_mounted() {
|
||||
local registry_root="$1" pid_variable="$2" required_packages_json="$3"
|
||||
shift 3
|
||||
[ -n "${OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DIR:-}" ] || return 0
|
||||
|
||||
OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_REQUIRED_PACKAGES_JSON="$required_packages_json" \
|
||||
openclaw_prepublish_plugin_registry_start \
|
||||
"$OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DIR" \
|
||||
"${OPENCLAW_DOCKER_E2E_SELECTED_SHA:?missing selected SHA}" \
|
||||
"${OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_CANDIDATE_VERSION:?missing candidate version}" \
|
||||
"${OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_MANIFEST_SHA256:?missing manifest SHA-256}" \
|
||||
"$registry_root" \
|
||||
"$pid_variable" \
|
||||
"$@"
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
SOURCE_ROOT="$(cd "${OPENCLAW_NPM_ONBOARD_SOURCE_ROOT:-${OPENCLAW_LIVE_DOCKER_REPO_ROOT:-$ROOT_DIR}}" && pwd)"
|
||||
source "$ROOT_DIR/scripts/lib/docker-e2e-image.sh"
|
||||
source "$ROOT_DIR/scripts/lib/docker-e2e-package.sh"
|
||||
source "$ROOT_DIR/scripts/e2e/lib/prepublish-plugin-registry.sh"
|
||||
|
||||
IMAGE_NAME="$(docker_e2e_resolve_image "openclaw-npm-onboard-channel-agent-e2e" OPENCLAW_NPM_ONBOARD_E2E_IMAGE)"
|
||||
DOCKER_TARGET="${OPENCLAW_NPM_ONBOARD_DOCKER_TARGET:-bare}"
|
||||
@@ -23,6 +24,7 @@ STATUS_TEXT_MAX_BYTES="$(
|
||||
run_log=""
|
||||
plugin_pack_dir=""
|
||||
plugin_package_args=()
|
||||
OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DOCKER_ARGS=()
|
||||
|
||||
cleanup() {
|
||||
if [ -n "${PACKAGE_TGZ:-}" ]; then
|
||||
@@ -95,6 +97,11 @@ prepare_source_plugin_package() {
|
||||
|
||||
prepare_source_plugin_package
|
||||
|
||||
if [ -n "${OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DIR:-}" ]; then
|
||||
openclaw_prepublish_plugin_registry_configure_docker_args \
|
||||
"$OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DIR"
|
||||
fi
|
||||
|
||||
docker_e2e_package_mount_args "$PACKAGE_TGZ"
|
||||
run_log="$(docker_e2e_run_log npm-onboard-channel-agent)"
|
||||
OPENCLAW_TEST_STATE_SCRIPT_B64="$(docker_e2e_test_state_shell_b64 npm-onboard-channel-agent empty)"
|
||||
@@ -108,10 +115,12 @@ if ! docker_e2e_run_with_harness \
|
||||
-e "OPENCLAW_TEST_STATE_SCRIPT_B64=$OPENCLAW_TEST_STATE_SCRIPT_B64" \
|
||||
"${DOCKER_E2E_PACKAGE_ARGS[@]}" \
|
||||
"${plugin_package_args[@]}" \
|
||||
"${OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DOCKER_ARGS[@]}" \
|
||||
-i "$IMAGE_NAME" bash -s >"$run_log" 2>&1 <<'EOF'; then
|
||||
set -Eeuo pipefail
|
||||
|
||||
source scripts/lib/openclaw-e2e-instance.sh
|
||||
source scripts/e2e/lib/prepublish-plugin-registry.sh
|
||||
openclaw_e2e_eval_test_state_from_b64 "${OPENCLAW_TEST_STATE_SCRIPT_B64:?missing OPENCLAW_TEST_STATE_SCRIPT_B64}"
|
||||
export NPM_CONFIG_PREFIX="$HOME/.npm-global"
|
||||
export PATH="$NPM_CONFIG_PREFIX/bin:$PATH"
|
||||
@@ -126,6 +135,7 @@ scenario_tmp="$(mktemp -d "${TMPDIR:-/tmp}/openclaw-npm-onboard-channel-agent.XX
|
||||
MOCK_REQUEST_LOG="$scenario_tmp/mock-openai-requests.jsonl"
|
||||
export SUCCESS_MARKER MOCK_REQUEST_LOG
|
||||
mock_pid=""
|
||||
plugin_registry_pid=""
|
||||
|
||||
case "$CHANNEL" in
|
||||
telegram)
|
||||
@@ -155,6 +165,7 @@ esac
|
||||
|
||||
cleanup() {
|
||||
openclaw_e2e_stop_process "${mock_pid:-}"
|
||||
openclaw_e2e_stop_process "${plugin_registry_pid:-}"
|
||||
rm -rf "$scenario_tmp"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
@@ -180,6 +191,11 @@ dump_debug_logs() {
|
||||
}
|
||||
trap 'status=$?; dump_debug_logs "$status"; exit "$status"' ERR
|
||||
|
||||
if [ -n "${OPENCLAW_PREPUBLISH_PLUGIN_REGISTRY_DIR:-}" ]; then
|
||||
openclaw_prepublish_plugin_registry_start_mounted \
|
||||
/tmp/openclaw-npm-onboard-plugin-registry plugin_registry_pid '["@openclaw/codex"]'
|
||||
fi
|
||||
|
||||
openclaw_e2e_install_package /tmp/openclaw-install.log
|
||||
|
||||
command -v openclaw >/dev/null
|
||||
|
||||
@@ -64,6 +64,12 @@ const updateMigrationCommand = upgradeSurvivorScriptCommand(
|
||||
const updateRunPackageSelfUpgradeCommand =
|
||||
"OPENCLAW_QA_ALLOW_UPDATE_RUN_SELF=1 OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:update-run-package-self-upgrade";
|
||||
const CODEX_HARNESS_API_KEY_ENV = "OPENCLAW_LIVE_CODEX_HARNESS_AUTH=api-key";
|
||||
const npmOnboardLaneOptions = {
|
||||
prepublishPluginPackages: ["@openclaw/codex"],
|
||||
resources: ["service"],
|
||||
stateScenario: "empty",
|
||||
weight: 3,
|
||||
} satisfies LaneOptions;
|
||||
|
||||
const LIVE_RETRY_PATTERNS = [
|
||||
/529\b/i,
|
||||
@@ -461,17 +467,17 @@ export const mainLanes: DockerE2eLane[] = [
|
||||
npmLane(
|
||||
"npm-onboard-channel-agent",
|
||||
"OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:npm-onboard-channel-agent",
|
||||
{ resources: ["service"], stateScenario: "empty", weight: 3 },
|
||||
npmOnboardLaneOptions,
|
||||
),
|
||||
npmLane(
|
||||
"npm-onboard-discord-channel-agent",
|
||||
"OPENCLAW_NPM_ONBOARD_CHANNEL=discord OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:npm-onboard-channel-agent",
|
||||
{ resources: ["service"], stateScenario: "empty", weight: 3 },
|
||||
npmOnboardLaneOptions,
|
||||
),
|
||||
npmLane(
|
||||
"npm-onboard-slack-channel-agent",
|
||||
"OPENCLAW_NPM_ONBOARD_CHANNEL=slack OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:npm-onboard-channel-agent",
|
||||
{ resources: ["service"], stateScenario: "empty", weight: 3 },
|
||||
npmOnboardLaneOptions,
|
||||
),
|
||||
// Prerelease validation must pair frozen core bytes with matching target plugin bytes.
|
||||
// Keep the registry-backed lanes above unchanged for published-package proof.
|
||||
@@ -481,7 +487,7 @@ export const mainLanes: DockerE2eLane[] = [
|
||||
"e2e/npm-onboard-channel-agent-docker.sh",
|
||||
"OPENCLAW_NPM_ONBOARD_CHANNEL=discord OPENCLAW_NPM_ONBOARD_USE_SOURCE_PLUGIN_PACKAGE=1",
|
||||
),
|
||||
{ resources: ["service"], stateScenario: "empty", weight: 3 },
|
||||
npmOnboardLaneOptions,
|
||||
),
|
||||
npmLane(
|
||||
"npm-onboard-slack-candidate-channel-agent",
|
||||
@@ -489,7 +495,7 @@ export const mainLanes: DockerE2eLane[] = [
|
||||
"e2e/npm-onboard-channel-agent-docker.sh",
|
||||
"OPENCLAW_NPM_ONBOARD_CHANNEL=slack OPENCLAW_NPM_ONBOARD_USE_SOURCE_PLUGIN_PACKAGE=1",
|
||||
),
|
||||
{ resources: ["service"], stateScenario: "empty", weight: 3 },
|
||||
npmOnboardLaneOptions,
|
||||
),
|
||||
npmLane(
|
||||
"release-user-journey",
|
||||
|
||||
Reference in New Issue
Block a user