ci: keep release checks compatible with stable refs

This commit is contained in:
Peter Steinberger
2026-04-27 13:59:41 +01:00
parent d0e4472616
commit fd4b59a906
11 changed files with 64 additions and 18 deletions

View File

@@ -200,7 +200,8 @@ gh workflow run openclaw-release-checks.yml \
`pnpm openclaw qa matrix` defaults to `--profile all`. Do not assume the CLI
default is the fast release path. Use explicit profiles:
- `--profile fast --fail-fast`: release-critical Matrix transport contract
- `--profile fast`: release-critical Matrix transport contract; add
`--fail-fast` only when the target CLI supports it
- `--profile transport|media|e2ee-smoke|e2ee-deep|e2ee-cli`: sharded full
Matrix proof
- `OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS=3000`: CI-friendly no-reply quiet

View File

@@ -407,15 +407,20 @@ jobs:
output_dir=".artifacts/qa-e2e/matrix-live-release-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
echo "output_dir=${output_dir}" >> "$GITHUB_OUTPUT"
pnpm openclaw qa matrix \
matrix_args=(
--repo-root . \
--output-dir "${output_dir}" \
--provider-mode live-frontier \
--model "${OPENCLAW_CI_OPENAI_MODEL}" \
--alt-model "${OPENCLAW_CI_OPENAI_MODEL}" \
--profile fast \
--fast \
--fail-fast
--fast
)
if pnpm openclaw qa matrix --help 2>/dev/null | grep -F -q -- "--fail-fast"; then
matrix_args+=(--fail-fast)
fi
pnpm openclaw qa matrix "${matrix_args[@]}"
- name: Upload Matrix QA artifacts
if: always()

View File

@@ -259,15 +259,20 @@ jobs:
output_dir=".artifacts/qa-e2e/matrix-live-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
echo "output_dir=${output_dir}" >> "$GITHUB_OUTPUT"
pnpm openclaw qa matrix \
matrix_args=(
--repo-root . \
--output-dir "${output_dir}" \
--provider-mode live-frontier \
--model "${OPENCLAW_CI_OPENAI_MODEL}" \
--alt-model "${OPENCLAW_CI_OPENAI_MODEL}" \
--profile "${INPUT_MATRIX_PROFILE}" \
--fast \
--fail-fast
--fast
)
if pnpm openclaw qa matrix --help 2>/dev/null | grep -F -q -- "--fail-fast"; then
matrix_args+=(--fail-fast)
fi
pnpm openclaw qa matrix "${matrix_args[@]}"
- name: Upload Matrix QA artifacts
if: always()
@@ -336,15 +341,20 @@ jobs:
output_dir=".artifacts/qa-e2e/matrix-live-${{ matrix.profile }}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
echo "output_dir=${output_dir}" >> "$GITHUB_OUTPUT"
pnpm openclaw qa matrix \
matrix_args=(
--repo-root . \
--output-dir "${output_dir}" \
--provider-mode live-frontier \
--model "${OPENCLAW_CI_OPENAI_MODEL}" \
--alt-model "${OPENCLAW_CI_OPENAI_MODEL}" \
--profile "${{ matrix.profile }}" \
--fast \
--fail-fast
--fast
)
if pnpm openclaw qa matrix --help 2>/dev/null | grep -F -q -- "--fail-fast"; then
matrix_args+=(--fail-fast)
fi
pnpm openclaw qa matrix "${matrix_args[@]}"
- name: Upload Matrix QA shard artifacts
if: always()

View File

@@ -172,8 +172,9 @@ agentic packs. The `QA-Lab - All Lanes` workflow runs nightly on `main` and on
manual dispatch; it fans out the mock parity gate, live Matrix lane, and live
Telegram and Discord lanes as parallel jobs. The live jobs use the
`qa-live-shared` environment, and Telegram/Discord use Convex leases. Matrix
uses `--profile fast --fail-fast` for scheduled and release gates while the CLI
default and manual workflow input remain `all`; manual `matrix_profile=all`
uses `--profile fast` for scheduled and release gates, adding `--fail-fast` only
when the checked-out CLI supports it. The CLI default and manual workflow input
remain `all`; manual `matrix_profile=all`
dispatch always shards full Matrix coverage into `transport`, `media`,
`e2ee-smoke`, `e2ee-deep`, and `e2ee-cli` jobs. `OpenClaw Release Checks` also
runs the release-critical QA Lab lanes before release approval.

View File

