fix(cli): prevent automatic updates from switching to less stable channels (#26132)

This commit is contained in:
Adib234
2026-04-28 14:03:08 -04:00
committed by GitHub
parent 59b2dea0e5
commit f8603e990b
5 changed files with 173 additions and 12 deletions
@@ -334,7 +334,8 @@ describe('handleAutoUpdate', () => {
...mockUpdateInfo,
update: {
...mockUpdateInfo.update,
latest: '2.0.0-nightly',
current: '1.0.0-nightly.0',
latest: '2.0.0-nightly.1',
},
};
mockGetInstallationInfo.mockReturnValue({
@@ -356,6 +357,26 @@ describe('handleAutoUpdate', () => {
);
});
it('should NOT update if target is less stable than current (defense-in-depth)', async () => {
mockUpdateInfo = {
...mockUpdateInfo,
update: {
...mockUpdateInfo.update,
current: '1.0.0',
latest: '1.1.0-nightly.1',
},
};
mockGetInstallationInfo.mockReturnValue({
updateCommand: 'npm i -g @google/gemini-cli@latest',
isGlobal: false,
packageManager: PackageManager.NPM,
});
handleAutoUpdate(mockUpdateInfo, mockSettings, '/root', mockSpawn);
expect(mockSpawn).not.toHaveBeenCalled();
});
it('should emit "update-success" when the update process succeeds', async () => {
await new Promise<void>((resolve) => {
mockGetInstallationInfo.mockReturnValue({
+24 -1
View File
@@ -11,7 +11,11 @@ import { updateEventEmitter } from './updateEventEmitter.js';
import { MessageType, type HistoryItem } from '../ui/types.js';
import { spawnWrapper } from './spawnWrapper.js';
import type { spawn } from 'node:child_process';
import { debugLogger } from '@google/gemini-cli-core';
import {
debugLogger,
getChannelFromVersion,
RELEASE_CHANNEL_STABILITY,
} from '@google/gemini-cli-core';
let _updateInProgress = false;
@@ -122,6 +126,25 @@ export function handleAutoUpdate(
return;
}
const currentVersion = info.update.current;
if (!currentVersion) {
debugLogger.warn(
'Update check: current version is missing. Skipping automatic update for safety.',
);
return;
}
const currentChannel = getChannelFromVersion(currentVersion);
const targetChannel = getChannelFromVersion(info.update.latest);
// Defense-in-depth: prevent updates to a less stable channel
if (
RELEASE_CHANNEL_STABILITY[targetChannel] <
RELEASE_CHANNEL_STABILITY[currentChannel]
) {
return;
}
const isNightly = info.update.latest.includes('nightly');
const updateCommand = installationInfo.updateCommand.replace(