fix(update): preserve upstream after pinned dev updates (#121328)

This commit is contained in:
Peter Steinberger
2026-08-09 18:50:12 -07:00
committed by GitHub
parent 2f97e8c9eb
commit f4e62523af
20 changed files with 938 additions and 154 deletions
@@ -1,3 +1,4 @@
import type { DevUpdateTarget } from "../../infra/update-dev-target.js";
import type { ResolvedGlobalInstallTarget } from "../../infra/update-global.js";
import type { UpdateRunResult } from "../../infra/update-runner.js";
import { defaultRuntime } from "../../runtime.js";
@@ -53,7 +54,7 @@ export async function executeMutableUpdate(params: {
showProgress: boolean;
opts: UpdateCommandOptions;
shouldRestart: boolean;
devTargetRef?: string;
devTarget?: DevUpdateTarget;
packageInstallSpec: string | null;
packageInstallEnv?: NodeJS.ProcessEnv;
packageInstallTarget?: ResolvedGlobalInstallTarget;
@@ -223,7 +224,7 @@ export async function executeMutableUpdate(params: {
showProgress: params.showProgress,
opts: params.opts,
stop: params.stop,
devTargetRef: params.devTargetRef,
devTarget: params.devTarget,
beforeGitMutation:
params.updateInstallKind === "git"
? createBeforeGitMutation({
+3 -2
View File
@@ -1,4 +1,5 @@
import type { UpdateChannel } from "../../infra/update-channels.js";
import type { DevUpdateTarget } from "../../infra/update-dev-target.js";
import {
createGlobalInstallEnv,
globalInstallArgs,
@@ -127,7 +128,7 @@ export async function runGitUpdate(params: {
showProgress: boolean;
opts: UpdateCommandOptions;
stop: () => void;
devTargetRef?: string;
devTarget?: DevUpdateTarget;
beforeGitMutation?: BeforeGitMutation;
allowGatewayServiceRepair: boolean;
allowGatewayActivation: boolean;
@@ -167,7 +168,7 @@ export async function runGitUpdate(params: {
progress: params.progress,
channel: params.channel,
tag: params.tag,
devTargetRef: params.devTargetRef,
devTarget: params.devTarget,
deferConfiguredPluginInstallRepair: true,
allowGatewayServiceRepair: params.allowGatewayServiceRepair,
allowGatewayActivation: params.allowGatewayActivation,
+33 -3
View File
@@ -27,6 +27,11 @@ import {
resolveNpmChannelTag,
} from "../../infra/update-check.js";
import { readControlPlaneUpdateSentinelMeta } from "../../infra/update-control-plane-sentinel.js";
import {
parseDevUpdateTargetEnv,
type DevUpdateTarget,
UPDATE_DEV_TARGET_REF_ENV,
} from "../../infra/update-dev-target.js";
import {
canResolveRegistryVersionForPackageTarget,
createGlobalInstallEnv,
@@ -85,6 +90,18 @@ export { updateFinalizeCommand } from "./update-command-post-core.js";
const CLI_NAME = resolveCliName();
const DEFAULT_UPDATE_STEP_TIMEOUT_MS = 30 * 60_000;
function readDevUpdateTargetOrExit(): { ok: true; target?: DevUpdateTarget } | { ok: false } {
const parsed = parseDevUpdateTargetEnv(process.env);
if (parsed.status === "invalid") {
defaultRuntime.error(
`Invalid internal ${UPDATE_DEV_TARGET_REF_ENV} contract; expected a plain Git ref or a supported tracked-target encoding.`,
);
defaultRuntime.exit(1);
return { ok: false };
}
return parsed.status === "valid" ? { ok: true, target: parsed.target } : { ok: true };
}
async function withUpdateInProgressEnv<T>(run: () => Promise<T>): Promise<T> {
const previousUpdateInProgress = process.env.OPENCLAW_UPDATE_IN_PROGRESS;
process.env.OPENCLAW_UPDATE_IN_PROGRESS = "1";
@@ -134,6 +151,14 @@ async function updateCommandInternal(
defaultRuntime.exit(1);
return;
}
let devTarget: DevUpdateTarget | undefined;
if (requestedChannel === "dev") {
const resolvedDevTarget = readDevUpdateTargetOrExit();
if (!resolvedDevTarget.ok) {
return;
}
devTarget = resolvedDevTarget.target;
}
if (!postCoreUpdateResume && opts.dryRun !== true && isGatewayExternallySupervised()) {
defaultRuntime.error(formatExternalSupervisorUpdateRequired());
@@ -246,8 +271,13 @@ async function updateCommandInternal(
currentVersion: VERSION,
installKind: updateInstallKind,
}).channel);
const devTargetRef =
channel === "dev" ? process.env.OPENCLAW_UPDATE_DEV_TARGET_REF?.trim() || undefined : undefined;
if (channel === "dev" && requestedChannel !== "dev") {
const resolvedDevTarget = readDevUpdateTargetOrExit();
if (!resolvedDevTarget.ok) {
return;
}
devTarget = resolvedDevTarget.target;
}
const explicitTag = normalizeTag(opts.tag);
if (channel === "extended-stable" && explicitTag) {
@@ -579,7 +609,7 @@ async function updateCommandInternal(
showProgress,
opts,
shouldRestart,
devTargetRef,
devTarget,
packageInstallSpec,
packageInstallEnv,
packageInstallTarget,