mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-06 23:55:12 +00:00
ci(docker): split bundled release lanes
This commit is contained in:
@@ -286,6 +286,10 @@ image. Release-path normal mode remains max three Docker chunk jobs:
|
||||
|
||||
OpenWebUI is folded into `plugins-integrations` for full release-path coverage
|
||||
and keeps a standalone `openwebui` chunk only for OpenWebUI-only dispatches.
|
||||
The bundled-channel runtime-dependency coverage inside `plugins-integrations`
|
||||
uses the split `bundled-channel-*` and `bundled-channel-update-*` lanes rather
|
||||
than the serial `bundled-channel-deps` lane, so failures produce cheap targeted
|
||||
reruns for the exact channel/update scenario.
|
||||
|
||||
## Package Acceptance
|
||||
|
||||
@@ -448,7 +452,7 @@ these rough bands:
|
||||
`session-runtime-context` ~20s, `gateway-network` ~34s, `qr` ~44s.
|
||||
- Medium deterministic lanes, ~1-5 minutes:
|
||||
`npm-onboard-channel-agent` ~96s, `openai-image-auth` ~99s,
|
||||
bundled channel/update lanes usually ~90-300s, `openwebui` ~225s,
|
||||
bundled channel/update lanes usually ~90-300s when split, `openwebui` ~225s,
|
||||
`mcp-channels` ~274s.
|
||||
- Heavy deterministic lanes, ~6-10 minutes:
|
||||
`bundled-channel-root-owned` ~429s,
|
||||
|
||||
@@ -483,6 +483,7 @@ jobs:
|
||||
OPENCLAW_DOCKER_E2E_BARE_IMAGE: ${{ needs.prepare_docker_e2e_image.outputs.bare_image }}
|
||||
OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE: ${{ needs.prepare_docker_e2e_image.outputs.functional_image }}
|
||||
OPENCLAW_DOCKER_E2E_PACKAGE_ARTIFACT_NAME: ${{ inputs.package_artifact_name || 'docker-e2e-package' }}
|
||||
OPENCLAW_DOCKER_E2E_SELECTED_SHA: ${{ needs.validate_selected_ref.outputs.selected_sha }}
|
||||
OPENCLAW_CURRENT_PACKAGE_TGZ: .artifacts/docker-e2e-package/openclaw-current.tgz
|
||||
OPENCLAW_SKIP_DOCKER_BUILD: "1"
|
||||
INCLUDE_OPENWEBUI: ${{ inputs.include_openwebui }}
|
||||
@@ -611,6 +612,7 @@ jobs:
|
||||
OPENCLAW_DOCKER_E2E_BARE_IMAGE: ${{ needs.prepare_docker_e2e_image.outputs.bare_image }}
|
||||
OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE: ${{ needs.prepare_docker_e2e_image.outputs.functional_image }}
|
||||
OPENCLAW_DOCKER_E2E_PACKAGE_ARTIFACT_NAME: ${{ inputs.package_artifact_name || 'docker-e2e-package' }}
|
||||
OPENCLAW_DOCKER_E2E_SELECTED_SHA: ${{ needs.validate_selected_ref.outputs.selected_sha }}
|
||||
OPENCLAW_CURRENT_PACKAGE_TGZ: .artifacts/docker-e2e-package/openclaw-current.tgz
|
||||
OPENCLAW_SKIP_DOCKER_BUILD: "1"
|
||||
INCLUDE_OPENWEBUI: ${{ inputs.include_openwebui }}
|
||||
@@ -698,6 +700,7 @@ jobs:
|
||||
OPENCLAW_DOCKER_E2E_IMAGE: ${{ needs.prepare_docker_e2e_image.outputs.image }}
|
||||
OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE: ${{ needs.prepare_docker_e2e_image.outputs.functional_image }}
|
||||
OPENCLAW_DOCKER_E2E_PACKAGE_ARTIFACT_NAME: ${{ inputs.package_artifact_name || 'docker-e2e-package' }}
|
||||
OPENCLAW_DOCKER_E2E_SELECTED_SHA: ${{ needs.validate_selected_ref.outputs.selected_sha }}
|
||||
OPENCLAW_CURRENT_PACKAGE_TGZ: .artifacts/docker-e2e-package/openclaw-current.tgz
|
||||
OPENCLAW_SKIP_DOCKER_BUILD: "1"
|
||||
steps:
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -687,7 +687,7 @@ The live-model Docker runners also bind-mount only the needed CLI auth homes (or
|
||||
Set `OPENCLAW_PLUGINS_E2E_CLAWHUB=0` to skip the live ClawHub block, or override the default package with `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC` and `OPENCLAW_PLUGINS_E2E_CLAWHUB_ID`.
|
||||
- Plugin update unchanged smoke: `pnpm test:docker:plugin-update` (script: `scripts/e2e/plugin-update-unchanged-docker.sh`)
|
||||
- Config reload metadata smoke: `pnpm test:docker:config-reload` (script: `scripts/e2e/config-reload-source-docker.sh`)
|
||||
- Bundled plugin runtime deps: `pnpm test:docker:bundled-channel-deps` builds a small Docker runner image by default, builds and packs OpenClaw once on the host, then mounts that tarball into each Linux install scenario. Reuse the image with `OPENCLAW_SKIP_DOCKER_BUILD=1`, skip the host rebuild after a fresh local build with `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0`, or point at an existing tarball with `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz`. The full Docker aggregate pre-packs this tarball once, then shards bundled channel checks into independent lanes, including separate update lanes for Telegram, Discord, Slack, Feishu, memory-lancedb, and ACPX. Use `OPENCLAW_BUNDLED_CHANNELS=telegram,slack` to narrow the channel matrix when running the bundled lane directly, or `OPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx` to narrow the update scenario. The lane also verifies that `channels.<id>.enabled=false` and `plugins.entries.<id>.enabled=false` suppress doctor/runtime-dependency repair.
|
||||
- Bundled plugin runtime deps: `pnpm test:docker:bundled-channel-deps` builds a small Docker runner image by default, builds and packs OpenClaw once on the host, then mounts that tarball into each Linux install scenario. Reuse the image with `OPENCLAW_SKIP_DOCKER_BUILD=1`, skip the host rebuild after a fresh local build with `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0`, or point at an existing tarball with `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz`. The full Docker aggregate and release-path `plugins-integrations` chunk pre-pack this tarball once, then shard bundled channel checks into independent lanes, including separate update lanes for Telegram, Discord, Slack, Feishu, memory-lancedb, and ACPX. Use `OPENCLAW_BUNDLED_CHANNELS=telegram,slack` to narrow the channel matrix when running the bundled lane directly, or `OPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx` to narrow the update scenario. The lane also verifies that `channels.<id>.enabled=false` and `plugins.entries.<id>.enabled=false` suppress doctor/runtime-dependency repair.
|
||||
- Narrow bundled plugin runtime deps while iterating by disabling unrelated scenarios, for example:
|
||||
`OPENCLAW_BUNDLED_CHANNEL_SCENARIOS=0 OPENCLAW_BUNDLED_CHANNEL_UPDATE_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_ROOT_OWNED_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_SETUP_ENTRY_SCENARIO=0 pnpm test:docker:bundled-channel-deps`.
|
||||
|
||||
|
||||
@@ -321,6 +321,8 @@ Release Docker coverage includes:
|
||||
- release-path Docker chunks: `core`, `package-update`, and
|
||||
`plugins-integrations`
|
||||
- OpenWebUI coverage inside the `plugins-integrations` chunk when requested
|
||||
- split bundled-channel dependency lanes inside `plugins-integrations` instead
|
||||
of the serial all-in-one bundled-channel lane
|
||||
- live/E2E provider suites and Docker live model coverage when release checks
|
||||
include live suites
|
||||
|
||||
|
||||
@@ -946,15 +946,17 @@ if (installRecords[pluginId]) {
|
||||
throw new Error(`ClawHub install record still present after uninstall: ${pluginId}`);
|
||||
}
|
||||
|
||||
const configPath = path.join(process.env.HOME, ".openclaw", "openclaw.json");
|
||||
const config = fs.existsSync(configPath) ? JSON.parse(fs.readFileSync(configPath, "utf8")) : {};
|
||||
if (config.plugins?.entries?.[pluginId]) {
|
||||
const configAfterUninstallPath = path.join(process.env.HOME, ".openclaw", "openclaw.json");
|
||||
const configAfterUninstall = fs.existsSync(configAfterUninstallPath)
|
||||
? JSON.parse(fs.readFileSync(configAfterUninstallPath, "utf8"))
|
||||
: {};
|
||||
if (configAfterUninstall.plugins?.entries?.[pluginId]) {
|
||||
throw new Error(`ClawHub config entry still present after uninstall: ${pluginId}`);
|
||||
}
|
||||
if ((config.plugins?.allow || []).includes(pluginId)) {
|
||||
if ((configAfterUninstall.plugins?.allow || []).includes(pluginId)) {
|
||||
throw new Error(`ClawHub allowlist entry still present after uninstall: ${pluginId}`);
|
||||
}
|
||||
if ((config.plugins?.deny || []).includes(pluginId)) {
|
||||
if ((configAfterUninstall.plugins?.deny || []).includes(pluginId)) {
|
||||
throw new Error(`ClawHub denylist entry still present after uninstall: ${pluginId}`);
|
||||
}
|
||||
if (fs.existsSync(installPath)) {
|
||||
|
||||
@@ -388,11 +388,7 @@ const releasePathChunks = {
|
||||
weight: 6,
|
||||
}),
|
||||
npmLane("plugin-update", "OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:plugin-update"),
|
||||
npmLane(
|
||||
"bundled-channel-deps",
|
||||
"OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:bundled-channel-deps",
|
||||
{ resources: ["service"], weight: 3 },
|
||||
),
|
||||
...bundledScenarioLanes,
|
||||
serviceLane(
|
||||
"cron-mcp-cleanup",
|
||||
"OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:cron-mcp-cleanup",
|
||||
|
||||
@@ -333,6 +333,7 @@ async function writeRunSummary(logDir, summary) {
|
||||
process.env.GITHUB_SERVER_URL && process.env.GITHUB_REPOSITORY && process.env.GITHUB_RUN_ID
|
||||
? `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`
|
||||
: undefined,
|
||||
selectedSha: process.env.OPENCLAW_DOCKER_E2E_SELECTED_SHA || undefined,
|
||||
sha: process.env.GITHUB_SHA || undefined,
|
||||
workflow: process.env.GITHUB_WORKFLOW || undefined,
|
||||
},
|
||||
@@ -344,7 +345,13 @@ async function writeRunSummary(logDir, summary) {
|
||||
}
|
||||
|
||||
async function writeFailureIndex(logDir, summary) {
|
||||
const ref = summary.github?.sha || summary.github?.ref || process.env.GITHUB_SHA || "HEAD";
|
||||
const ref =
|
||||
summary.github?.selectedSha ||
|
||||
process.env.OPENCLAW_DOCKER_E2E_SELECTED_SHA ||
|
||||
summary.github?.sha ||
|
||||
summary.github?.ref ||
|
||||
process.env.GITHUB_SHA ||
|
||||
"HEAD";
|
||||
const failures = Array.isArray(summary.failures)
|
||||
? summary.failures
|
||||
: (summary.lanes ?? []).filter((lane) => lane.status !== 0);
|
||||
|
||||
@@ -42,6 +42,9 @@ describe("scripts/lib/docker-e2e-plan", () => {
|
||||
expect(plan.credentials).toEqual(["anthropic", "openai"]);
|
||||
expect(plan.lanes.map((lane) => lane.name)).toContain("install-e2e");
|
||||
expect(plan.lanes.map((lane) => lane.name)).toContain("mcp-channels");
|
||||
expect(plan.lanes.map((lane) => lane.name)).toContain("bundled-channel-feishu");
|
||||
expect(plan.lanes.map((lane) => lane.name)).toContain("bundled-channel-update-acpx");
|
||||
expect(plan.lanes.map((lane) => lane.name)).not.toContain("bundled-channel-deps");
|
||||
expect(plan.lanes.map((lane) => lane.name)).not.toContain("openwebui");
|
||||
});
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ describe("package artifact reuse", () => {
|
||||
expect(workflow).toContain("package_artifact_run_id:");
|
||||
expect(workflow).toContain("docker_e2e_bare_image:");
|
||||
expect(workflow).toContain("docker_e2e_functional_image:");
|
||||
expect(workflow).toContain("OPENCLAW_DOCKER_E2E_SELECTED_SHA:");
|
||||
expect(workflow).toContain("Download current-run OpenClaw Docker E2E package");
|
||||
expect(workflow).toContain("Download previous-run OpenClaw Docker E2E package");
|
||||
expect(workflow).toContain("inputs.package_artifact_name != ''");
|
||||
|
||||
Reference in New Issue
Block a user