|
| 1 | +#!/usr/bin/env bash |
| 2 | +# Installs OpenClaw from a prepared package tarball, installs @openclaw/codex |
| 3 | +# from the real npm registry, and verifies a live Codex app-server turn. |
| 4 | +set -euo pipefail |
| 5 | + |
| 6 | +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" |
| 7 | +source "$ROOT_DIR/scripts/lib/docker-e2e-image.sh" |
| 8 | +source "$ROOT_DIR/scripts/lib/docker-e2e-package.sh" |
| 9 | + |
| 10 | +IMAGE_NAME="$(docker_e2e_resolve_image "openclaw-codex-npm-plugin-live-e2e" OPENCLAW_CODEX_NPM_PLUGIN_E2E_IMAGE)" |
| 11 | +DOCKER_TARGET="${OPENCLAW_CODEX_NPM_PLUGIN_DOCKER_TARGET:-bare}" |
| 12 | +HOST_BUILD="${OPENCLAW_CODEX_NPM_PLUGIN_HOST_BUILD:-1}" |
| 13 | +PACKAGE_TGZ="${OPENCLAW_CURRENT_PACKAGE_TGZ:-}" |
| 14 | +PROFILE_FILE="${OPENCLAW_CODEX_NPM_PLUGIN_PROFILE_FILE:-$HOME/.profile}" |
| 15 | + |
| 16 | +docker_e2e_build_or_reuse "$IMAGE_NAME" codex-npm-plugin-live "$ROOT_DIR/scripts/e2e/Dockerfile" "$ROOT_DIR" "$DOCKER_TARGET" |
| 17 | + |
| 18 | +prepare_package_tgz() { |
| 19 | + if [ -n "$PACKAGE_TGZ" ]; then |
| 20 | + PACKAGE_TGZ="$(docker_e2e_prepare_package_tgz codex-npm-plugin-live "$PACKAGE_TGZ")" |
| 21 | + return 0 |
| 22 | + fi |
| 23 | + if [ "$HOST_BUILD" = "0" ] && [ -z "${OPENCLAW_CURRENT_PACKAGE_TGZ:-}" ]; then |
| 24 | + echo "OPENCLAW_CODEX_NPM_PLUGIN_HOST_BUILD=0 requires OPENCLAW_CURRENT_PACKAGE_TGZ" >&2 |
| 25 | + exit 1 |
| 26 | + fi |
| 27 | + PACKAGE_TGZ="$(docker_e2e_prepare_package_tgz codex-npm-plugin-live)" |
| 28 | +} |
| 29 | + |
| 30 | +prepare_package_tgz |
| 31 | + |
| 32 | +PROFILE_MOUNT=() |
| 33 | +PROFILE_STATUS="none" |
| 34 | +if [ -f "$PROFILE_FILE" ] && [ -r "$PROFILE_FILE" ]; then |
| 35 | + PROFILE_MOUNT=(-v "$PROFILE_FILE":/home/appuser/.profile:ro) |
| 36 | + PROFILE_STATUS="$PROFILE_FILE" |
| 37 | +fi |
| 38 | + |
| 39 | +docker_e2e_package_mount_args "$PACKAGE_TGZ" |
| 40 | +run_log="$(docker_e2e_run_log codex-npm-plugin-live)" |
| 41 | +OPENCLAW_TEST_STATE_SCRIPT_B64="$(docker_e2e_test_state_shell_b64 codex-npm-plugin-live empty)" |
| 42 | + |
| 43 | +echo "Running Codex npm plugin live Docker E2E..." |
| 44 | +echo "Profile file: $PROFILE_STATUS" |
| 45 | +if ! docker_e2e_run_with_harness \ |
| 46 | + -e COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \ |
| 47 | + -e OPENCLAW_CODEX_NPM_PLUGIN_MODEL="${OPENCLAW_CODEX_NPM_PLUGIN_MODEL:-codex/gpt-5.4}" \ |
| 48 | + -e OPENCLAW_CODEX_NPM_PLUGIN_SPEC="${OPENCLAW_CODEX_NPM_PLUGIN_SPEC:-npm:@openclaw/codex@beta}" \ |
| 49 | + -e "OPENCLAW_TEST_STATE_SCRIPT_B64=$OPENCLAW_TEST_STATE_SCRIPT_B64" \ |
| 50 | + "${DOCKER_E2E_PACKAGE_ARGS[@]}" \ |
| 51 | + "${PROFILE_MOUNT[@]}" \ |
| 52 | + -i "$IMAGE_NAME" bash -s >"$run_log" 2>&1 <<'EOF'; then |
| 53 | +set -euo pipefail |
| 54 | +
|
| 55 | +source scripts/lib/openclaw-e2e-instance.sh |
| 56 | +openclaw_e2e_eval_test_state_from_b64 "${OPENCLAW_TEST_STATE_SCRIPT_B64:?missing OPENCLAW_TEST_STATE_SCRIPT_B64}" |
| 57 | +export NPM_CONFIG_PREFIX="$HOME/.npm-global" |
| 58 | +export npm_config_prefix="$NPM_CONFIG_PREFIX" |
| 59 | +export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}" |
| 60 | +export NPM_CONFIG_CACHE="${NPM_CONFIG_CACHE:-$XDG_CACHE_HOME/npm}" |
| 61 | +export npm_config_cache="$NPM_CONFIG_CACHE" |
| 62 | +export PATH="$NPM_CONFIG_PREFIX/bin:$PATH" |
| 63 | +export OPENCLAW_AGENT_HARNESS_FALLBACK=none |
| 64 | +
|
| 65 | +for profile_path in "$HOME/.profile" /home/appuser/.profile; do |
| 66 | + if [ -f "$profile_path" ] && [ -r "$profile_path" ]; then |
| 67 | + set +e +u |
| 68 | + source "$profile_path" |
| 69 | + set -euo pipefail |
| 70 | + break |
| 71 | + fi |
| 72 | +done |
| 73 | +if [ -z "${OPENAI_API_KEY:-}" ]; then |
| 74 | + echo "ERROR: OPENAI_API_KEY was not available after sourcing ~/.profile." >&2 |
| 75 | + exit 1 |
| 76 | +fi |
| 77 | +export OPENAI_API_KEY |
| 78 | +if [ -n "${OPENAI_BASE_URL:-}" ]; then |
| 79 | + export OPENAI_BASE_URL |
| 80 | +fi |
| 81 | +
|
| 82 | +CODEX_PLUGIN_SPEC="${OPENCLAW_CODEX_NPM_PLUGIN_SPEC:?missing OPENCLAW_CODEX_NPM_PLUGIN_SPEC}" |
| 83 | +MODEL_REF="${OPENCLAW_CODEX_NPM_PLUGIN_MODEL:?missing OPENCLAW_CODEX_NPM_PLUGIN_MODEL}" |
| 84 | +SESSION_ID="codex-npm-plugin-live" |
| 85 | +SUCCESS_MARKER="OPENCLAW-CODEX-NPM-PLUGIN-LIVE-OK" |
| 86 | +
|
| 87 | +dump_debug_logs() { |
| 88 | + local status="$1" |
| 89 | + echo "Codex npm plugin live scenario failed with exit code $status" >&2 |
| 90 | + openclaw_e2e_dump_logs \ |
| 91 | + /tmp/openclaw-install.log \ |
| 92 | + /tmp/openclaw-codex-plugin-install.log \ |
| 93 | + /tmp/openclaw-codex-plugin-enable.log \ |
| 94 | + /tmp/openclaw-codex-plugins-list.json \ |
| 95 | + /tmp/openclaw-codex-plugin-inspect.json \ |
| 96 | + /tmp/openclaw-codex-preflight.log \ |
| 97 | + /tmp/openclaw-codex-agent.json \ |
| 98 | + /tmp/openclaw-codex-agent.err \ |
| 99 | + /tmp/openclaw-codex-plugin-uninstall.log \ |
| 100 | + /tmp/openclaw-codex-plugins-list-after-uninstall.json \ |
| 101 | + /tmp/openclaw-codex-agent-after-uninstall.json \ |
| 102 | + /tmp/openclaw-codex-agent-after-uninstall.err |
| 103 | +} |
| 104 | +trap 'status=$?; dump_debug_logs "$status"; exit "$status"' ERR |
| 105 | +
|
| 106 | +mkdir -p "$NPM_CONFIG_PREFIX" "$XDG_CACHE_HOME" "$NPM_CONFIG_CACHE" |
| 107 | +chmod 700 "$XDG_CACHE_HOME" "$NPM_CONFIG_CACHE" || true |
| 108 | +
|
| 109 | +openclaw_e2e_install_package /tmp/openclaw-install.log |
| 110 | +command -v openclaw >/dev/null |
| 111 | +
|
| 112 | +echo "Installing Codex plugin from npm: $CODEX_PLUGIN_SPEC" |
| 113 | +openclaw plugins install "$CODEX_PLUGIN_SPEC" --force >/tmp/openclaw-codex-plugin-install.log 2>&1 |
| 114 | +
|
| 115 | +node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs configure "$MODEL_REF" |
| 116 | +
|
| 117 | +echo "Enabling Codex plugin..." |
| 118 | +openclaw plugins enable codex >/tmp/openclaw-codex-plugin-enable.log 2>&1 |
| 119 | +
|
| 120 | +openclaw plugins list --json >/tmp/openclaw-codex-plugins-list.json |
| 121 | +openclaw plugins inspect codex --runtime --json >/tmp/openclaw-codex-plugin-inspect.json |
| 122 | +node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-plugin "$CODEX_PLUGIN_SPEC" |
| 123 | +node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-npm-deps |
| 124 | +
|
| 125 | +CODEX_BIN="$(node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs print-codex-bin)" |
| 126 | +printf '%s\n' "$OPENAI_API_KEY" | "$CODEX_BIN" login --with-api-key >/dev/null |
| 127 | +
|
| 128 | +echo "Running Codex CLI preflight via managed npm dependency..." |
| 129 | +"$CODEX_BIN" exec \ |
| 130 | + --json \ |
| 131 | + --color never \ |
| 132 | + --skip-git-repo-check \ |
| 133 | + "Reply exactly: ${SUCCESS_MARKER}-PREFLIGHT" >/tmp/openclaw-codex-preflight.log 2>&1 |
| 134 | +node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-preflight "${SUCCESS_MARKER}-PREFLIGHT" |
| 135 | +
|
| 136 | +echo "Running OpenClaw local agent turn through npm-installed Codex plugin..." |
| 137 | +openclaw agent --local \ |
| 138 | + --agent main \ |
| 139 | + --session-id "$SESSION_ID" \ |
| 140 | + --model "$MODEL_REF" \ |
| 141 | + --message "Reply exactly: $SUCCESS_MARKER" \ |
| 142 | + --thinking low \ |
| 143 | + --timeout 420 \ |
| 144 | + --json >/tmp/openclaw-codex-agent.json 2>/tmp/openclaw-codex-agent.err |
| 145 | +
|
| 146 | +node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-agent-turn "$SUCCESS_MARKER" "$SESSION_ID" "$MODEL_REF" |
| 147 | +
|
| 148 | +echo "Uninstalling Codex plugin and verifying the configured harness now fails..." |
| 149 | +openclaw plugins uninstall codex --force >/tmp/openclaw-codex-plugin-uninstall.log 2>&1 |
| 150 | +openclaw plugins list --json >/tmp/openclaw-codex-plugins-list-after-uninstall.json |
| 151 | +node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-uninstalled |
| 152 | +
|
| 153 | +set +e |
| 154 | +openclaw agent --local \ |
| 155 | + --agent main \ |
| 156 | + --session-id "${SESSION_ID}-after-uninstall" \ |
| 157 | + --model "$MODEL_REF" \ |
| 158 | + --message "Reply exactly: ${SUCCESS_MARKER}-AFTER-UNINSTALL" \ |
| 159 | + --thinking low \ |
| 160 | + --timeout 120 \ |
| 161 | + --json >/tmp/openclaw-codex-agent-after-uninstall.json 2>/tmp/openclaw-codex-agent-after-uninstall.err |
| 162 | +after_uninstall_status=$? |
| 163 | +set -e |
| 164 | +node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-agent-error "$after_uninstall_status" |
| 165 | +
|
| 166 | +echo "Codex npm plugin live Docker E2E passed" |
| 167 | +EOF |
| 168 | + docker_e2e_print_log "$run_log" |
| 169 | + rm -f "$run_log" |
| 170 | + exit 1 |
| 171 | +fi |
| 172 | + |
| 173 | +rm -f "$run_log" |
| 174 | +echo "Codex npm plugin live Docker E2E passed" |
0 commit comments