From b1439ca527c34bd39140008b8ad653ab62cc4963 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Mon, 27 Apr 2026 20:37:57 -0700 Subject: [PATCH] fix(ci): keep codex live harness helpers trusted --- scripts/lib/live-docker-stage.sh | 3 ++- scripts/test-live-build-docker.sh | 6 +++-- scripts/test-live-codex-harness-docker.sh | 26 ++++++++++-------- .../package-acceptance-workflow.test.ts | 27 +++++++++++++++++++ 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/scripts/lib/live-docker-stage.sh b/scripts/lib/live-docker-stage.sh index 4b3d3f2ccd8..3da8d0ddca4 100644 --- a/scripts/lib/live-docker-stage.sh +++ b/scripts/lib/live-docker-stage.sh @@ -103,8 +103,9 @@ openclaw_live_prepare_staged_config() { return 0 fi + local scripts_dir="${OPENCLAW_LIVE_DOCKER_SCRIPTS_DIR:-/src/scripts}" ( cd /app - node --import tsx /src/scripts/live-docker-normalize-config.ts + node --import tsx "$scripts_dir/live-docker-normalize-config.ts" ) } diff --git a/scripts/test-live-build-docker.sh b/scripts/test-live-build-docker.sh index f067279bf41..35e42403578 100755 --- a/scripts/test-live-build-docker.sh +++ b/scripts/test-live-build-docker.sh @@ -1,8 +1,10 @@ #!/usr/bin/env bash set -euo pipefail -ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -source "$ROOT_DIR/scripts/lib/docker-build.sh" +SCRIPT_ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +ROOT_DIR="${OPENCLAW_LIVE_DOCKER_REPO_ROOT:-$SCRIPT_ROOT_DIR}" +ROOT_DIR="$(cd "$ROOT_DIR" && pwd)" +source "$SCRIPT_ROOT_DIR/scripts/lib/docker-build.sh" IMAGE_NAME="${OPENCLAW_IMAGE:-openclaw:local}" LIVE_IMAGE_NAME="${OPENCLAW_LIVE_IMAGE:-${IMAGE_NAME}-live}" DOCKER_BUILD_EXTENSIONS="${OPENCLAW_DOCKER_BUILD_EXTENSIONS:-${OPENCLAW_EXTENSIONS:-}}" diff --git a/scripts/test-live-codex-harness-docker.sh b/scripts/test-live-codex-harness-docker.sh index 7b126d4fd46..ea70001cc09 100644 --- a/scripts/test-live-codex-harness-docker.sh +++ b/scripts/test-live-codex-harness-docker.sh @@ -4,14 +4,19 @@ set -euo pipefail SCRIPT_ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" ROOT_DIR="${OPENCLAW_LIVE_DOCKER_REPO_ROOT:-$SCRIPT_ROOT_DIR}" ROOT_DIR="$(cd "$ROOT_DIR" && pwd)" -source "$ROOT_DIR/scripts/lib/live-docker-auth.sh" +TRUSTED_HARNESS_DIR="${OPENCLAW_LIVE_CODEX_TRUSTED_HARNESS_DIR:-$SCRIPT_ROOT_DIR}" +if [[ -z "$TRUSTED_HARNESS_DIR" || ! -d "$TRUSTED_HARNESS_DIR" ]]; then + echo "ERROR: trusted Codex harness directory not found: ${TRUSTED_HARNESS_DIR:-}." >&2 + exit 1 +fi +TRUSTED_HARNESS_DIR="$(cd "$TRUSTED_HARNESS_DIR" && pwd)" +source "$TRUSTED_HARNESS_DIR/scripts/lib/live-docker-auth.sh" IMAGE_NAME="${OPENCLAW_IMAGE:-openclaw:local}" LIVE_IMAGE_NAME="${OPENCLAW_LIVE_IMAGE:-${IMAGE_NAME}-live}" CONFIG_DIR="${OPENCLAW_CONFIG_DIR:-$HOME/.openclaw}" WORKSPACE_DIR="${OPENCLAW_WORKSPACE_DIR:-$HOME/.openclaw/workspace}" PROFILE_FILE="${OPENCLAW_PROFILE_FILE:-$HOME/.profile}" CODEX_HARNESS_AUTH_MODE="${OPENCLAW_LIVE_CODEX_HARNESS_AUTH:-codex-auth}" -TRUSTED_HARNESS_DIR="${OPENCLAW_LIVE_CODEX_TRUSTED_HARNESS_DIR:-$SCRIPT_ROOT_DIR}" TEMP_DIRS=() DOCKER_USER="${OPENCLAW_DOCKER_USER:-node}" DOCKER_HOME_MOUNT=() @@ -86,11 +91,8 @@ if [[ -f "$PROFILE_FILE" && -r "$PROFILE_FILE" ]]; then PROFILE_STATUS="$PROFILE_FILE" fi -if [[ -n "$TRUSTED_HARNESS_DIR" && -d "$TRUSTED_HARNESS_DIR" ]]; then - TRUSTED_HARNESS_DIR="$(cd "$TRUSTED_HARNESS_DIR" && pwd)" - DOCKER_TRUSTED_HARNESS_CONTAINER_DIR="/trusted-harness" - DOCKER_TRUSTED_HARNESS_MOUNT=(-v "$TRUSTED_HARNESS_DIR":"$DOCKER_TRUSTED_HARNESS_CONTAINER_DIR":ro) -fi +DOCKER_TRUSTED_HARNESS_CONTAINER_DIR="/trusted-harness" +DOCKER_TRUSTED_HARNESS_MOUNT=(-v "$TRUSTED_HARNESS_DIR":"$DOCKER_TRUSTED_HARNESS_CONTAINER_DIR":ro) AUTH_FILES=() if [[ "$CODEX_HARNESS_AUTH_MODE" != "api-key" ]]; then @@ -170,8 +172,9 @@ if [ "${OPENCLAW_LIVE_CODEX_HARNESS_AUTH:-codex-auth}" != "api-key" ] && [ ! -s echo "ERROR: missing ~/.codex/auth.json for Codex harness live test." >&2 exit 1 fi +trusted_scripts_dir="${OPENCLAW_LIVE_DOCKER_SCRIPTS_DIR:-/src/scripts}" if [ "${OPENCLAW_LIVE_CODEX_HARNESS_AUTH:-codex-auth}" != "api-key" ]; then - node --import tsx /src/scripts/prepare-codex-ci-auth.ts "$HOME/.codex/auth.json" + node --import tsx "$trusted_scripts_dir/prepare-codex-ci-auth.ts" "$HOME/.codex/auth.json" fi if [ ! -x "$NPM_CONFIG_PREFIX/bin/codex" ]; then npm install -g @openai/codex @@ -180,7 +183,7 @@ if [ "${OPENCLAW_LIVE_CODEX_HARNESS_AUTH:-codex-auth}" = "api-key" ]; then printf '%s\n' "$OPENAI_API_KEY" | "$NPM_CONFIG_PREFIX/bin/codex" login --with-api-key >/dev/null fi tmp_dir="$(mktemp -d)" -source /src/scripts/lib/live-docker-stage.sh +source "$trusted_scripts_dir/lib/live-docker-stage.sh" openclaw_live_stage_source_tree "$tmp_dir" openclaw_live_stage_node_modules "$tmp_dir" openclaw_live_link_runtime_tree "$tmp_dir" @@ -196,7 +199,7 @@ fi openclaw_live_prepare_staged_config cd "$tmp_dir" if [ "${OPENCLAW_LIVE_CODEX_HARNESS_USE_CI_SAFE_CODEX_CONFIG:-1}" = "1" ]; then - node --import tsx /src/scripts/prepare-codex-ci-config.ts "$HOME/.codex/config.toml" "$tmp_dir" + node --import tsx "$trusted_scripts_dir/prepare-codex-ci-config.ts" "$HOME/.codex/config.toml" "$tmp_dir" fi codex_preflight_log="$tmp_dir/codex-preflight.log" codex_preflight_token="CODEX-PREFLIGHT-OK" @@ -216,7 +219,7 @@ pnpm test:live ${OPENCLAW_LIVE_CODEX_TEST_FILES:-src/gateway/gateway-codex-harne EOF openclaw_live_codex_harness_append_build_extension codex -"$ROOT_DIR/scripts/test-live-build-docker.sh" +OPENCLAW_LIVE_DOCKER_REPO_ROOT="$ROOT_DIR" "$TRUSTED_HARNESS_DIR/scripts/test-live-build-docker.sh" echo "==> Run Codex harness live test in Docker" echo "==> Model: ${OPENCLAW_LIVE_CODEX_HARNESS_MODEL:-codex/gpt-5.5}" @@ -254,6 +257,7 @@ DOCKER_RUN_ARGS=(docker run --rm -t \ -e OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY="${OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY:-}" \ -e OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE="${OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE:-1}" \ -e OPENCLAW_LIVE_CODEX_HARNESS_USE_CI_SAFE_CODEX_CONFIG="${OPENCLAW_LIVE_CODEX_HARNESS_USE_CI_SAFE_CODEX_CONFIG:-1}" \ + -e OPENCLAW_LIVE_DOCKER_SCRIPTS_DIR="${DOCKER_TRUSTED_HARNESS_CONTAINER_DIR}/scripts" \ -e OPENCLAW_LIVE_CODEX_TRUSTED_HARNESS_DIR="$DOCKER_TRUSTED_HARNESS_CONTAINER_DIR" \ -e OPENCLAW_LIVE_CODEX_BIND="${OPENCLAW_LIVE_CODEX_BIND:-}" \ -e OPENCLAW_LIVE_CODEX_BIND_MODEL="${OPENCLAW_LIVE_CODEX_BIND_MODEL:-}" \ diff --git a/test/scripts/package-acceptance-workflow.test.ts b/test/scripts/package-acceptance-workflow.test.ts index b7de9b124cc..b096e3a9329 100644 --- a/test/scripts/package-acceptance-workflow.test.ts +++ b/test/scripts/package-acceptance-workflow.test.ts @@ -129,6 +129,33 @@ describe("package artifact reuse", () => { expect(workflow).toContain("if: matrix.needs_ffmpeg"); }); + it("runs the Codex Docker live harness from trusted helper scripts", () => { + const workflow = readFileSync(LIVE_E2E_WORKFLOW, "utf8"); + const harness = readFileSync("scripts/test-live-codex-harness-docker.sh", "utf8"); + const build = readFileSync("scripts/test-live-build-docker.sh", "utf8"); + const stage = readFileSync("scripts/lib/live-docker-stage.sh", "utf8"); + + expect(workflow).toContain( + 'command: OPENCLAW_LIVE_DOCKER_REPO_ROOT="$GITHUB_WORKSPACE" bash .release-harness/scripts/test-live-codex-harness-docker.sh', + ); + expect(harness).toContain('source "$TRUSTED_HARNESS_DIR/scripts/lib/live-docker-auth.sh"'); + expect(harness).not.toContain('source "$ROOT_DIR/scripts/lib/live-docker-auth.sh"'); + expect(harness).toContain( + 'OPENCLAW_LIVE_DOCKER_REPO_ROOT="$ROOT_DIR" "$TRUSTED_HARNESS_DIR/scripts/test-live-build-docker.sh"', + ); + expect(harness).toContain( + '-e OPENCLAW_LIVE_DOCKER_SCRIPTS_DIR="${DOCKER_TRUSTED_HARNESS_CONTAINER_DIR}/scripts"', + ); + expect(harness).toContain('node --import tsx "$trusted_scripts_dir/prepare-codex-ci-auth.ts"'); + expect(harness).toContain('source "$trusted_scripts_dir/lib/live-docker-stage.sh"'); + expect(build).toContain('ROOT_DIR="${OPENCLAW_LIVE_DOCKER_REPO_ROOT:-$SCRIPT_ROOT_DIR}"'); + expect(build).toContain('source "$SCRIPT_ROOT_DIR/scripts/lib/docker-build.sh"'); + expect(stage).toContain( + 'local scripts_dir="${OPENCLAW_LIVE_DOCKER_SCRIPTS_DIR:-/src/scripts}"', + ); + expect(stage).toContain('node --import tsx "$scripts_dir/live-docker-normalize-config.ts"'); + }); + it("allows the Telegram lane to run from reusable package acceptance artifacts", () => { const workflow = readFileSync(NPM_TELEGRAM_WORKFLOW, "utf8");