mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-26 04:15:48 -06:00
fix(update): defer legacy parent plugin repair
This commit is contained in:
@@ -787,10 +787,13 @@ async function installCandidate(params: {
|
||||
const existingNpmPackagePath = npmInstallSpec
|
||||
? resolveExistingCandidateNpmPackagePath({ candidate, npmDir })
|
||||
: null;
|
||||
const existingNpmPackageVersion = existingNpmPackagePath
|
||||
? await readNpmPackageVersion(existingNpmPackagePath)
|
||||
: undefined;
|
||||
if (
|
||||
existingNpmPackagePath &&
|
||||
existingNpmPackageVersion &&
|
||||
npmInstallSpec &&
|
||||
clawhubInstallSpec &&
|
||||
params.mode !== "update" &&
|
||||
isPostCoreConvergencePass(params.env)
|
||||
) {
|
||||
@@ -800,6 +803,7 @@ async function installCandidate(params: {
|
||||
npmInstallSpec,
|
||||
npmRecordSpec: npmSpecs?.recordSpec ?? npmInstallSpec,
|
||||
packagePath: existingNpmPackagePath,
|
||||
version: existingNpmPackageVersion,
|
||||
});
|
||||
}
|
||||
const shouldTryClawHub =
|
||||
@@ -965,12 +969,12 @@ async function adoptExistingNpmPackage(params: {
|
||||
npmInstallSpec: string;
|
||||
npmRecordSpec: string;
|
||||
packagePath: string;
|
||||
version: string;
|
||||
}): Promise<{
|
||||
records: Record<string, PluginInstallRecord>;
|
||||
changes: string[];
|
||||
warnings: string[];
|
||||
}> {
|
||||
const version = await readNpmPackageVersion(params.packagePath);
|
||||
const npmName = parseRegistryNpmSpec(params.npmInstallSpec)?.name;
|
||||
return {
|
||||
records: {
|
||||
@@ -980,9 +984,10 @@ async function adoptExistingNpmPackage(params: {
|
||||
spec: params.npmRecordSpec,
|
||||
installPath: params.packagePath,
|
||||
installedAt: new Date().toISOString(),
|
||||
...(version ? { version, resolvedVersion: version } : {}),
|
||||
version: params.version,
|
||||
resolvedVersion: params.version,
|
||||
...(npmName ? { resolvedName: npmName } : {}),
|
||||
...(npmName && version ? { resolvedSpec: `${npmName}@${version}` } : {}),
|
||||
...(npmName ? { resolvedSpec: `${npmName}@${params.version}` } : {}),
|
||||
},
|
||||
},
|
||||
changes: [
|
||||
|
||||
@@ -428,7 +428,7 @@ describe("configured plugin install release step", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("repairs package-manager plugins for writable legacy parents without explicit deferral", async () => {
|
||||
it("defers package-manager plugin release completion for writable legacy parents", async () => {
|
||||
mocks.repairMissingPluginInstallsForIds.mockResolvedValue({
|
||||
changes: ['Installed missing configured plugin "discord".'],
|
||||
warnings: [],
|
||||
@@ -459,8 +459,8 @@ describe("configured plugin install release step", () => {
|
||||
expect(result).toEqual({
|
||||
changes: ['Installed missing configured plugin "discord".'],
|
||||
warnings: [],
|
||||
completed: true,
|
||||
touchedConfig: true,
|
||||
completed: false,
|
||||
touchedConfig: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ describe("update-phase env helpers", () => {
|
||||
expect(isPostCoreConvergencePass(env)).toBe(true);
|
||||
});
|
||||
|
||||
it("defers configured plugin repair only for explicit update handoffs", () => {
|
||||
it("defers configured plugin repair for post-core handoffs", () => {
|
||||
expect(
|
||||
shouldDeferConfiguredPluginInstallRepair({
|
||||
[UPDATE_IN_PROGRESS_ENV]: "1",
|
||||
@@ -53,7 +53,7 @@ describe("update-phase env helpers", () => {
|
||||
[UPDATE_IN_PROGRESS_ENV]: "1",
|
||||
[UPDATE_PARENT_SUPPORTS_DOCTOR_CONFIG_WRITE_ENV]: "1",
|
||||
}),
|
||||
).toBe(false);
|
||||
).toBe(true);
|
||||
expect(
|
||||
shouldDeferConfiguredPluginInstallRepair({
|
||||
[UPDATE_IN_PROGRESS_ENV]: "1",
|
||||
@@ -80,7 +80,7 @@ describe("update-phase env helpers", () => {
|
||||
[UPDATE_IN_PROGRESS_ENV]: "1",
|
||||
[UPDATE_PARENT_SUPPORTS_DOCTOR_CONFIG_WRITE_ENV]: "1",
|
||||
}),
|
||||
).toBe(true);
|
||||
).toBe(false);
|
||||
expect(
|
||||
isLegacyPackageUpdateDoctorPass({
|
||||
[UPDATE_IN_PROGRESS_ENV]: "1",
|
||||
|
||||
@@ -40,14 +40,15 @@ export function isUpdatePackageSwapInProgress(env: NodeJS.ProcessEnv): boolean {
|
||||
/**
|
||||
* True iff configured plugin install repair should be deferred because the
|
||||
* updater guarantees a later post-core convergence pass. Older shipped
|
||||
* parents may set only the writable-config marker; they still resume after
|
||||
* the candidate doctor exits, so the candidate must repair payloads before
|
||||
* control returns to that stale process.
|
||||
* parents may set only the writable-config marker. Those parents still have a
|
||||
* post-core handoff, but their in-memory install records are stale after the
|
||||
* candidate doctor exits, so defer payload repair to the updated child process.
|
||||
*/
|
||||
export function shouldDeferConfiguredPluginInstallRepair(env: NodeJS.ProcessEnv): boolean {
|
||||
return (
|
||||
isUpdatePackageSwapInProgress(env) &&
|
||||
isTruthyEnvValue(env[UPDATE_DEFER_CONFIGURED_PLUGIN_INSTALL_REPAIR_ENV])
|
||||
(isTruthyEnvValue(env[UPDATE_DEFER_CONFIGURED_PLUGIN_INSTALL_REPAIR_ENV]) ||
|
||||
isTruthyEnvValue(env[UPDATE_PARENT_SUPPORTS_DOCTOR_CONFIG_WRITE_ENV]))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -67,9 +68,9 @@ export function isLegacyParentWritableUpdateDoctorPass(env: NodeJS.ProcessEnv):
|
||||
}
|
||||
|
||||
/**
|
||||
* True iff this newer doctor is running under an older updater. Legacy
|
||||
* updaters set only `OPENCLAW_UPDATE_IN_PROGRESS`; they do not opt into the
|
||||
* post-core convergence pass, so configured plugin repair must happen now.
|
||||
* True iff this newer doctor is running under an older updater that does not
|
||||
* advertise any post-core handoff marker. Those parents set only
|
||||
* `OPENCLAW_UPDATE_IN_PROGRESS`, so configured plugin repair must happen now.
|
||||
*/
|
||||
export function isLegacyPackageUpdateDoctorPass(env: NodeJS.ProcessEnv): boolean {
|
||||
return isUpdatePackageSwapInProgress(env) && !shouldDeferConfiguredPluginInstallRepair(env);
|
||||
|
||||
Reference in New Issue
Block a user