diff --git a/.github/workflows/openclaw-live-and-e2e-checks-reusable.yml b/.github/workflows/openclaw-live-and-e2e-checks-reusable.yml index ed126fac9fd..8448323d832 100644 --- a/.github/workflows/openclaw-live-and-e2e-checks-reusable.yml +++ b/.github/workflows/openclaw-live-and-e2e-checks-reusable.yml @@ -1875,18 +1875,20 @@ jobs: case "${{ matrix.suite_id }}" in live-cli-backend-docker) echo "OPENCLAW_LIVE_CLI_BACKEND_MODEL=codex-cli/gpt-5.5" >> "$GITHUB_ENV" - # The CLI backend Docker lane should exercise the same staged - # Codex auth path Peter uses locally so MCP cron creation and - # multimodal probes stay covered in CI. Replace the staged - # config.toml with a minimal CI-safe config so the repo stays - # trusted for MCP/tool use without inheriting maintainer-local - # provider/profile overrides that do not exist inside CI. + # Keep the release-blocking CI lane on Codex API-key auth. The + # staged auth-file path remains supported for local maintainer + # reruns, but it can hang on stale subscription/session state in + # an otherwise healthy release run. + echo "OPENCLAW_LIVE_CLI_BACKEND_AUTH=api-key" >> "$GITHUB_ENV" + # Replace the staged config.toml with a minimal CI-safe config so + # the repo stays trusted for MCP/tool use without inheriting + # maintainer-local provider/profile overrides that do not exist + # inside CI. # Codex's workspace-write sandbox relies on user namespaces that # this Docker lane does not provide, so run Codex unsandboxed # inside the already-isolated container to keep MCP cron/tool # execution representative instead of failing on nested sandbox # setup. - echo 'OPENCLAW_LIVE_CLI_BACKEND_CLEAR_ENV=["OPENAI_API_KEY","OPENAI_BASE_URL"]' >> "$GITHUB_ENV" echo 'OPENCLAW_LIVE_CLI_BACKEND_ARGS=["exec","--json","--color","never","--sandbox","danger-full-access","--skip-git-repo-check"]' >> "$GITHUB_ENV" echo 'OPENCLAW_LIVE_CLI_BACKEND_RESUME_ARGS=["exec","resume","{sessionId}","-c","sandbox_mode=\"danger-full-access\"","--skip-git-repo-check"]' >> "$GITHUB_ENV" echo "OPENCLAW_LIVE_CLI_BACKEND_DEBUG=1" >> "$GITHUB_ENV" diff --git a/scripts/e2e/openwebui-docker.sh b/scripts/e2e/openwebui-docker.sh index 54f080e8774..1ab9f05d441 100755 --- a/scripts/e2e/openwebui-docker.sh +++ b/scripts/e2e/openwebui-docker.sh @@ -23,6 +23,7 @@ GW_NAME="openclaw-openwebui-gateway-$$" OW_NAME="openclaw-openwebui-$$" DOCKER_COMMAND_TIMEOUT="${OPENCLAW_OPENWEBUI_DOCKER_COMMAND_TIMEOUT:-600s}" DOCKER_PULL_TIMEOUT="${OPENCLAW_OPENWEBUI_DOCKER_PULL_TIMEOUT:-600s}" +OPENWEBUI_READY_ATTEMPTS="${OPENCLAW_OPENWEBUI_READY_ATTEMPTS:-420}" docker_cmd() { timeout "$DOCKER_COMMAND_TIMEOUT" "$@" @@ -177,7 +178,7 @@ docker_cmd docker run -d \ echo "Waiting for Open WebUI..." ow_ready=0 -for _ in $(seq 1 240); do +for _ in $(seq 1 "$OPENWEBUI_READY_ATTEMPTS"); do if [ "$(docker_cmd docker inspect -f '{{.State.Running}}' "$OW_NAME" 2>/dev/null || echo false)" != "true" ]; then break fi diff --git a/test/scripts/package-acceptance-workflow.test.ts b/test/scripts/package-acceptance-workflow.test.ts index d408f435d48..562dbc29d6f 100644 --- a/test/scripts/package-acceptance-workflow.test.ts +++ b/test/scripts/package-acceptance-workflow.test.ts @@ -6,6 +6,7 @@ const LIVE_E2E_WORKFLOW = ".github/workflows/openclaw-live-and-e2e-checks-reusab const NPM_TELEGRAM_WORKFLOW = ".github/workflows/npm-telegram-beta-e2e.yml"; const RELEASE_CHECKS_WORKFLOW = ".github/workflows/openclaw-release-checks.yml"; const FULL_RELEASE_VALIDATION_WORKFLOW = ".github/workflows/full-release-validation.yml"; +const OPENWEBUI_DOCKER_SCRIPT = "scripts/e2e/openwebui-docker.sh"; describe("package acceptance workflow", () => { it("resolves candidate package sources before reusing Docker E2E lanes", () => { @@ -110,6 +111,20 @@ describe("package artifact reuse", () => { expect(workflow).not.toContain("cache-to: type=gha,mode=max,scope=docker-e2e"); }); + it("keeps release Docker live and Open WebUI checks patient in CI", () => { + const workflow = readFileSync(LIVE_E2E_WORKFLOW, "utf8"); + const openwebui = readFileSync(OPENWEBUI_DOCKER_SCRIPT, "utf8"); + + expect(workflow).toContain("OPENCLAW_LIVE_CLI_BACKEND_AUTH=api-key"); + expect(workflow).not.toContain( + 'OPENCLAW_LIVE_CLI_BACKEND_CLEAR_ENV=["OPENAI_API_KEY","OPENAI_BASE_URL"]', + ); + expect(openwebui).toContain( + 'OPENWEBUI_READY_ATTEMPTS="${OPENCLAW_OPENWEBUI_READY_ATTEMPTS:-420}"', + ); + expect(openwebui).toContain('seq 1 "$OPENWEBUI_READY_ATTEMPTS"'); + }); + it("shards broad native live tests instead of one serial live-all job", () => { const workflow = readFileSync(LIVE_E2E_WORKFLOW, "utf8");