mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
ci: add live Codex plugin release check
This commit is contained in:
@@ -88,6 +88,11 @@ on:
|
||||
required: false
|
||||
default: ""
|
||||
type: string
|
||||
codex_plugin_spec:
|
||||
description: Optional Codex plugin install spec for live Docker package checks; blank derives from release_package_spec or packs the selected ref
|
||||
required: false
|
||||
default: ""
|
||||
type: string
|
||||
npm_telegram_provider_mode:
|
||||
description: Provider mode for the package Telegram E2E lane
|
||||
required: false
|
||||
@@ -151,6 +156,7 @@ jobs:
|
||||
RELEASE_PACKAGE_SPEC: ${{ inputs.release_package_spec }}
|
||||
EVIDENCE_PACKAGE_SPEC: ${{ inputs.evidence_package_spec }}
|
||||
PACKAGE_ACCEPTANCE_PACKAGE_SPEC: ${{ inputs.package_acceptance_package_spec }}
|
||||
CODEX_PLUGIN_SPEC: ${{ inputs.codex_plugin_spec }}
|
||||
RELEASE_PROFILE: ${{ inputs.release_profile }}
|
||||
RUN_RELEASE_SOAK: ${{ inputs.run_release_soak || inputs.release_profile == 'full' }}
|
||||
RERUN_GROUP: ${{ inputs.rerun_group }}
|
||||
@@ -208,6 +214,9 @@ jobs:
|
||||
else
|
||||
echo "- Package Acceptance package spec: SHA-built release artifact"
|
||||
fi
|
||||
if [[ -n "${CODEX_PLUGIN_SPEC// }" ]]; then
|
||||
echo "- Codex plugin spec: \`${CODEX_PLUGIN_SPEC}\`"
|
||||
fi
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
docker_runtime_assets_preflight:
|
||||
@@ -463,6 +472,7 @@ jobs:
|
||||
CROSS_OS_SUITE_FILTER: ${{ inputs.cross_os_suite_filter }}
|
||||
RELEASE_PACKAGE_SPEC: ${{ inputs.release_package_spec }}
|
||||
PACKAGE_ACCEPTANCE_PACKAGE_SPEC: ${{ inputs.package_acceptance_package_spec }}
|
||||
CODEX_PLUGIN_SPEC: ${{ inputs.codex_plugin_spec }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
@@ -558,6 +568,9 @@ jobs:
|
||||
if [[ -n "${PACKAGE_ACCEPTANCE_PACKAGE_SPEC// }" ]]; then
|
||||
echo "- Package Acceptance package spec: \`${PACKAGE_ACCEPTANCE_PACKAGE_SPEC}\`"
|
||||
fi
|
||||
if [[ -n "${CODEX_PLUGIN_SPEC// }" ]]; then
|
||||
echo "- Codex plugin spec: \`${CODEX_PLUGIN_SPEC}\`"
|
||||
fi
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
child_rerun_group="$RERUN_GROUP"
|
||||
@@ -586,6 +599,9 @@ jobs:
|
||||
if [[ -n "${PACKAGE_ACCEPTANCE_PACKAGE_SPEC// }" ]]; then
|
||||
args+=(-f package_acceptance_package_spec="$PACKAGE_ACCEPTANCE_PACKAGE_SPEC")
|
||||
fi
|
||||
if [[ -n "${CODEX_PLUGIN_SPEC// }" ]]; then
|
||||
args+=(-f codex_plugin_spec="$CODEX_PLUGIN_SPEC")
|
||||
fi
|
||||
|
||||
dispatch_and_wait openclaw-release-checks.yml "${args[@]}"
|
||||
|
||||
|
||||
@@ -68,6 +68,11 @@ on:
|
||||
required: false
|
||||
default: ""
|
||||
type: string
|
||||
codex_plugin_spec:
|
||||
description: Optional Codex plugin install spec for the live package lane; blank packs extensions/codex from the selected ref
|
||||
required: false
|
||||
default: ""
|
||||
type: string
|
||||
include_live_suites:
|
||||
description: Whether to run live-provider coverage
|
||||
required: false
|
||||
@@ -173,6 +178,11 @@ on:
|
||||
required: false
|
||||
default: ""
|
||||
type: string
|
||||
codex_plugin_spec:
|
||||
description: Optional Codex plugin install spec for the live package lane; blank packs extensions/codex from the selected ref
|
||||
required: false
|
||||
default: ""
|
||||
type: string
|
||||
include_live_suites:
|
||||
description: Whether to run live-provider coverage
|
||||
required: false
|
||||
@@ -631,7 +641,7 @@ jobs:
|
||||
profiles: stable full
|
||||
- chunk_id: package-update-openai
|
||||
label: package/update OpenAI install
|
||||
timeout_minutes: 20
|
||||
timeout_minutes: 45
|
||||
profiles: beta minimum stable full
|
||||
- chunk_id: package-update-anthropic
|
||||
label: package/update Anthropic install
|
||||
@@ -734,6 +744,7 @@ jobs:
|
||||
OPENCLAW_DOCKER_E2E_REPO_ROOT: ${{ github.workspace }}
|
||||
OPENCLAW_DOCKER_E2E_SELECTED_SHA: ${{ needs.validate_selected_ref.outputs.selected_sha }}
|
||||
OPENCLAW_DOCKER_ALL_RELEASE_PROFILE: ${{ inputs.release_test_profile }}
|
||||
OPENCLAW_CODEX_NPM_PLUGIN_SPEC: ${{ inputs.codex_plugin_spec }}
|
||||
OPENCLAW_CURRENT_PACKAGE_TGZ: .artifacts/docker-e2e-package/openclaw-current.tgz
|
||||
OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC: ${{ inputs.published_upgrade_survivor_baseline }}
|
||||
OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS: ${{ inputs.published_upgrade_survivor_baselines }}
|
||||
@@ -974,6 +985,7 @@ jobs:
|
||||
OPENCLAW_DOCKER_E2E_PACKAGE_ARTIFACT_NAME: ${{ inputs.package_artifact_name || 'docker-e2e-package' }}
|
||||
OPENCLAW_DOCKER_E2E_REPO_ROOT: ${{ github.workspace }}
|
||||
OPENCLAW_DOCKER_E2E_SELECTED_SHA: ${{ needs.validate_selected_ref.outputs.selected_sha }}
|
||||
OPENCLAW_CODEX_NPM_PLUGIN_SPEC: ${{ inputs.codex_plugin_spec }}
|
||||
OPENCLAW_CURRENT_PACKAGE_TGZ: .artifacts/docker-e2e-package/openclaw-current.tgz
|
||||
OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC: ${{ inputs.published_upgrade_survivor_baseline }}
|
||||
OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS: ${{ matrix.group.published_upgrade_survivor_baselines || inputs.published_upgrade_survivor_baselines }}
|
||||
|
||||
@@ -78,6 +78,11 @@ on:
|
||||
required: false
|
||||
default: ""
|
||||
type: string
|
||||
codex_plugin_spec:
|
||||
description: Optional Codex plugin install spec for live Docker package checks; blank derives from release_package_spec or packs the selected ref
|
||||
required: false
|
||||
default: ""
|
||||
type: string
|
||||
|
||||
concurrency:
|
||||
group: openclaw-release-checks-${{ inputs.expected_sha || inputs.ref }}-${{ inputs.rerun_group }}
|
||||
@@ -112,6 +117,7 @@ jobs:
|
||||
qa_live_slack_enabled: ${{ steps.inputs.outputs.qa_live_slack_enabled }}
|
||||
release_package_spec: ${{ steps.inputs.outputs.release_package_spec }}
|
||||
package_acceptance_package_spec: ${{ steps.inputs.outputs.package_acceptance_package_spec }}
|
||||
codex_plugin_spec: ${{ steps.inputs.outputs.codex_plugin_spec }}
|
||||
steps:
|
||||
- name: Require trusted workflow ref for release checks
|
||||
env:
|
||||
@@ -262,6 +268,7 @@ jobs:
|
||||
RELEASE_QA_SLACK_LIVE_CI_ENABLED: ${{ vars.OPENCLAW_RELEASE_QA_SLACK_LIVE_CI_ENABLED || 'false' }}
|
||||
RELEASE_PACKAGE_SPEC_INPUT: ${{ inputs.release_package_spec }}
|
||||
RELEASE_PACKAGE_ACCEPTANCE_PACKAGE_SPEC_INPUT: ${{ inputs.package_acceptance_package_spec }}
|
||||
RELEASE_CODEX_PLUGIN_SPEC_INPUT: ${{ inputs.codex_plugin_spec }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
qa_live_matrix_enabled=true
|
||||
@@ -307,6 +314,10 @@ jobs:
|
||||
if [[ "$release_profile" == "full" ]]; then
|
||||
run_release_soak=true
|
||||
fi
|
||||
codex_plugin_spec="$RELEASE_CODEX_PLUGIN_SPEC_INPUT"
|
||||
if [[ -z "${codex_plugin_spec// }" && "$RELEASE_PACKAGE_SPEC_INPUT" =~ ^openclaw@(.+)$ ]]; then
|
||||
codex_plugin_spec="npm:@openclaw/codex@${BASH_REMATCH[1]}"
|
||||
fi
|
||||
|
||||
filter="$(printf '%s' "$RELEASE_LIVE_SUITE_FILTER_INPUT" | tr '[:upper:]' '[:lower:]')"
|
||||
if [[ -n "${filter// }" ]]; then
|
||||
@@ -387,6 +398,7 @@ jobs:
|
||||
printf 'qa_live_slack_enabled=%s\n' "$qa_live_slack_enabled"
|
||||
printf 'release_package_spec=%s\n' "$RELEASE_PACKAGE_SPEC_INPUT"
|
||||
printf 'package_acceptance_package_spec=%s\n' "$RELEASE_PACKAGE_ACCEPTANCE_PACKAGE_SPEC_INPUT"
|
||||
printf 'codex_plugin_spec=%s\n' "$codex_plugin_spec"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Summarize validated ref
|
||||
@@ -403,6 +415,7 @@ jobs:
|
||||
RELEASE_CROSS_OS_SUITE_FILTER: ${{ inputs.cross_os_suite_filter }}
|
||||
RELEASE_PACKAGE_SPEC: ${{ inputs.release_package_spec }}
|
||||
PACKAGE_ACCEPTANCE_PACKAGE_SPEC: ${{ inputs.package_acceptance_package_spec }}
|
||||
CODEX_PLUGIN_SPEC: ${{ steps.inputs.outputs.codex_plugin_spec }}
|
||||
run: |
|
||||
{
|
||||
echo "## Release checks"
|
||||
@@ -432,6 +445,11 @@ jobs:
|
||||
else
|
||||
echo "- Package Acceptance package spec: prepared release artifact"
|
||||
fi
|
||||
if [[ -n "${CODEX_PLUGIN_SPEC// }" ]]; then
|
||||
echo "- Codex plugin spec: \`${CODEX_PLUGIN_SPEC}\`"
|
||||
else
|
||||
echo "- Codex plugin spec: packed from selected ref"
|
||||
fi
|
||||
if [[ "$RUN_RELEASE_SOAK" == "true" ]]; then
|
||||
echo "- This run will execute blocking release validation plus exhaustive live/Docker soak coverage."
|
||||
else
|
||||
@@ -640,6 +658,7 @@ jobs:
|
||||
include_live_suites: false
|
||||
release_test_profile: ${{ needs.resolve_target.outputs.release_profile }}
|
||||
package_artifact_name: ${{ needs.prepare_release_package.outputs.artifact_name }}
|
||||
codex_plugin_spec: ${{ needs.resolve_target.outputs.codex_plugin_spec }}
|
||||
secrets: *live_e2e_release_secrets
|
||||
|
||||
package_acceptance_release_checks:
|
||||
|
||||
+3
-3
@@ -154,7 +154,7 @@ Every lane uploads GitHub artifacts. When `CLAWGRIT_REPORTS_TOKEN` is configured
|
||||
|
||||
## Full Release Validation
|
||||
|
||||
`Full Release Validation` is the manual umbrella workflow for "run everything before release." It accepts a branch, tag, or full commit SHA, dispatches the manual `CI` workflow with that target, dispatches `Plugin Prerelease` for release-only plugin/package/static/Docker proof, and dispatches `OpenClaw Release Checks` for install smoke, package acceptance, cross-OS package checks, QA Lab parity, Matrix, and Telegram lanes. Stable/default runs keep exhaustive live/E2E and Docker release-path coverage behind `run_release_soak=true`; `release_profile=full` forces that soak coverage on so broad advisory validation remains broad. With `rerun_group=all` and `release_profile=full`, it also runs `NPM Telegram Beta E2E` against the `release-package-under-test` artifact from release checks. After publishing, pass `release_package_spec` to reuse the shipped npm package across release checks, Package Acceptance, Docker, cross-OS, and Telegram without rebuilding. Use `npm_telegram_package_spec` only when Telegram must prove a different package.
|
||||
`Full Release Validation` is the manual umbrella workflow for "run everything before release." It accepts a branch, tag, or full commit SHA, dispatches the manual `CI` workflow with that target, dispatches `Plugin Prerelease` for release-only plugin/package/static/Docker proof, and dispatches `OpenClaw Release Checks` for install smoke, package acceptance, cross-OS package checks, QA Lab parity, Matrix, and Telegram lanes. Stable/default runs keep exhaustive live/E2E and Docker release-path coverage behind `run_release_soak=true`; `release_profile=full` forces that soak coverage on so broad advisory validation remains broad. With `rerun_group=all` and `release_profile=full`, it also runs `NPM Telegram Beta E2E` against the `release-package-under-test` artifact from release checks. After publishing, pass `release_package_spec` to reuse the shipped npm package across release checks, Package Acceptance, Docker, cross-OS, and Telegram without rebuilding. Use `npm_telegram_package_spec` only when Telegram must prove a different package. The Codex plugin live package lane uses the same selected state by default: published `release_package_spec=openclaw@<tag>` derives `codex_plugin_spec=npm:@openclaw/codex@<tag>`, while SHA/artifact runs pack `extensions/codex` from the selected ref. Set `codex_plugin_spec` explicitly for custom plugin sources such as `npm:`, `npm-pack:`, or `git:` specs.
|
||||
|
||||
See [Full release validation](/reference/full-release-validation) for the
|
||||
stage matrix, exact workflow job names, profile differences, artifacts, and
|
||||
@@ -203,7 +203,7 @@ The umbrella records the dispatched child run ids, and the final `Verify full va
|
||||
|
||||
For recovery, both `Full Release Validation` and `OpenClaw Release Checks` accept `rerun_group`. Use `all` for a release candidate, `ci` for only the normal full CI child, `plugin-prerelease` for only the plugin prerelease child, `release-checks` for every release child, or a narrower group: `install-smoke`, `cross-os`, `live-e2e`, `package`, `qa`, `qa-parity`, `qa-live`, or `npm-telegram` on the umbrella. This keeps a failed release box rerun bounded after a focused fix. For one failed cross-OS lane, combine `rerun_group=cross-os` with `cross_os_suite_filter`, for example `windows/packaged-upgrade`; long cross-OS commands emit heartbeat lines and packaged-upgrade summaries include per-phase timings. QA release-check lanes are advisory except the standard runtime tool coverage gate, which blocks when required OpenClaw dynamic tools drift or disappear from the standard tier summary.
|
||||
|
||||
`OpenClaw Release Checks` uses the trusted workflow ref to resolve the selected ref once into a `release-package-under-test` tarball, then passes that artifact to cross-OS checks and Package Acceptance, plus the live/E2E release-path Docker workflow when soak coverage runs. That keeps the package bytes consistent across release boxes and avoids repacking the same candidate in multiple child jobs.
|
||||
`OpenClaw Release Checks` uses the trusted workflow ref to resolve the selected ref once into a `release-package-under-test` tarball, then passes that artifact to cross-OS checks and Package Acceptance, plus the live/E2E release-path Docker workflow when soak coverage runs. That keeps the package bytes consistent across release boxes and avoids repacking the same candidate in multiple child jobs. For the Codex npm-plugin live lane, release checks either pass a matching published plugin spec derived from `release_package_spec`, pass the operator-supplied `codex_plugin_spec`, or leave the input blank so the Docker script packs the selected checkout's Codex plugin.
|
||||
|
||||
Duplicate `Full Release Validation` runs for `ref=main` and `rerun_group=all`
|
||||
supersede the older umbrella. The parent monitor cancels any child workflow it
|
||||
@@ -371,7 +371,7 @@ Release Docker coverage runs smaller chunked jobs with `OPENCLAW_SKIP_DOCKER_BUI
|
||||
- `OPENCLAW_DOCKER_ALL_PROFILE=release-path`
|
||||
- `OPENCLAW_DOCKER_ALL_CHUNK=core | package-update-openai | package-update-anthropic | package-update-core | plugins-runtime-plugins | plugins-runtime-services | plugins-runtime-install-a..h`
|
||||
|
||||
Current release Docker chunks are `core`, `package-update-openai`, `package-update-anthropic`, `package-update-core`, `plugins-runtime-plugins`, `plugins-runtime-services`, and `plugins-runtime-install-a` through `plugins-runtime-install-h`. `plugins-runtime-core`, `plugins-runtime`, and `plugins-integrations` remain aggregate plugin/runtime aliases. The `install-e2e` lane alias remains the aggregate manual rerun alias for both provider installer lanes.
|
||||
Current release Docker chunks are `core`, `package-update-openai`, `package-update-anthropic`, `package-update-core`, `plugins-runtime-plugins`, `plugins-runtime-services`, and `plugins-runtime-install-a` through `plugins-runtime-install-h`. `package-update-openai` includes the live Codex plugin package lane, which installs the candidate OpenClaw package, installs the Codex plugin from `codex_plugin_spec` or a same-ref tarball with explicit Codex CLI install approval, runs Codex CLI preflight, then runs multiple same-session OpenClaw agent turns against OpenAI. `plugins-runtime-core`, `plugins-runtime`, and `plugins-integrations` remain aggregate plugin/runtime aliases. The `install-e2e` lane alias remains the aggregate manual rerun alias for both provider installer lanes.
|
||||
|
||||
OpenWebUI is folded into `plugins-runtime-services` when full release-path coverage requests it, and keeps a standalone `openwebui` chunk only for OpenWebUI-only dispatches. Bundled-channel update lanes retry once for transient npm network failures.
|
||||
|
||||
|
||||
@@ -38,6 +38,12 @@ beta publish, pass `release_package_spec=openclaw@YYYY.M.D-beta.N` to reuse the
|
||||
shipped npm package across release checks, Package Acceptance, cross-OS,
|
||||
release-path Docker, and package Telegram. Use `package_acceptance_package_spec`
|
||||
only when Package Acceptance should intentionally prove a different package.
|
||||
The Codex plugin live package lane follows the same state: published
|
||||
`release_package_spec` values derive `codex_plugin_spec=npm:@openclaw/codex@<version>`;
|
||||
SHA/artifact runs pack `extensions/codex` from the selected ref; and operators
|
||||
can set `codex_plugin_spec` directly for `npm:`, `npm-pack:`, or `git:` plugin
|
||||
sources. The lane grants the explicit Codex CLI install approval required by
|
||||
that plugin, then runs Codex CLI preflight and same-session OpenAI agent turns.
|
||||
|
||||
## Top-level stages
|
||||
|
||||
@@ -81,15 +87,15 @@ or Docker-facing stages need it.
|
||||
The Docker release-path stage runs these chunks when `live_suite_filter` is
|
||||
empty:
|
||||
|
||||
| Chunk | Coverage |
|
||||
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
|
||||
| `core` | Core Docker release-path smoke lanes. |
|
||||
| `package-update-openai` | OpenAI package install/update behavior, Codex on-demand install, and Chat Completions tool calls. |
|
||||
| `package-update-anthropic` | Anthropic package install and update behavior. |
|
||||
| `package-update-core` | Provider-neutral package and update behavior. |
|
||||
| `plugins-runtime-plugins` | Plugin runtime lanes that exercise plugin behavior. |
|
||||
| `plugins-runtime-services` | Service-backed and live plugin runtime lanes; includes OpenWebUI when requested. |
|
||||
| `plugins-runtime-install-a` through `plugins-runtime-install-h` | Plugin install/runtime batches split for parallel release validation. |
|
||||
| Chunk | Coverage |
|
||||
| --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `core` | Core Docker release-path smoke lanes. |
|
||||
| `package-update-openai` | OpenAI package install/update behavior, Codex on-demand install, Codex plugin live turns, and Chat Completions tool calls. |
|
||||
| `package-update-anthropic` | Anthropic package install and update behavior. |
|
||||
| `package-update-core` | Provider-neutral package and update behavior. |
|
||||
| `plugins-runtime-plugins` | Plugin runtime lanes that exercise plugin behavior. |
|
||||
| `plugins-runtime-services` | Service-backed and live plugin runtime lanes; includes OpenWebUI when requested. |
|
||||
| `plugins-runtime-install-a` through `plugins-runtime-install-h` | Plugin install/runtime batches split for parallel release validation. |
|
||||
|
||||
Use targeted `docker_lanes=<lane[,lane]>` on the reusable live/E2E workflow when
|
||||
only one Docker lane failed. The release artifacts include per-lane rerun
|
||||
|
||||
@@ -1,19 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
# Installs OpenClaw from a prepared package tarball, installs @openclaw/codex
|
||||
# from the real npm registry, and verifies a live Codex app-server turn.
|
||||
# from a registry/git/tarball spec, and verifies a live Codex app-server turn.
|
||||
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"
|
||||
SCRIPT_ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
TRUSTED_HARNESS_DIR="${OPENCLAW_LIVE_DOCKER_TRUSTED_HARNESS_DIR:-$SCRIPT_ROOT_DIR}"
|
||||
CANDIDATE_ROOT="${OPENCLAW_LIVE_DOCKER_REPO_ROOT:-$SCRIPT_ROOT_DIR}"
|
||||
TRUSTED_HARNESS_DIR="$(cd "$TRUSTED_HARNESS_DIR" && pwd)"
|
||||
CANDIDATE_ROOT="$(cd "$CANDIDATE_ROOT" && pwd)"
|
||||
ROOT_DIR="$TRUSTED_HARNESS_DIR"
|
||||
source "$TRUSTED_HARNESS_DIR/scripts/lib/docker-e2e-image.sh"
|
||||
source "$TRUSTED_HARNESS_DIR/scripts/lib/docker-e2e-package.sh"
|
||||
|
||||
IMAGE_NAME="$(docker_e2e_resolve_image "openclaw-codex-npm-plugin-live-e2e" OPENCLAW_CODEX_NPM_PLUGIN_E2E_IMAGE)"
|
||||
DOCKER_TARGET="${OPENCLAW_CODEX_NPM_PLUGIN_DOCKER_TARGET:-bare}"
|
||||
HOST_BUILD="${OPENCLAW_CODEX_NPM_PLUGIN_HOST_BUILD:-1}"
|
||||
PACKAGE_TGZ="${OPENCLAW_CURRENT_PACKAGE_TGZ:-}"
|
||||
PROFILE_FILE="${OPENCLAW_CODEX_NPM_PLUGIN_PROFILE_FILE:-${OPENCLAW_TESTBOX_PROFILE_FILE:-$HOME/.openclaw-testbox-live.profile}}"
|
||||
CODEX_PLUGIN_SPEC="${OPENCLAW_CODEX_NPM_PLUGIN_SPEC:-}"
|
||||
CODEX_PLUGIN_MOUNT=()
|
||||
CODEX_PLUGIN_PACK_DIR=""
|
||||
|
||||
docker_e2e_build_or_reuse "$IMAGE_NAME" codex-npm-plugin-live "$ROOT_DIR/scripts/e2e/Dockerfile" "$ROOT_DIR" "$DOCKER_TARGET"
|
||||
docker_e2e_build_or_reuse "$IMAGE_NAME" codex-npm-plugin-live "$CANDIDATE_ROOT/scripts/e2e/Dockerfile" "$CANDIDATE_ROOT" "$DOCKER_TARGET"
|
||||
|
||||
prepare_package_tgz() {
|
||||
if [ -n "$PACKAGE_TGZ" ]; then
|
||||
@@ -24,11 +32,60 @@ prepare_package_tgz() {
|
||||
echo "OPENCLAW_CODEX_NPM_PLUGIN_HOST_BUILD=0 requires OPENCLAW_CURRENT_PACKAGE_TGZ" >&2
|
||||
exit 1
|
||||
fi
|
||||
local harness_root="$ROOT_DIR"
|
||||
ROOT_DIR="$CANDIDATE_ROOT"
|
||||
PACKAGE_TGZ="$(docker_e2e_prepare_package_tgz codex-npm-plugin-live)"
|
||||
ROOT_DIR="$harness_root"
|
||||
}
|
||||
|
||||
prepare_package_tgz
|
||||
|
||||
prepare_codex_plugin_spec() {
|
||||
local source_path
|
||||
local container_path
|
||||
local pack_output
|
||||
|
||||
if [ -z "$CODEX_PLUGIN_SPEC" ]; then
|
||||
CODEX_PLUGIN_PACK_DIR="$(mktemp -d "${TMPDIR:-/tmp}/openclaw-codex-plugin-pack.XXXXXX")"
|
||||
(
|
||||
cd "$CANDIDATE_ROOT"
|
||||
node scripts/lib/plugin-npm-runtime-build.mjs extensions/codex
|
||||
node scripts/lib/plugin-npm-package-manifest.mjs --run extensions/codex -- \
|
||||
npm pack --json --ignore-scripts --pack-destination "$CODEX_PLUGIN_PACK_DIR"
|
||||
) >/tmp/openclaw-codex-plugin-pack.log 2>&1
|
||||
pack_output=()
|
||||
while IFS= read -r packed_file; do
|
||||
pack_output+=("$packed_file")
|
||||
done < <(find "$CODEX_PLUGIN_PACK_DIR" -maxdepth 1 -type f -name '*.tgz' | sort)
|
||||
if [ "${#pack_output[@]}" -ne 1 ]; then
|
||||
echo "Expected one packed Codex plugin tarball; found ${#pack_output[@]}." >&2
|
||||
cat /tmp/openclaw-codex-plugin-pack.log >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
source_path="${pack_output[0]}"
|
||||
container_path="/tmp/$(basename "$source_path")"
|
||||
CODEX_PLUGIN_MOUNT=(-v "$source_path":"$container_path":ro)
|
||||
CODEX_PLUGIN_SPEC="npm-pack:$container_path"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "$CODEX_PLUGIN_SPEC" == npm-pack:* ]]; then
|
||||
source_path="${CODEX_PLUGIN_SPEC#npm-pack:}"
|
||||
if [[ "$source_path" != /* ]]; then
|
||||
source_path="$CANDIDATE_ROOT/$source_path"
|
||||
fi
|
||||
if [ ! -f "$source_path" ]; then
|
||||
echo "Codex plugin npm-pack tarball not found: $source_path" >&2
|
||||
exit 1
|
||||
fi
|
||||
container_path="/tmp/$(basename "$source_path")"
|
||||
CODEX_PLUGIN_MOUNT=(-v "$source_path":"$container_path":ro)
|
||||
CODEX_PLUGIN_SPEC="npm-pack:$container_path"
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_codex_plugin_spec
|
||||
|
||||
PROFILE_MOUNT=()
|
||||
PROFILE_STATUS="none"
|
||||
if [ -f "$PROFILE_FILE" ] && [ -r "$PROFILE_FILE" ]; then
|
||||
@@ -46,16 +103,18 @@ OPENCLAW_TEST_STATE_SCRIPT_B64="$(docker_e2e_test_state_shell_b64 codex-npm-plug
|
||||
|
||||
echo "Running Codex npm plugin live Docker E2E..."
|
||||
echo "Profile file: $PROFILE_STATUS"
|
||||
echo "Codex plugin spec: $CODEX_PLUGIN_SPEC"
|
||||
if ! docker_e2e_run_with_harness \
|
||||
-e COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \
|
||||
-e OPENCLAW_CODEX_NPM_PLUGIN_ALLOW_BETA_COMPAT_DIAGNOSTICS="${OPENCLAW_CODEX_NPM_PLUGIN_ALLOW_BETA_COMPAT_DIAGNOSTICS:-0}" \
|
||||
-e OPENCLAW_CODEX_NPM_PLUGIN_FORCE_UNSAFE_INSTALL="${OPENCLAW_CODEX_NPM_PLUGIN_FORCE_UNSAFE_INSTALL:-0}" \
|
||||
-e OPENCLAW_CODEX_NPM_PLUGIN_FORCE_UNSAFE_INSTALL="${OPENCLAW_CODEX_NPM_PLUGIN_FORCE_UNSAFE_INSTALL:-1}" \
|
||||
-e OPENCLAW_CODEX_NPM_PLUGIN_MODEL="${OPENCLAW_CODEX_NPM_PLUGIN_MODEL:-codex/gpt-5.4}" \
|
||||
-e OPENCLAW_CODEX_NPM_PLUGIN_SPEC="${OPENCLAW_CODEX_NPM_PLUGIN_SPEC:-npm:@openclaw/codex}" \
|
||||
-e OPENCLAW_CODEX_NPM_PLUGIN_SPEC="$CODEX_PLUGIN_SPEC" \
|
||||
-e OPENAI_API_KEY \
|
||||
-e OPENAI_BASE_URL \
|
||||
-e "OPENCLAW_TEST_STATE_SCRIPT_B64=$OPENCLAW_TEST_STATE_SCRIPT_B64" \
|
||||
"${DOCKER_E2E_PACKAGE_ARGS[@]}" \
|
||||
"${CODEX_PLUGIN_MOUNT[@]}" \
|
||||
"${PROFILE_MOUNT[@]}" \
|
||||
-i "$IMAGE_NAME" bash -s >"$run_log" 2>&1 <<'EOF'; then
|
||||
set -euo pipefail
|
||||
@@ -108,6 +167,10 @@ dump_debug_logs() {
|
||||
/tmp/openclaw-codex-preflight.log \
|
||||
/tmp/openclaw-codex-agent.json \
|
||||
/tmp/openclaw-codex-agent.err \
|
||||
/tmp/openclaw-codex-agent-turn1.json \
|
||||
/tmp/openclaw-codex-agent-turn1.err \
|
||||
/tmp/openclaw-codex-agent-turn2.json \
|
||||
/tmp/openclaw-codex-agent-turn2.err \
|
||||
/tmp/openclaw-codex-plugin-uninstall.log \
|
||||
/tmp/openclaw-codex-plugins-list-after-uninstall.json \
|
||||
/tmp/openclaw-codex-agent-after-uninstall.json \
|
||||
@@ -121,7 +184,7 @@ chmod 700 "$XDG_CACHE_HOME" "$NPM_CONFIG_CACHE" || true
|
||||
openclaw_e2e_install_package /tmp/openclaw-install.log
|
||||
command -v openclaw >/dev/null
|
||||
|
||||
echo "Installing Codex plugin from npm: $CODEX_PLUGIN_SPEC"
|
||||
echo "Installing Codex plugin: $CODEX_PLUGIN_SPEC"
|
||||
openclaw plugins install "$CODEX_PLUGIN_SPEC" "${PLUGIN_INSTALL_FLAGS[@]}" >/tmp/openclaw-codex-plugin-install.log 2>&1
|
||||
|
||||
node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs configure "$MODEL_REF"
|
||||
@@ -137,43 +200,101 @@ node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-npm-deps
|
||||
CODEX_BIN="$(node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs print-codex-bin)"
|
||||
printf '%s\n' "$OPENAI_API_KEY" | "$CODEX_BIN" login --with-api-key >/dev/null
|
||||
|
||||
print_agent_reply() {
|
||||
node -e '
|
||||
const fs = require("node:fs");
|
||||
const file = process.argv[1];
|
||||
const marker = process.argv[2];
|
||||
const label = process.argv[3];
|
||||
const response = JSON.parse(fs.readFileSync(file, "utf8"));
|
||||
const text = (response.payloads || [])
|
||||
.map((payload) => (payload && typeof payload.text === "string" ? payload.text : ""))
|
||||
.filter(Boolean)
|
||||
.join("\n")
|
||||
.trim();
|
||||
console.log(`${label}: ${text}`);
|
||||
if (!text.includes(marker)) {
|
||||
console.error(`missing marker ${marker} in ${file}`);
|
||||
process.exit(1);
|
||||
}
|
||||
' "$1" "$2" "$3"
|
||||
}
|
||||
|
||||
run_agent_turn() {
|
||||
local label="$1"
|
||||
local marker="$2"
|
||||
local message="$3"
|
||||
local out="$4"
|
||||
local err="$5"
|
||||
|
||||
echo "${label}_prompt: $message"
|
||||
openclaw agent --local \
|
||||
--agent main \
|
||||
--session-id "$SESSION_ID" \
|
||||
--model "$MODEL_REF" \
|
||||
--message "$message" \
|
||||
--thinking low \
|
||||
--timeout 420 \
|
||||
--json >"$out" 2>"$err" </dev/null
|
||||
print_agent_reply "$out" "$marker" "${label}_reply"
|
||||
}
|
||||
|
||||
echo "TRANSCRIPT_BEGIN"
|
||||
echo "Running Codex CLI preflight via managed npm dependency..."
|
||||
echo "codex_cli_prompt: Reply exactly: ${SUCCESS_MARKER}-PREFLIGHT"
|
||||
"$CODEX_BIN" exec \
|
||||
--json \
|
||||
--color never \
|
||||
--skip-git-repo-check \
|
||||
"Reply exactly: ${SUCCESS_MARKER}-PREFLIGHT" >/tmp/openclaw-codex-preflight.log 2>&1
|
||||
"Reply exactly: ${SUCCESS_MARKER}-PREFLIGHT" >/tmp/openclaw-codex-preflight.log 2>&1 </dev/null
|
||||
node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-preflight "${SUCCESS_MARKER}-PREFLIGHT"
|
||||
echo "codex_cli_reply: ${SUCCESS_MARKER}-PREFLIGHT"
|
||||
|
||||
echo "Running OpenClaw local agent turn through npm-installed Codex plugin..."
|
||||
openclaw agent --local \
|
||||
--agent main \
|
||||
--session-id "$SESSION_ID" \
|
||||
--model "$MODEL_REF" \
|
||||
--message "Reply exactly: $SUCCESS_MARKER" \
|
||||
--thinking low \
|
||||
--timeout 420 \
|
||||
--json >/tmp/openclaw-codex-agent.json 2>/tmp/openclaw-codex-agent.err
|
||||
echo "Running OpenClaw local agent turns through npm-installed Codex plugin..."
|
||||
run_agent_turn \
|
||||
"turn1" \
|
||||
"${SUCCESS_MARKER}-TURN-1" \
|
||||
"Reply in one short sentence. Include token ${SUCCESS_MARKER}-TURN-1 and say hello from the OpenClaw Codex plugin." \
|
||||
/tmp/openclaw-codex-agent-turn1.json \
|
||||
/tmp/openclaw-codex-agent-turn1.err
|
||||
run_agent_turn \
|
||||
"turn2" \
|
||||
"${SUCCESS_MARKER}-TURN-2" \
|
||||
"Using this same conversation, name the exact token from your previous reply, then include token ${SUCCESS_MARKER}-TURN-2." \
|
||||
/tmp/openclaw-codex-agent-turn2.json \
|
||||
/tmp/openclaw-codex-agent-turn2.err
|
||||
run_agent_turn \
|
||||
"turn3" \
|
||||
"$SUCCESS_MARKER" \
|
||||
"Answer 7 plus 8, include token $SUCCESS_MARKER, and mention whether you saw ${SUCCESS_MARKER}-TURN-2 earlier." \
|
||||
/tmp/openclaw-codex-agent.json \
|
||||
/tmp/openclaw-codex-agent.err
|
||||
|
||||
node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-agent-turn "$SUCCESS_MARKER" "$SESSION_ID" "$MODEL_REF"
|
||||
echo "TRANSCRIPT_END"
|
||||
|
||||
echo "Uninstalling Codex plugin and verifying the configured harness now fails..."
|
||||
openclaw plugins uninstall codex --force >/tmp/openclaw-codex-plugin-uninstall.log 2>&1
|
||||
openclaw plugins list --json >/tmp/openclaw-codex-plugins-list-after-uninstall.json
|
||||
node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-uninstalled
|
||||
|
||||
set +e
|
||||
openclaw agent --local \
|
||||
if openclaw agent --local \
|
||||
--agent main \
|
||||
--session-id "${SESSION_ID}-after-uninstall" \
|
||||
--model "$MODEL_REF" \
|
||||
--message "Reply exactly: ${SUCCESS_MARKER}-AFTER-UNINSTALL" \
|
||||
--thinking low \
|
||||
--timeout 120 \
|
||||
--json >/tmp/openclaw-codex-agent-after-uninstall.json 2>/tmp/openclaw-codex-agent-after-uninstall.err
|
||||
after_uninstall_status=$?
|
||||
set -e
|
||||
node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-agent-error "$after_uninstall_status"
|
||||
--json >/tmp/openclaw-codex-agent-after-uninstall.json 2>/tmp/openclaw-codex-agent-after-uninstall.err; then
|
||||
echo "Expected OpenClaw agent to fail after Codex uninstall, got status 0" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! grep -Fq 'Requested agent harness "codex" is not registered' /tmp/openclaw-codex-agent-after-uninstall.err &&
|
||||
! grep -Fq 'Unknown model: codex/' /tmp/openclaw-codex-agent-after-uninstall.err; then
|
||||
echo "Unexpected post-uninstall agent error:" >&2
|
||||
cat /tmp/openclaw-codex-agent-after-uninstall.err >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Codex npm plugin live Docker E2E passed"
|
||||
EOF
|
||||
@@ -182,5 +303,6 @@ EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
awk '/TRANSCRIPT_BEGIN/{printing=1} printing{print} /TRANSCRIPT_END/{printing=0}' "$run_log"
|
||||
rm -f "$run_log"
|
||||
echo "Codex npm plugin live Docker E2E passed"
|
||||
|
||||
@@ -95,6 +95,32 @@ function readInstallRecords() {
|
||||
return index.installRecords || index.records || {};
|
||||
}
|
||||
|
||||
function normalizePluginSpec(spec) {
|
||||
if (spec.startsWith("npm:")) {
|
||||
return {
|
||||
expectedSpec: spec.slice("npm:".length),
|
||||
source: "npm",
|
||||
};
|
||||
}
|
||||
if (spec.startsWith("npm-pack:")) {
|
||||
return {
|
||||
artifactKind: "npm-pack",
|
||||
source: "npm",
|
||||
sourcePath: spec.slice("npm-pack:".length),
|
||||
};
|
||||
}
|
||||
if (spec.startsWith("git:")) {
|
||||
return {
|
||||
expectedSpec: spec,
|
||||
source: "git",
|
||||
};
|
||||
}
|
||||
return {
|
||||
expectedSpec: spec,
|
||||
source: "npm",
|
||||
};
|
||||
}
|
||||
|
||||
function assertPlugin() {
|
||||
const spec = process.argv[3] || "npm:@openclaw/codex";
|
||||
const list = readJson("/tmp/openclaw-codex-plugins-list.json");
|
||||
@@ -141,16 +167,32 @@ function assertPlugin() {
|
||||
}
|
||||
|
||||
const record = readInstallRecord();
|
||||
const expectedSpec = spec.replace(/^npm:/u, "");
|
||||
if (record.source !== "npm") {
|
||||
throw new Error(`expected codex npm install record, got source=${record.source}`);
|
||||
const expected = normalizePluginSpec(spec);
|
||||
if (record.source !== expected.source) {
|
||||
throw new Error(
|
||||
`expected codex ${expected.source} install record, got source=${record.source}`,
|
||||
);
|
||||
}
|
||||
if (record.spec !== expectedSpec) {
|
||||
throw new Error(`expected codex npm spec ${expectedSpec}, got ${record.spec}`);
|
||||
if (expected.expectedSpec && record.spec !== expected.expectedSpec) {
|
||||
throw new Error(`expected codex install spec ${expected.expectedSpec}, got ${record.spec}`);
|
||||
}
|
||||
if (!record.resolvedVersion || !record.resolvedSpec) {
|
||||
if (expected.artifactKind && record.artifactKind !== expected.artifactKind) {
|
||||
throw new Error(
|
||||
`expected codex artifact kind ${expected.artifactKind}, got ${record.artifactKind}`,
|
||||
);
|
||||
}
|
||||
if (
|
||||
expected.sourcePath &&
|
||||
realPathMaybe(record.sourcePath || "") !== realPathMaybe(expected.sourcePath)
|
||||
) {
|
||||
throw new Error(`expected codex source path ${expected.sourcePath}, got ${record.sourcePath}`);
|
||||
}
|
||||
if (record.source === "npm" && (!record.resolvedVersion || !record.resolvedSpec)) {
|
||||
throw new Error(`missing codex npm resolution metadata: ${JSON.stringify(record)}`);
|
||||
}
|
||||
if (record.source === "git" && !record.gitCommit) {
|
||||
throw new Error(`missing codex git resolution metadata: ${JSON.stringify(record)}`);
|
||||
}
|
||||
}
|
||||
|
||||
function managedNpmRoot() {
|
||||
@@ -307,6 +349,12 @@ function assertAgentTurn() {
|
||||
`OpenClaw agent reply did not contain ${marker}:\nstdout=${stdout}\nstderr=${stderr}`,
|
||||
);
|
||||
}
|
||||
const executionTrace = response.meta?.executionTrace;
|
||||
if (!executionTrace || executionTrace.winnerProvider !== "codex") {
|
||||
throw new Error(
|
||||
`expected Codex plugin to win the agent turn, got ${JSON.stringify(executionTrace)}`,
|
||||
);
|
||||
}
|
||||
|
||||
const sessionsDir = path.join(stateDir(), "agents", "main", "sessions");
|
||||
const storePath = path.join(sessionsDir, "sessions.json");
|
||||
@@ -333,17 +381,22 @@ function assertAgentTurn() {
|
||||
if (binding.model !== modelRef.split("/").slice(1).join("/")) {
|
||||
throw new Error(`unexpected Codex binding model: ${binding.model}`);
|
||||
}
|
||||
if (binding.modelProvider && binding.modelProvider !== "codex") {
|
||||
if (binding.modelProvider && !["codex", "openai"].includes(binding.modelProvider)) {
|
||||
throw new Error(`unexpected Codex binding provider: ${binding.modelProvider}`);
|
||||
}
|
||||
|
||||
const codexHome = path.join(stateDir(), "agents", "main", "agent", "codex-home");
|
||||
const nativeHome = path.join(codexHome, "home");
|
||||
if (!fs.existsSync(codexHome) || !fs.existsSync(nativeHome)) {
|
||||
throw new Error(`missing isolated Codex home: ${codexHome}`);
|
||||
const agentDir = path.join(stateDir(), "agents", "main");
|
||||
const codexHomes = [
|
||||
path.join(agentDir, "codex-home"),
|
||||
path.join(agentDir, "agent", "codex-home"),
|
||||
path.join(path.dirname(agentDir), "codex-home"),
|
||||
].filter((entry, index, entries) => entries.indexOf(entry) === index);
|
||||
const codexHome = codexHomes.find((entry) => fs.existsSync(entry));
|
||||
if (!codexHome) {
|
||||
throw new Error(`missing isolated Codex home; checked ${codexHomes.join(", ")}`);
|
||||
}
|
||||
const codexSessionRoot = path.join(codexHome, "sessions");
|
||||
const nativeSessionRoot = path.join(nativeHome, ".codex", "sessions");
|
||||
const nativeSessionRoot = path.join(codexHome, "home", ".codex", "sessions");
|
||||
assertNativeCodexSessionEvidence({
|
||||
codexHome,
|
||||
marker,
|
||||
@@ -387,7 +440,10 @@ function assertAgentError() {
|
||||
? fs.readFileSync("/tmp/openclaw-codex-agent-after-uninstall.err", "utf8")
|
||||
: "";
|
||||
const combined = `${stdout}\n${stderr}`;
|
||||
if (!combined.includes('Requested agent harness "codex" is not registered')) {
|
||||
if (
|
||||
!combined.includes('Requested agent harness "codex" is not registered') &&
|
||||
!combined.includes("Unknown model: codex/")
|
||||
) {
|
||||
throw new Error(`unexpected post-uninstall agent error:\nstdout=${stdout}\nstderr=${stderr}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,6 +159,22 @@ function liveOpenAiChatToolsLane() {
|
||||
);
|
||||
}
|
||||
|
||||
function liveCodexNpmPluginLane() {
|
||||
return liveLane(
|
||||
"live-codex-npm-plugin",
|
||||
liveDockerScriptCommand("e2e/codex-npm-plugin-live-docker.sh"),
|
||||
{
|
||||
cacheKey: "codex-npm-plugin",
|
||||
e2eImageKind: "bare",
|
||||
provider: "openai",
|
||||
resources: ["npm"],
|
||||
stateScenario: "empty",
|
||||
timeoutMs: 30 * 60 * 1000,
|
||||
weight: 3,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export const mainLanes = [
|
||||
liveLane("live-models", liveDockerScriptCommand("test-live-models-docker.sh"), {
|
||||
providers: ["claude-cli", "google-gemini-cli"],
|
||||
@@ -484,19 +500,7 @@ export const tailLanes = [
|
||||
weight: 3,
|
||||
},
|
||||
),
|
||||
liveLane(
|
||||
"live-codex-npm-plugin",
|
||||
"OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:live-codex-npm-plugin",
|
||||
{
|
||||
cacheKey: "codex-npm-plugin",
|
||||
e2eImageKind: "bare",
|
||||
provider: "openai",
|
||||
resources: ["npm"],
|
||||
stateScenario: "empty",
|
||||
timeoutMs: 30 * 60 * 1000,
|
||||
weight: 3,
|
||||
},
|
||||
),
|
||||
liveCodexNpmPluginLane(),
|
||||
livePluginToolLane(),
|
||||
liveLane(
|
||||
"live-acp-bind-claude",
|
||||
@@ -633,6 +637,7 @@ const releasePathPackageInstallOpenAiLanes = [
|
||||
},
|
||||
),
|
||||
liveOpenAiChatToolsLane(),
|
||||
liveCodexNpmPluginLane(),
|
||||
npmLane("codex-on-demand", "OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:codex-on-demand", {
|
||||
resources: ["service"],
|
||||
stateScenario: "empty",
|
||||
|
||||
@@ -113,6 +113,7 @@ describe("scripts/lib/docker-e2e-plan", () => {
|
||||
expect(plan.credentials).toEqual(["anthropic", "openai"]);
|
||||
expect(plan.lanes.map((lane) => lane.name)).toContain("install-e2e-openai");
|
||||
expect(plan.lanes.map((lane) => lane.name)).toContain("openai-chat-tools");
|
||||
expect(plan.lanes.map((lane) => lane.name)).toContain("live-codex-npm-plugin");
|
||||
expect(plan.lanes.map((lane) => lane.name)).toContain("codex-on-demand");
|
||||
expect(plan.lanes.map((lane) => lane.name)).toContain("install-e2e-anthropic");
|
||||
expect(plan.lanes.map((lane) => lane.name)).toContain("mcp-channels");
|
||||
@@ -157,6 +158,7 @@ describe("scripts/lib/docker-e2e-plan", () => {
|
||||
expect(plan.releaseProfile).toBe("beta");
|
||||
expect(laneNames).toContain("install-e2e-openai");
|
||||
expect(laneNames).toContain("openai-chat-tools");
|
||||
expect(laneNames).toContain("live-codex-npm-plugin");
|
||||
expect(laneNames).toContain("install-e2e-anthropic");
|
||||
expect(laneNames).toContain("update-channel-switch");
|
||||
expect(laneNames).not.toContain("plugins");
|
||||
@@ -246,6 +248,7 @@ describe("scripts/lib/docker-e2e-plan", () => {
|
||||
expect(packageInstallOpenAi.lanes.map((lane) => lane.name)).toEqual([
|
||||
"install-e2e-openai",
|
||||
"openai-chat-tools",
|
||||
"live-codex-npm-plugin",
|
||||
"codex-on-demand",
|
||||
]);
|
||||
expect(packageInstallAnthropic.lanes.map((lane) => lane.name)).toEqual([
|
||||
@@ -483,6 +486,7 @@ describe("scripts/lib/docker-e2e-plan", () => {
|
||||
expect(packageUpdate.lanes.map((lane) => lane.name)).toEqual([
|
||||
"install-e2e-openai",
|
||||
"openai-chat-tools",
|
||||
"live-codex-npm-plugin",
|
||||
"codex-on-demand",
|
||||
"install-e2e-anthropic",
|
||||
"npm-onboard-channel-agent",
|
||||
@@ -653,7 +657,8 @@ describe("scripts/lib/docker-e2e-plan", () => {
|
||||
expect(plan.credentials).toEqual(["openai"]);
|
||||
expect(plan.lanes.map(summarizeLane)).toEqual([
|
||||
{
|
||||
command: "OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:live-codex-npm-plugin",
|
||||
command:
|
||||
'OPENCLAW_SKIP_DOCKER_BUILD=1 bash -c \'harness="${OPENCLAW_DOCKER_E2E_TRUSTED_HARNESS_DIR:-}"; if [ -z "$harness" ]; then if [ -d .release-harness/scripts ]; then harness=.release-harness; else harness=.; fi; fi; OPENCLAW_LIVE_DOCKER_REPO_ROOT="${OPENCLAW_DOCKER_E2E_REPO_ROOT:-$PWD}" bash "$harness/scripts/e2e/codex-npm-plugin-live-docker.sh"\'',
|
||||
imageKind: "bare",
|
||||
live: true,
|
||||
name: "live-codex-npm-plugin",
|
||||
|
||||
@@ -166,6 +166,14 @@ describe("package acceptance workflow", () => {
|
||||
expect(workflow).toContain(
|
||||
'args+=(-f package_acceptance_package_spec="$PACKAGE_ACCEPTANCE_PACKAGE_SPEC")',
|
||||
);
|
||||
expect(workflow).toContain("codex_plugin_spec:");
|
||||
expect(workflow).toContain('args+=(-f codex_plugin_spec="$CODEX_PLUGIN_SPEC")');
|
||||
expect(releaseChecksWorkflow).toContain(
|
||||
'codex_plugin_spec="npm:@openclaw/codex@${BASH_REMATCH[1]}"',
|
||||
);
|
||||
expect(releaseChecksWorkflow).toContain(
|
||||
"codex_plugin_spec: ${{ needs.resolve_target.outputs.codex_plugin_spec }}",
|
||||
);
|
||||
expect(workflow).toContain("--json status,conclusion,url,attempt,headSha,jobs");
|
||||
expect(workflow).toContain(
|
||||
'[[ "$CHILD_WORKFLOW_REF" == release-ci/* && -n "${TARGET_SHA// }" && "$head_sha" != "$TARGET_SHA" ]]',
|
||||
@@ -525,6 +533,9 @@ describe("package artifact reuse", () => {
|
||||
expect(scenarios).toMatch(/liveDockerScriptCommand\(\s*"test-live-cli-backend-docker\.sh"/u);
|
||||
expect(scenarios).toMatch(/liveDockerScriptCommand\(\s*"test-live-acp-bind-docker\.sh"/u);
|
||||
expect(scenarios).toMatch(/liveDockerScriptCommand\(\s*"test-live-codex-harness-docker\.sh"/u);
|
||||
expect(scenarios).toMatch(
|
||||
/liveDockerScriptCommand\(\s*"e2e\/codex-npm-plugin-live-docker\.sh"/u,
|
||||
);
|
||||
expect(scenarios).toMatch(
|
||||
/liveDockerScriptCommand\(\s*"test-live-subagent-announce-docker\.sh"/u,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user