mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-26 13:42:16 +00:00
fix(update): complete channel switch follow-up work
This commit is contained in:
parent
cd8187d7ce
commit
6a00be5f90
9 changed files with 270 additions and 106 deletions
|
|
@ -430,6 +430,11 @@ jobs:
|
|||
command: pnpm test:docker:doctor-switch
|
||||
timeout_minutes: 60
|
||||
release_path: true
|
||||
- suite_id: docker-update-channel-switch
|
||||
label: Update Channel Switch Docker E2E
|
||||
command: pnpm test:docker:update-channel-switch
|
||||
timeout_minutes: 60
|
||||
release_path: true
|
||||
- suite_id: docker-session-runtime-context
|
||||
label: Session Runtime Context Docker E2E
|
||||
command: pnpm test:docker:session-runtime-context
|
||||
|
|
|
|||
|
|
@ -607,7 +607,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`, then reuses it for the live Docker lanes. It also builds one shared `scripts/e2e/Dockerfile` image via `test:docker:e2e-build` and reuses it for the E2E container smoke runners that exercise the built app. 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. Defaults are 10 slots, `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=6`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=8`, 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.
|
||||
- Container smoke runners: `test:docker:openwebui`, `test:docker:onboard`, `test:docker:npm-onboard-channel-agent`, `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.
|
||||
- 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.
|
||||
|
||||
The live-model Docker runners also bind-mount only the needed CLI auth homes (or all supported ones when the run is not narrowed), then copy them into the container home before the run so external-CLI OAuth can refresh tokens without mutating the host auth store:
|
||||
|
||||
|
|
@ -619,6 +619,7 @@ The live-model Docker runners also bind-mount only the needed CLI auth homes (or
|
|||
- Open WebUI live smoke: `pnpm test:docker:openwebui` (script: `scripts/e2e/openwebui-docker.sh`)
|
||||
- Onboarding wizard (TTY, full scaffolding): `pnpm test:docker:onboard` (script: `scripts/e2e/onboard-docker.sh`)
|
||||
- Npm tarball onboarding/channel/agent smoke: `pnpm test:docker:npm-onboard-channel-agent` installs the packed OpenClaw tarball globally in Docker, configures OpenAI via env-ref onboarding plus Telegram by default, verifies doctor repairs activated plugin runtime deps, and runs one mocked OpenAI agent turn. Reuse a prebuilt tarball with `OPENCLAW_NPM_ONBOARD_PACKAGE_TGZ=/path/to/openclaw-*.tgz`, skip the host rebuild with `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0`, or switch channel with `OPENCLAW_NPM_ONBOARD_CHANNEL=discord`.
|
||||
- Update channel switch smoke: `pnpm test:docker:update-channel-switch` installs the packed OpenClaw tarball globally in Docker, switches from package `stable` to git `dev`, verifies the persisted channel and plugin post-update work, then switches back to package `stable` and checks update status.
|
||||
- Session runtime context smoke: `pnpm test:docker:session-runtime-context` verifies hidden runtime context transcript persistence plus doctor repair of affected duplicated prompt-rewrite branches.
|
||||
- Bun global install smoke: `bash scripts/e2e/bun-global-install-smoke.sh` packs the current tree, installs it with `bun install -g` in an isolated home, and verifies `openclaw infer image providers --json` returns bundled image providers instead of hanging. Reuse a prebuilt tarball with `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz`, skip the host build with `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0`, or copy `dist/` from a built Docker image with `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local`.
|
||||
- Installer Docker smoke: `bash scripts/test-install-sh-docker.sh` shares one npm cache across its root, update, and direct-npm containers. Update smoke defaults to npm `latest` as the stable baseline before upgrading to the candidate tarball. Non-root installer checks keep an isolated npm cache so root-owned cache entries do not mask user-local install behavior. Set `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache` to reuse the root/update/direct-npm cache across local reruns.
|
||||
|
|
|
|||
|
|
@ -1542,6 +1542,7 @@
|
|||
"test:docker:plugins": "bash scripts/e2e/plugins-docker.sh",
|
||||
"test:docker:qr": "bash scripts/e2e/qr-import-docker.sh",
|
||||
"test:docker:session-runtime-context": "bash scripts/e2e/session-runtime-context-docker.sh",
|
||||
"test:docker:update-channel-switch": "bash scripts/e2e/update-channel-switch-docker.sh",
|
||||
"test:e2e": "node scripts/run-vitest.mjs run --config test/vitest/vitest.e2e.config.ts",
|
||||
"test:e2e:openshell": "OPENCLAW_E2E_OPENSHELL=1 node scripts/run-vitest.mjs run --config test/vitest/vitest.e2e.config.ts extensions/openshell/src/backend.e2e.test.ts",
|
||||
"test:extension": "node scripts/test-extension.mjs",
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ RUN --mount=type=cache,id=openclaw-pnpm-store,target=/home/appuser/.local/share/
|
|||
|
||||
FROM deps AS build
|
||||
|
||||
COPY --chown=appuser:appuser tsconfig.json tsconfig.plugin-sdk.dts.json tsdown.config.ts vitest.config.ts openclaw.mjs ./
|
||||
COPY --chown=appuser:appuser .oxlintrc.json tsconfig.json tsconfig.plugin-sdk.dts.json tsconfig.oxlint*.json tsdown.config.ts vitest.config.ts openclaw.mjs ./
|
||||
COPY --chown=appuser:appuser src ./src
|
||||
COPY --chown=appuser:appuser test ./test
|
||||
COPY --chown=appuser:appuser scripts ./scripts
|
||||
|
|
|
|||
165
scripts/e2e/update-channel-switch-docker.sh
Executable file
165
scripts/e2e/update-channel-switch-docker.sh
Executable file
|
|
@ -0,0 +1,165 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
source "$ROOT_DIR/scripts/lib/docker-e2e-image.sh"
|
||||
|
||||
IMAGE_NAME="$(docker_e2e_resolve_image "openclaw-update-channel-switch-e2e" OPENCLAW_UPDATE_CHANNEL_SWITCH_E2E_IMAGE)"
|
||||
SKIP_BUILD="${OPENCLAW_UPDATE_CHANNEL_SWITCH_E2E_SKIP_BUILD:-0}"
|
||||
|
||||
docker_e2e_build_or_reuse "$IMAGE_NAME" update-channel-switch "$ROOT_DIR/scripts/e2e/Dockerfile" "$ROOT_DIR" "" "$SKIP_BUILD"
|
||||
|
||||
echo "Running update channel switch E2E..."
|
||||
docker run --rm \
|
||||
-e COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \
|
||||
-e OPENCLAW_SKIP_CHANNELS=1 \
|
||||
-e OPENCLAW_SKIP_PROVIDERS=1 \
|
||||
"$IMAGE_NAME" \
|
||||
bash -lc 'set -euo pipefail
|
||||
|
||||
export npm_config_loglevel=error
|
||||
export npm_config_fund=false
|
||||
export npm_config_audit=false
|
||||
export npm_config_prefix=/tmp/npm-prefix
|
||||
export NPM_CONFIG_PREFIX=/tmp/npm-prefix
|
||||
export PNPM_HOME=/tmp/pnpm-home
|
||||
export PATH="/tmp/npm-prefix/bin:/tmp/pnpm-home:$PATH"
|
||||
export CI=true
|
||||
export OPENCLAW_DISABLE_BUNDLED_PLUGINS=1
|
||||
export OPENCLAW_NO_ONBOARD=1
|
||||
export OPENCLAW_NO_PROMPT=1
|
||||
|
||||
cat > /app/.gitignore <<'"'"'GITIGNORE'"'"'
|
||||
node_modules
|
||||
**/node_modules/
|
||||
dist
|
||||
dist-runtime
|
||||
.turbo
|
||||
coverage
|
||||
GITIGNORE
|
||||
|
||||
node --import tsx scripts/write-package-dist-inventory.ts
|
||||
|
||||
git config --global user.email "docker-e2e@openclaw.local"
|
||||
git config --global user.name "OpenClaw Docker E2E"
|
||||
git config --global gc.auto 0
|
||||
git -C /app init -q
|
||||
git -C /app config gc.auto 0
|
||||
git -C /app add -A
|
||||
git -C /app commit -qm "test fixture"
|
||||
fixture_sha="$(git -C /app rev-parse HEAD)"
|
||||
|
||||
pkg_tgz="$(npm pack --ignore-scripts --silent --pack-destination /tmp /app | tail -n 1 | tr -d "\r")"
|
||||
pkg_tgz_path="/tmp/$pkg_tgz"
|
||||
if [ ! -f "$pkg_tgz_path" ]; then
|
||||
echo "npm pack failed (expected $pkg_tgz_path)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
npm install -g --prefix /tmp/npm-prefix --omit=optional "$pkg_tgz_path"
|
||||
|
||||
home_dir="$(mktemp -d /tmp/openclaw-update-channel-switch-home.XXXXXX)"
|
||||
export HOME="$home_dir"
|
||||
mkdir -p "$HOME/.openclaw"
|
||||
cat > "$HOME/.openclaw/openclaw.json" <<'"'"'JSON'"'"'
|
||||
{
|
||||
"update": {
|
||||
"channel": "stable"
|
||||
},
|
||||
"plugins": {}
|
||||
}
|
||||
JSON
|
||||
|
||||
export OPENCLAW_GIT_DIR=/app
|
||||
export OPENCLAW_UPDATE_DEV_TARGET_REF="$fixture_sha"
|
||||
|
||||
echo "==> package -> git dev channel"
|
||||
set +e
|
||||
dev_json="$(openclaw update --channel dev --yes --json --no-restart)"
|
||||
dev_status=$?
|
||||
set -e
|
||||
printf "%s\n" "$dev_json"
|
||||
if [ "$dev_status" -ne 0 ]; then
|
||||
exit "$dev_status"
|
||||
fi
|
||||
DEV_JSON="$dev_json" node - <<'"'"'NODE'"'"'
|
||||
const payload = JSON.parse(process.env.DEV_JSON);
|
||||
if (payload.status !== "ok") {
|
||||
throw new Error(`expected dev update status ok, got ${payload.status}`);
|
||||
}
|
||||
if (payload.mode !== "git") {
|
||||
throw new Error(`expected dev update mode git, got ${payload.mode}`);
|
||||
}
|
||||
if (payload.postUpdate?.plugins?.status !== "ok") {
|
||||
throw new Error(`expected plugin post-update ok, got ${JSON.stringify(payload.postUpdate?.plugins)}`);
|
||||
}
|
||||
NODE
|
||||
|
||||
node - <<'"'"'NODE'"'"'
|
||||
const fs = require("node:fs");
|
||||
const path = require("node:path");
|
||||
const configPath = path.join(process.env.HOME, ".openclaw", "openclaw.json");
|
||||
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
||||
if (config.update?.channel !== "dev") {
|
||||
throw new Error(`expected persisted update.channel dev, got ${JSON.stringify(config.update?.channel)}`);
|
||||
}
|
||||
NODE
|
||||
|
||||
status_json="$(openclaw update status --json)"
|
||||
printf "%s\n" "$status_json"
|
||||
STATUS_JSON="$status_json" node - <<'"'"'NODE'"'"'
|
||||
const payload = JSON.parse(process.env.STATUS_JSON);
|
||||
if (payload.update?.installKind !== "git") {
|
||||
throw new Error(`expected git install after dev switch, got ${payload.update?.installKind}`);
|
||||
}
|
||||
if (payload.channel?.value !== "dev" || payload.channel?.source !== "config") {
|
||||
throw new Error(`expected dev config channel after dev switch, got ${JSON.stringify(payload.channel)}`);
|
||||
}
|
||||
NODE
|
||||
|
||||
echo "==> git -> package stable channel"
|
||||
set +e
|
||||
stable_json="$(openclaw update --channel stable --tag "$pkg_tgz_path" --yes --json --no-restart)"
|
||||
stable_status=$?
|
||||
set -e
|
||||
printf "%s\n" "$stable_json"
|
||||
if [ "$stable_status" -ne 0 ]; then
|
||||
exit "$stable_status"
|
||||
fi
|
||||
STABLE_JSON="$stable_json" node - <<'"'"'NODE'"'"'
|
||||
const payload = JSON.parse(process.env.STABLE_JSON);
|
||||
if (payload.status !== "ok") {
|
||||
throw new Error(`expected stable update status ok, got ${payload.status}`);
|
||||
}
|
||||
if (!["npm", "pnpm", "bun"].includes(payload.mode)) {
|
||||
throw new Error(`expected package-manager mode after stable switch, got ${payload.mode}`);
|
||||
}
|
||||
if (payload.postUpdate?.plugins?.status !== "ok") {
|
||||
throw new Error(`expected plugin post-update ok, got ${JSON.stringify(payload.postUpdate?.plugins)}`);
|
||||
}
|
||||
NODE
|
||||
|
||||
node - <<'"'"'NODE'"'"'
|
||||
const fs = require("node:fs");
|
||||
const path = require("node:path");
|
||||
const configPath = path.join(process.env.HOME, ".openclaw", "openclaw.json");
|
||||
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
||||
if (config.update?.channel !== "stable") {
|
||||
throw new Error(`expected persisted update.channel stable, got ${JSON.stringify(config.update?.channel)}`);
|
||||
}
|
||||
NODE
|
||||
|
||||
status_json="$(openclaw update status --json)"
|
||||
printf "%s\n" "$status_json"
|
||||
STATUS_JSON="$status_json" node - <<'"'"'NODE'"'"'
|
||||
const payload = JSON.parse(process.env.STATUS_JSON);
|
||||
if (payload.update?.installKind !== "package") {
|
||||
throw new Error(`expected package install after stable switch, got ${payload.update?.installKind}`);
|
||||
}
|
||||
if (payload.channel?.value !== "stable" || payload.channel?.source !== "config") {
|
||||
throw new Error(`expected stable config channel after stable switch, got ${JSON.stringify(payload.channel)}`);
|
||||
}
|
||||
NODE
|
||||
|
||||
echo "OK"
|
||||
'
|
||||
|
|
@ -246,6 +246,14 @@ const lanes = [
|
|||
npmLane("doctor-switch", "OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:doctor-switch", {
|
||||
weight: 3,
|
||||
}),
|
||||
npmLane(
|
||||
"update-channel-switch",
|
||||
"OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:update-channel-switch",
|
||||
{
|
||||
timeoutMs: 30 * 60 * 1000,
|
||||
weight: 3,
|
||||
},
|
||||
),
|
||||
lane("plugins", "OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:plugins", {
|
||||
resources: ["npm", "service"],
|
||||
weight: 6,
|
||||
|
|
|
|||
|
|
@ -1693,41 +1693,68 @@ describe("update-cli", () => {
|
|||
expect(syncConfig?.plugins?.entries).toBeUndefined();
|
||||
});
|
||||
|
||||
it("skips plugin sync in the old process after switching from package to git", async () => {
|
||||
it("persists channel and runs post-update work after switching from package to git", async () => {
|
||||
const tempDir = createCaseDir("openclaw-update");
|
||||
const gitRoot = path.join(tempDir, "..", "openclaw");
|
||||
const completionCacheSpy = vi
|
||||
.spyOn(updateCliShared, "tryWriteCompletionCache")
|
||||
.mockResolvedValue(undefined);
|
||||
mockPackageInstallStatus(tempDir);
|
||||
vi.mocked(readConfigFileSnapshot).mockResolvedValue({
|
||||
...baseSnapshot,
|
||||
parsed: { update: { channel: "stable" } },
|
||||
resolved: { update: { channel: "stable" } } as OpenClawConfig,
|
||||
sourceConfig: { update: { channel: "stable" } } as OpenClawConfig,
|
||||
runtimeConfig: { update: { channel: "stable" } } as OpenClawConfig,
|
||||
config: { update: { channel: "stable" } } as OpenClawConfig,
|
||||
});
|
||||
vi.mocked(runGatewayUpdate).mockResolvedValue(
|
||||
makeOkUpdateResult({
|
||||
mode: "git",
|
||||
root: path.join(tempDir, "..", "openclaw"),
|
||||
root: gitRoot,
|
||||
after: { version: "2026.4.10" },
|
||||
}),
|
||||
);
|
||||
serviceLoaded.mockResolvedValue(true);
|
||||
syncPluginsForUpdateChannel.mockRejectedValue(
|
||||
new Error("Config validation failed: old host version"),
|
||||
syncPluginsForUpdateChannel.mockImplementation(async ({ config }) => ({
|
||||
changed: false,
|
||||
config,
|
||||
summary: {
|
||||
switchedToBundled: [],
|
||||
switchedToNpm: [],
|
||||
warnings: [],
|
||||
errors: [],
|
||||
},
|
||||
}));
|
||||
updateNpmInstalledPlugins.mockImplementation(async ({ config }) => ({
|
||||
changed: false,
|
||||
config,
|
||||
outcomes: [],
|
||||
}));
|
||||
|
||||
await updateCommand({ channel: "dev", yes: true, restart: false });
|
||||
|
||||
const persistedConfig = vi.mocked(replaceConfigFile).mock.calls[0]?.[0]?.nextConfig;
|
||||
expect(persistedConfig?.update?.channel).toBe("dev");
|
||||
expect(syncPluginsForUpdateChannel).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
channel: "dev",
|
||||
config: expect.objectContaining({
|
||||
update: expect.objectContaining({ channel: "dev" }),
|
||||
}),
|
||||
workspaceDir: gitRoot,
|
||||
}),
|
||||
);
|
||||
|
||||
await updateCommand({ channel: "dev", yes: true });
|
||||
|
||||
expect(syncPluginsForUpdateChannel).not.toHaveBeenCalled();
|
||||
expect(replaceConfigFile).not.toHaveBeenCalled();
|
||||
expect(completionCacheSpy).not.toHaveBeenCalled();
|
||||
expect(updateNpmInstalledPlugins).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
config: expect.objectContaining({
|
||||
update: expect.objectContaining({ channel: "dev" }),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expect(completionCacheSpy).toHaveBeenCalledWith(gitRoot, false);
|
||||
expect(runRestartScript).not.toHaveBeenCalled();
|
||||
expect(runDaemonRestart).not.toHaveBeenCalled();
|
||||
expect(defaultRuntime.exit).toHaveBeenCalledWith(0);
|
||||
expect(defaultRuntime.exit).not.toHaveBeenCalledWith(1);
|
||||
expect(
|
||||
vi
|
||||
.mocked(defaultRuntime.log)
|
||||
.mock.calls.map((call) => String(call[0]))
|
||||
.join("\n"),
|
||||
).toContain(
|
||||
"Switched from a package install to a git checkout. Skipping remaining post-update work in the old CLI process; rerun follow-up commands from the new git install if needed.",
|
||||
);
|
||||
});
|
||||
it("explains why git updates cannot run with edited files", async () => {
|
||||
vi.mocked(defaultRuntime.log).mockClear();
|
||||
|
|
|
|||
|
|
@ -1339,54 +1339,30 @@ export async function updateCommand(opts: UpdateCommandOptions): Promise<void> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (switchToGit && result.status === "ok" && result.mode === "git") {
|
||||
if (!opts.json) {
|
||||
defaultRuntime.log(
|
||||
theme.muted(
|
||||
"Switched from a package install to a git checkout. Skipping remaining post-update work in the old CLI process; rerun follow-up commands from the new git install if needed.",
|
||||
),
|
||||
);
|
||||
} else {
|
||||
defaultRuntime.writeJson(result);
|
||||
}
|
||||
defaultRuntime.exit(0);
|
||||
return;
|
||||
}
|
||||
|
||||
let postUpdateConfigSnapshot = configSnapshot;
|
||||
if (requestedChannel && configSnapshot.valid && requestedChannel !== storedChannel) {
|
||||
if (switchToGit) {
|
||||
if (!opts.json) {
|
||||
defaultRuntime.log(
|
||||
theme.muted(
|
||||
`Skipped persisting update.channel=${requestedChannel} in the pre-update CLI process after switching to a git install.`,
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const next = {
|
||||
...configSnapshot.sourceConfig,
|
||||
update: {
|
||||
...configSnapshot.sourceConfig.update,
|
||||
channel: requestedChannel,
|
||||
},
|
||||
};
|
||||
await replaceConfigFile({
|
||||
nextConfig: next,
|
||||
baseHash: configSnapshot.hash,
|
||||
});
|
||||
postUpdateConfigSnapshot = {
|
||||
...configSnapshot,
|
||||
hash: undefined,
|
||||
parsed: next,
|
||||
sourceConfig: asResolvedSourceConfig(next),
|
||||
resolved: asResolvedSourceConfig(next),
|
||||
runtimeConfig: asRuntimeConfig(next),
|
||||
config: asRuntimeConfig(next),
|
||||
};
|
||||
if (!opts.json) {
|
||||
defaultRuntime.log(theme.muted(`Update channel set to ${requestedChannel}.`));
|
||||
}
|
||||
const next = {
|
||||
...configSnapshot.sourceConfig,
|
||||
update: {
|
||||
...configSnapshot.sourceConfig.update,
|
||||
channel: requestedChannel,
|
||||
},
|
||||
};
|
||||
await replaceConfigFile({
|
||||
nextConfig: next,
|
||||
baseHash: configSnapshot.hash,
|
||||
});
|
||||
postUpdateConfigSnapshot = {
|
||||
...configSnapshot,
|
||||
hash: undefined,
|
||||
parsed: next,
|
||||
sourceConfig: asResolvedSourceConfig(next),
|
||||
resolved: asResolvedSourceConfig(next),
|
||||
runtimeConfig: asRuntimeConfig(next),
|
||||
config: asRuntimeConfig(next),
|
||||
};
|
||||
if (!opts.json) {
|
||||
defaultRuntime.log(theme.muted(`Update channel set to ${requestedChannel}.`));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1409,16 +1385,7 @@ export async function updateCommand(opts: UpdateCommandOptions): Promise<void> {
|
|||
postCorePluginUpdate = freshProcessResult.pluginUpdate;
|
||||
}
|
||||
|
||||
const deferOldProcessPostUpdateWork = switchToGit && result.mode === "git";
|
||||
if (deferOldProcessPostUpdateWork) {
|
||||
if (!opts.json) {
|
||||
defaultRuntime.log(
|
||||
theme.muted(
|
||||
"Skipped plugin update sync in the pre-update CLI process after switching to a git install.",
|
||||
),
|
||||
);
|
||||
}
|
||||
} else if (!pluginsUpdatedInFreshProcess) {
|
||||
if (!pluginsUpdatedInFreshProcess) {
|
||||
postCorePluginUpdate = await runPostCorePluginUpdate({
|
||||
root: postUpdateRoot,
|
||||
channel,
|
||||
|
|
@ -1468,34 +1435,24 @@ export async function updateCommand(opts: UpdateCommandOptions): Promise<void> {
|
|||
}
|
||||
}
|
||||
|
||||
if (deferOldProcessPostUpdateWork) {
|
||||
if (!opts.json) {
|
||||
defaultRuntime.log(
|
||||
theme.muted(
|
||||
"Skipped completion/restart follow-ups in the pre-update CLI process after switching to a git install.",
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
await tryWriteCompletionCache(postUpdateRoot, Boolean(opts.json));
|
||||
await tryInstallShellCompletion({
|
||||
jsonMode: Boolean(opts.json),
|
||||
skipPrompt: Boolean(opts.yes),
|
||||
});
|
||||
await tryWriteCompletionCache(postUpdateRoot, Boolean(opts.json));
|
||||
await tryInstallShellCompletion({
|
||||
jsonMode: Boolean(opts.json),
|
||||
skipPrompt: Boolean(opts.yes),
|
||||
});
|
||||
|
||||
const restartOk = await maybeRestartService({
|
||||
shouldRestart,
|
||||
result: resultWithPostUpdate,
|
||||
opts,
|
||||
refreshServiceEnv: refreshGatewayServiceEnv,
|
||||
gatewayPort,
|
||||
restartScriptPath,
|
||||
invocationCwd,
|
||||
});
|
||||
if (!restartOk) {
|
||||
defaultRuntime.exit(1);
|
||||
return;
|
||||
}
|
||||
const restartOk = await maybeRestartService({
|
||||
shouldRestart,
|
||||
result: resultWithPostUpdate,
|
||||
opts,
|
||||
refreshServiceEnv: refreshGatewayServiceEnv,
|
||||
gatewayPort,
|
||||
restartScriptPath,
|
||||
invocationCwd,
|
||||
});
|
||||
if (!restartOk) {
|
||||
defaultRuntime.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!opts.json) {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ describe("docker build cache layout", () => {
|
|||
/^COPY(?:\s+--chown=\S+)?\s+scripts\/postinstall-bundled-plugins\.mjs scripts\/preinstall-package-manager-warning\.mjs scripts\/npm-runner\.mjs scripts\/windows-cmd-helpers\.mjs \.\/scripts\/$/m,
|
||||
);
|
||||
expectPatternAfterInstall(
|
||||
/^COPY(?:\s+--chown=\S+)?\s+tsconfig\.json tsconfig\.plugin-sdk\.dts\.json tsdown\.config\.ts vitest\.config\.ts openclaw\.mjs \.\/$/m,
|
||||
/^COPY(?:\s+--chown=\S+)?\s+\.oxlintrc\.json tsconfig\.json tsconfig\.plugin-sdk\.dts\.json tsconfig\.oxlint\*\.json tsdown\.config\.ts vitest\.config\.ts openclaw\.mjs \.\/$/m,
|
||||
);
|
||||
expectPatternAfterInstall(/^COPY(?:\s+--chown=\S+)?\s+src \.\/src$/m);
|
||||
expectPatternAfterInstall(/^COPY(?:\s+--chown=\S+)?\s+test \.\/test$/m);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue