Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Adolf is a fork/vendored clone of github.com/openclaw/openclaw (v2026.6.11), free to diverge. Tree copied sans upstream .git; upstream remote added for future syncs. Node pinned to 24 (.nvmrc); engines already require >=22.19. Preserves docs/ARCHITECTURE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
143 lines
4.5 KiB
JavaScript
143 lines
4.5 KiB
JavaScript
// Docker E2E CI helper.
|
|
// Converts scheduler JSON into GitHub Actions outputs and compact markdown
|
|
// summaries so the workflow does not duplicate Docker E2E planning logic.
|
|
import { readDockerE2eJsonArtifact } from "./lib/docker-e2e-json-artifacts.mjs";
|
|
|
|
function usage() {
|
|
return [
|
|
"Usage:",
|
|
" node scripts/docker-e2e.mjs github-outputs <plan.json>",
|
|
" node scripts/docker-e2e.mjs summary <summary.json> <title>",
|
|
" node scripts/docker-e2e.mjs failed-reruns <summary.json>",
|
|
].join("\n");
|
|
}
|
|
|
|
function readJson(file) {
|
|
return readDockerE2eJsonArtifact(file);
|
|
}
|
|
|
|
function boolOutput(value) {
|
|
return value ? "1" : "0";
|
|
}
|
|
|
|
function githubOutputs(plan) {
|
|
const needs = plan.needs ?? {};
|
|
return [
|
|
`credentials=${(plan.credentials ?? []).join(",")}`,
|
|
`needs_bare_image=${boolOutput(needs.bareImage)}`,
|
|
`needs_e2e_image=${boolOutput(needs.e2eImage)}`,
|
|
`needs_functional_image=${boolOutput(needs.functionalImage)}`,
|
|
`needs_live_image=${boolOutput(needs.liveImage)}`,
|
|
`needs_package=${boolOutput(needs.package)}`,
|
|
];
|
|
}
|
|
|
|
function markdownCell(value) {
|
|
return String(value ?? "").replaceAll("|", "\\|");
|
|
}
|
|
|
|
function inlineCode(value) {
|
|
return `\`${String(value ?? "").replaceAll("`", "\\`")}\``;
|
|
}
|
|
|
|
function formatSeconds(value) {
|
|
const seconds = Number(value);
|
|
if (!Number.isFinite(seconds) || seconds < 0) {
|
|
return "";
|
|
}
|
|
const rounded = Math.round(seconds);
|
|
const minutes = Math.floor(rounded / 60);
|
|
const rest = rounded % 60;
|
|
return minutes > 0 ? `${minutes}m ${rest}s` : `${rest}s`;
|
|
}
|
|
|
|
function summaryMarkdown(summary, title) {
|
|
const lanes = Array.isArray(summary.lanes) ? summary.lanes : [];
|
|
const slowest = lanes
|
|
.filter((lane) => Number.isFinite(Number(lane.elapsedSeconds)))
|
|
.toSorted((a, b) => Number(b.elapsedSeconds) - Number(a.elapsedSeconds))
|
|
.slice(0, 8);
|
|
const lines = [
|
|
`### ${title}`,
|
|
"",
|
|
`Status: ${inlineCode(summary.status)}`,
|
|
"",
|
|
"| Lane | Status | Seconds | Timed out | Rerun |",
|
|
"| --- | ---: | ---: | --- | --- |",
|
|
];
|
|
for (const lane of lanes) {
|
|
const status = lane.status === 0 ? "pass" : `fail ${lane.status}`;
|
|
lines.push(
|
|
`| ${inlineCode(lane.name)} | ${markdownCell(status)} | ${markdownCell(lane.elapsedSeconds)} | ${lane.timedOut ? "yes" : "no"} | ${inlineCode(lane.rerunCommand)} |`,
|
|
);
|
|
}
|
|
|
|
if (slowest.length > 0) {
|
|
lines.push("", "| Slowest lane | Duration | Status |", "| --- | ---: | --- |");
|
|
for (const lane of slowest) {
|
|
const status = lane.status === 0 ? "pass" : `fail ${lane.status}`;
|
|
lines.push(
|
|
`| ${inlineCode(lane.name)} | ${markdownCell(formatSeconds(lane.elapsedSeconds))} | ${markdownCell(status)} |`,
|
|
);
|
|
}
|
|
}
|
|
|
|
const phases = Array.isArray(summary.phases) ? summary.phases : [];
|
|
if (phases.length > 0) {
|
|
lines.push("", "| Phase | Duration | Status | Image kind |", "| --- | ---: | --- | --- |");
|
|
for (const phase of phases) {
|
|
lines.push(
|
|
`| ${inlineCode(phase.name)} | ${markdownCell(formatSeconds(phase.elapsedSeconds))} | ${markdownCell(phase.status)} | ${markdownCell(phase.imageKind)} |`,
|
|
);
|
|
}
|
|
}
|
|
const failedReruns = failedRerunCommands(summary);
|
|
if (failedReruns.length > 0) {
|
|
lines.push("", "Failed lane reruns:", "");
|
|
for (const command of failedReruns) {
|
|
lines.push(`- ${inlineCode(command)}`);
|
|
}
|
|
}
|
|
return lines.join("\n");
|
|
}
|
|
|
|
function failedRerunCommands(summary) {
|
|
const lanes = Array.isArray(summary.lanes) ? summary.lanes : [];
|
|
return lanes
|
|
.filter((lane) => lane.status !== 0 && lane.rerunCommand)
|
|
.map((lane) => lane.rerunCommand);
|
|
}
|
|
|
|
function main(argv = process.argv.slice(2)) {
|
|
const [command, file, ...args] = argv;
|
|
if (command === "--help" || command === "-h") {
|
|
process.stdout.write(`${usage()}\n`);
|
|
return 0;
|
|
}
|
|
if (!command || !file) {
|
|
throw new Error(usage());
|
|
}
|
|
|
|
if (command === "github-outputs") {
|
|
process.stdout.write(`${githubOutputs(readJson(file)).join("\n")}\n`);
|
|
} else if (command === "summary") {
|
|
const title = args.join(" ").trim();
|
|
if (!title) {
|
|
throw new Error(usage());
|
|
}
|
|
process.stdout.write(`${summaryMarkdown(readJson(file), title)}\n`);
|
|
} else if (command === "failed-reruns") {
|
|
process.stdout.write(`${failedRerunCommands(readJson(file)).join("\n")}\n`);
|
|
} else {
|
|
throw new Error(`unknown command: ${command}\n${usage()}`);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
try {
|
|
process.exitCode = main();
|
|
} catch (error) {
|
|
console.error(error instanceof Error ? error.message : String(error));
|
|
process.exitCode = 1;
|
|
}
|