diff --git a/.agents/skills/openclaw-testing/SKILL.md b/.agents/skills/openclaw-testing/SKILL.md index 95fed1f8a3c..bde7b85397a 100644 --- a/.agents/skills/openclaw-testing/SKILL.md +++ b/.agents/skills/openclaw-testing/SKILL.md @@ -176,8 +176,10 @@ that private workflow manually with the full-validation run id. `OpenClaw Release Checks` (`openclaw-release-checks.yml`) is the release child workflow. It is broader than normal CI but narrower than the umbrella because it does not dispatch the separate full normal CI child. It runs Package Acceptance -with `telegram_mode=mock-openai`, so the release package tarball also goes -through Telegram package QA. Use it when release-path validation is needed +with artifact-native delta lanes and `telegram_mode=mock-openai`, so the release +package tarball also goes through offline plugin proof, bundled-channel compat, +and Telegram package QA. The Docker release-path chunks cover the overlapping +package/update/plugin lanes. Use it when release-path validation is needed without rerunning the entire umbrella. ```bash diff --git a/.github/workflows/full-release-validation.yml b/.github/workflows/full-release-validation.yml index c4329db67a3..ee63ab7f330 100644 --- a/.github/workflows/full-release-validation.yml +++ b/.github/workflows/full-release-validation.yml @@ -236,7 +236,7 @@ jobs: if [[ "$status" == "completed" ]]; then break fi - sleep 60 + sleep 30 done conclusion="$(gh run view "$run_id" --json conclusion --jq '.conclusion')" @@ -319,7 +319,7 @@ jobs: if [[ "$status" == "completed" ]]; then break fi - sleep 60 + sleep 30 done conclusion="$(gh run view "$run_id" --json conclusion --jq '.conclusion')" diff --git a/.github/workflows/openclaw-release-checks.yml b/.github/workflows/openclaw-release-checks.yml index fff0e57dcca..9cc9f1883cf 100644 --- a/.github/workflows/openclaw-release-checks.yml +++ b/.github/workflows/openclaw-release-checks.yml @@ -228,7 +228,8 @@ jobs: workflow_ref: ${{ github.ref_name }} source: ref package_ref: ${{ needs.resolve_target.outputs.ref }} - suite_profile: package + suite_profile: custom + docker_lanes: bundled-channel-deps-compat plugins-offline telegram_mode: mock-openai secrets: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} diff --git a/docs/ci.md b/docs/ci.md index 8a4738d4d5f..27f2f525444 100644 --- a/docs/ci.md +++ b/docs/ci.md @@ -91,9 +91,12 @@ Profiles map to Docker coverage: Release checks call Package Acceptance with `source=ref`, `package_ref=`, `workflow_ref=`, -`suite_profile=package`, and `telegram_mode=mock-openai`. That profile is the -GitHub-native replacement for most Parallels package/update validation, with -Telegram proving the same package artifact through the QA live transport. +`suite_profile=custom`, +`docker_lanes='bundled-channel-deps-compat plugins-offline'`, and +`telegram_mode=mock-openai`. The release-path Docker +chunks cover the overlapping package/update/plugin lanes, while Package +Acceptance keeps the artifact-native bundled-channel compat, offline plugin, and +Telegram proof against the same resolved package tarball. Cross-OS release checks still cover OS-specific onboarding, installer, and platform behavior; package/update product validation should start with Package Acceptance. The Windows packaged and installer fresh lanes also verify that an diff --git a/docs/help/testing.md b/docs/help/testing.md index 3f1e7e7f134..22a5182255a 100644 --- a/docs/help/testing.md +++ b/docs/help/testing.md @@ -656,7 +656,7 @@ These Docker runners split into two buckets: `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`. Override those env vars when you explicitly want the larger exhaustive scan. - `test:docker:all` builds the live Docker image once via `test:docker:live-build`, packs OpenClaw once as an npm tarball through `scripts/package-openclaw-for-docker.mjs`, then builds/reuses two `scripts/e2e/Dockerfile` images. The bare image is only the Node/Git runner for install/update/plugin-dependency lanes; those lanes mount the prebuilt tarball. The functional image installs the same tarball into `/app` for built-app functionality lanes. Docker lane definitions live in `scripts/lib/docker-e2e-scenarios.mjs`; planner logic lives in `scripts/lib/docker-e2e-plan.mjs`; `scripts/test-docker-all.mjs` executes the selected plan. The aggregate uses a weighted local scheduler: `OPENCLAW_DOCKER_ALL_PARALLELISM` controls process slots, while resource caps keep heavy live, npm-install, and multi-service lanes from all starting at once. If a single lane is heavier than the active caps, the scheduler can still start it when the pool is empty and then keeps it running alone until capacity is available again. Defaults are 10 slots, `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=10`, and `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`; tune `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` or `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT` only when the Docker host has more headroom. The runner performs a Docker preflight by default, removes stale OpenClaw E2E containers, prints status every 30 seconds, stores successful lane timings in `.artifacts/docker-tests/lane-timings.json`, and uses those timings to start longer lanes first on later runs. Use `OPENCLAW_DOCKER_ALL_DRY_RUN=1` to print the weighted lane manifest without building or running Docker, or `node scripts/test-docker-all.mjs --plan-json` to print the CI plan for selected lanes, package/image needs, and credentials. -- `Package Acceptance` is the GitHub-native package gate for "does this installable tarball work as a product?" It resolves one candidate package from `source=npm`, `source=ref`, `source=url`, or `source=artifact`, uploads it as `package-under-test`, then runs the reusable Docker E2E lanes against that exact tarball instead of repacking the selected ref. `workflow_ref` selects the trusted workflow/harness scripts, while `package_ref` selects the source commit/branch/tag to pack when `source=ref`; this lets current acceptance logic validate older trusted commits. Profiles are ordered by breadth: `smoke` is quick install/channel/agent plus gateway/config, `package` is the package/update/plugin contract and the default native replacement for most Parallels package/update coverage, `product` adds MCP channels, cron/subagent cleanup, OpenAI web search, and OpenWebUI, and `full` runs the release-path Docker chunks with OpenWebUI. Release validation runs the `package` profile for the target ref with Telegram package QA enabled. Targeted GitHub Docker rerun commands generated from artifacts include prior package artifact and prepared image inputs when available, so failed lanes can avoid rebuilding the package and images. +- `Package Acceptance` is the GitHub-native package gate for "does this installable tarball work as a product?" It resolves one candidate package from `source=npm`, `source=ref`, `source=url`, or `source=artifact`, uploads it as `package-under-test`, then runs the reusable Docker E2E lanes against that exact tarball instead of repacking the selected ref. `workflow_ref` selects the trusted workflow/harness scripts, while `package_ref` selects the source commit/branch/tag to pack when `source=ref`; this lets current acceptance logic validate older trusted commits. Profiles are ordered by breadth: `smoke` is quick install/channel/agent plus gateway/config, `package` is the package/update/plugin contract and the default native replacement for most Parallels package/update coverage, `product` adds MCP channels, cron/subagent cleanup, OpenAI web search, and OpenWebUI, and `full` runs the release-path Docker chunks with OpenWebUI. Release validation runs a custom package delta (`bundled-channel-deps-compat plugins-offline`) plus Telegram package QA because the release-path Docker chunks already cover the overlapping package/update/plugin lanes. Targeted GitHub Docker rerun commands generated from artifacts include prior package artifact and prepared image inputs when available, so failed lanes can avoid rebuilding the package and images. - Build and release checks run `scripts/check-cli-bootstrap-imports.mjs` after tsdown. The guard walks the static built graph from `dist/entry.js` and `dist/cli/run-main.js` and fails if pre-dispatch startup imports package dependencies such as Commander, prompt UI, undici, or logging before command dispatch. Packaged CLI smoke also covers root help, onboard help, doctor help, status, config schema, and a model-list command. - Package Acceptance legacy compatibility is capped at `2026.4.25` (`2026.4.25-beta.*` included). Through that cutoff, the harness tolerates only shipped-package metadata gaps: omitted private QA inventory entries, missing `gateway install --wrapper`, missing patch files in the tarball-derived git fixture, missing persisted `update.channel`, legacy plugin install-record locations, missing marketplace install-record persistence, and config metadata migration during `plugins update`. For packages after `2026.4.25`, those paths are strict failures. - Container smoke runners: `test:docker:openwebui`, `test:docker:onboard`, `test:docker:npm-onboard-channel-agent`, `test:docker:update-channel-switch`, `test:docker:session-runtime-context`, `test:docker:agents-delete-shared-workspace`, `test:docker:gateway-network`, `test:docker:browser-cdp-snapshot`, `test:docker:mcp-channels`, `test:docker:pi-bundle-mcp-tools`, `test:docker:cron-mcp-cleanup`, `test:docker:plugins`, `test:docker:plugin-update`, and `test:docker:config-reload` boot one or more real containers and verify higher-level integration paths. diff --git a/docs/reference/RELEASING.md b/docs/reference/RELEASING.md index b880b167b30..ff163dca082 100644 --- a/docs/reference/RELEASING.md +++ b/docs/reference/RELEASING.md @@ -377,14 +377,16 @@ Supported candidate sources: - `source=artifact`: reuse a `.tgz` uploaded by another GitHub Actions run `OpenClaw Release Checks` runs Package Acceptance with `source=ref`, -`package_ref=`, `suite_profile=package`, and -`telegram_mode=mock-openai`. That profile covers install, update, plugin -package contracts through offline plugin fixtures, and Telegram package QA -against the same resolved tarball. It is the GitHub-native replacement for most -of the package/update coverage that previously required Parallels. Cross-OS -release checks still matter for OS-specific onboarding, installer, and platform -behavior, but package/update product validation should prefer Package -Acceptance. +`package_ref=`, `suite_profile=custom`, +`docker_lanes=bundled-channel-deps-compat plugins-offline`, and +`telegram_mode=mock-openai`. The release-path Docker chunks cover the +overlapping install, update, and plugin-update lanes; Package Acceptance keeps +artifact-native bundled-channel compat, offline plugin fixtures, and Telegram +package QA against the same resolved tarball. It is the GitHub-native +replacement for most of the package/update coverage that previously required +Parallels. Cross-OS release checks still matter for OS-specific onboarding, +installer, and platform behavior, but package/update product validation should +prefer Package Acceptance. Legacy package-acceptance leniency is intentionally time boxed. Packages through `2026.4.25` may use the compatibility path for metadata gaps already published diff --git a/scripts/lib/docker-e2e-scenarios.mjs b/scripts/lib/docker-e2e-scenarios.mjs index 30c76656bbc..9af38dd517c 100644 --- a/scripts/lib/docker-e2e-scenarios.mjs +++ b/scripts/lib/docker-e2e-scenarios.mjs @@ -146,8 +146,9 @@ const bundledPluginInstallUninstallLanes = Array.from( `bundled-plugin-install-uninstall-${index}`, `OPENCLAW_BUNDLED_PLUGIN_SWEEP_TOTAL=${BUNDLED_PLUGIN_INSTALL_UNINSTALL_SHARDS} OPENCLAW_BUNDLED_PLUGIN_SWEEP_INDEX=${index} OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:bundled-plugin-install-uninstall`, { + estimateSeconds: 280, resources: ["npm"], - weight: 2, + weight: 1, }, ), ); diff --git a/test/scripts/package-acceptance-workflow.test.ts b/test/scripts/package-acceptance-workflow.test.ts index 51352cf9909..7575d02e6e0 100644 --- a/test/scripts/package-acceptance-workflow.test.ts +++ b/test/scripts/package-acceptance-workflow.test.ts @@ -110,7 +110,8 @@ describe("package artifact reuse", () => { ); expect(workflow).toContain("uses: ./.github/workflows/package-acceptance.yml"); expect(workflow).toContain("package_ref: ${{ needs.resolve_target.outputs.ref }}"); - expect(workflow).toContain("suite_profile: package"); + expect(workflow).toContain("suite_profile: custom"); + expect(workflow).toContain("docker_lanes: bundled-channel-deps-compat plugins-offline"); expect(workflow).toContain("telegram_mode: mock-openai"); expect(workflow).toContain("ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}"); expect(workflow).toContain("ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}");