@@ -10,7 +10,7 @@ const gatewayRpcMock = vi.hoisted(() => {
};
});
vi.mock("openclaw/plugin-sdk/gateway-runtime", () => ({
vi.mock("openclaw/plugin-sdk/browser-node-runtime", () => ({
callGatewayFromCli: gatewayRpcMock.callGatewayFromCli,
}));

View File

@@ -1,5 +1,5 @@
import { callGatewayFromCli } from "openclaw/plugin-sdk/browser-node-runtime";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { callGatewayFromCli } from "openclaw/plugin-sdk/gateway-runtime";
import { formatQaGatewayLogsForError } from "./gateway-log-redaction.js";
type QaGatewayRpcRequestOptions = {

View File

@@ -1,7 +1,7 @@
export type { Command } from "commander";
export type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
export { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
export { callGatewayFromCli } from "openclaw/plugin-sdk/gateway-runtime";
export { callGatewayFromCli } from "openclaw/plugin-sdk/browser-node-runtime";
export type { PluginRuntime } from "openclaw/plugin-sdk/runtime-store";
export { defaultQaRuntimeModelForMode } from "./model-selection.runtime.js";
export {

View File

@@ -2314,7 +2314,7 @@ async function runInstalledBrowserOverrideImportSmoke(params) {
cwd: packageRoot,
env: {
...params.env,
OPENCLAW_BROWSER_CONTROL_MODULE: overridePath,
OPENCLAW_BROWSER_CONTROL_MODULE: pathToFileURL(overridePath).href,
OPENCLAW_BROWSER_OVERRIDE_STARTED_PATH: startedPath,
OPENCLAW_BROWSER_OVERRIDE_STOPPED_PATH: stoppedPath,
},

View File

@@ -57,6 +57,14 @@ describe("package Telegram live Docker E2E", () => {
it("keeps private QA harness imports local while using the installed package dist", () => {
const script = readFileSync(DOCKER_SCRIPT_PATH, "utf8");
const gatewayRpcClient = readFileSync(
path.resolve(TEST_DIR, "../../extensions/qa-lab/src/gateway-rpc-client.ts"),
"utf8",
);
const qaRuntimeApi = readFileSync(
path.resolve(TEST_DIR, "../../extensions/qa-lab/src/runtime-api.ts"),
"utf8",
);
expect(script).toContain('ln -sfnT "$openclaw_package_dir/dist" /app/dist');
expect(script).toContain('cp "$openclaw_package_dir/package.json" /app/package.json');
@@ -66,6 +74,9 @@ describe("package Telegram live Docker E2E", () => {
expect(script).toContain('"./extensions/qa-channel/api.ts"');
expect(script).toContain('pkg.exports["./plugin-sdk/qa-channel-protocol"]');
expect(script).toContain('"./extensions/qa-channel/src/protocol.ts"');
expect(gatewayRpcClient).toContain('from "openclaw/plugin-sdk/browser-node-runtime"');
expect(qaRuntimeApi).toContain('from "openclaw/plugin-sdk/browser-node-runtime"');
expect(gatewayRpcClient).not.toContain('from "openclaw/plugin-sdk/gateway-runtime"');
});
it("exposes installed package dependencies to the mounted QA harness", () => {
@@ -76,7 +87,7 @@ describe("package Telegram live Docker E2E", () => {
'local source="/npm-global/lib/node_modules/openclaw/node_modules/$name"',
);
expect(script).toContain('ln -sfn "$source" "$target"');
expect(script).toContain("link_installed_package_dependency \"$dependency\"");
expect(script).toContain('link_installed_package_dependency "$dependency"');
expect(script).toContain("@modelcontextprotocol/sdk");
expect(script).toContain("yaml");
expect(script).toContain("zod");

View File

@@ -1,4 +1,4 @@
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { createServer as createNetServer } from "node:net";
import { tmpdir } from "node:os";
import { join } from "node:path";
@@ -309,6 +309,9 @@ describe("scripts/openclaw-cross-os-release-checks", () => {
expect(installedScript).toContain(
'from "file:///C:/Users/runner/AppData/Roaming/npm/node_modules/openclaw/dist/plugin-sdk/browser-node-runtime.js"',
);
expect(readFileSync("scripts/openclaw-cross-os-release-checks.ts", "utf8")).toContain(
"OPENCLAW_BROWSER_CONTROL_MODULE: pathToFileURL(overridePath).href",
);
});
it("normalizes Windows installed CLI paths to the cmd shim", () => {

View File

@@ -124,6 +124,21 @@ describe("package artifact reuse", () => {
);
});
it("detects Matrix fail-fast support for older release refs", () => {
const releaseWorkflow = readFileSync(RELEASE_CHECKS_WORKFLOW, "utf8");
const qaWorkflow = readFileSync(".github/workflows/qa-live-transports-convex.yml", "utf8");
expect(releaseWorkflow).toContain("matrix_args=(");
expect(releaseWorkflow).toContain(
'pnpm openclaw qa matrix --help 2>/dev/null | grep -F -q -- "--fail-fast"',
);
expect(releaseWorkflow).toContain("matrix_args+=(--fail-fast)");
expect(releaseWorkflow).toContain('pnpm openclaw qa matrix "${matrix_args[@]}"');
expect(qaWorkflow).toContain(
'pnpm openclaw qa matrix --help 2>/dev/null | grep -F -q -- "--fail-fast"',
);
});
it("names package acceptance Telegram as artifact-backed package validation", () => {
const workflow = readFileSync(PACKAGE_ACCEPTANCE_WORKFLOW, "utf8");