diff --git a/packages/amazonq/.changes/next-release/Deprecation-4577def6-0191-48db-bec3-480b226285b8.json b/packages/amazonq/.changes/next-release/Deprecation-4577def6-0191-48db-bec3-480b226285b8.json new file mode 100644 index 00000000000..78d58a5fbe6 --- /dev/null +++ b/packages/amazonq/.changes/next-release/Deprecation-4577def6-0191-48db-bec3-480b226285b8.json @@ -0,0 +1,4 @@ +{ + "type": "Deprecation", + "description": "The next release of this extension will require VS Code 1.83.0 or newer." +} diff --git a/packages/amazonq/.changes/next-release/Feature-b02fae9d-cb44-4625-af37-0b119c18ef63.json b/packages/amazonq/.changes/next-release/Feature-b02fae9d-cb44-4625-af37-0b119c18ef63.json new file mode 100644 index 00000000000..021933ef072 --- /dev/null +++ b/packages/amazonq/.changes/next-release/Feature-b02fae9d-cb44-4625-af37-0b119c18ef63.json @@ -0,0 +1,4 @@ +{ + "type": "Feature", + "description": "Show a one-time warning if new VS Code is required" +} diff --git a/packages/amazonq/package.json b/packages/amazonq/package.json index 7662b0ed006..d3c38c991a3 100644 --- a/packages/amazonq/package.json +++ b/packages/amazonq/package.json @@ -112,6 +112,10 @@ "type": "boolean", "default": false }, + "minIdeVersion": { + "type": "boolean", + "default": false + }, "ssoCacheError": { "type": "boolean", "default": false @@ -1046,6 +1050,6 @@ }, "engines": { "npm": "^10.1.0", - "vscode": "^1.83.0" + "vscode": "^1.68.0" } } diff --git a/packages/amazonq/src/extension.ts b/packages/amazonq/src/extension.ts index 8e16a262254..bc5c8ae34c8 100644 --- a/packages/amazonq/src/extension.ts +++ b/packages/amazonq/src/extension.ts @@ -40,6 +40,7 @@ import { placeholder, setContext, setupUninstallHandler, + maybeShowMinVscodeWarning, } from 'aws-core-vscode/shared' import { ExtStartUpSources, telemetry } from 'aws-core-vscode/telemetry' import { VSCODE_EXTENSION_ID } from 'aws-core-vscode/utils' @@ -98,6 +99,8 @@ export async function activateAmazonQCommon(context: vscode.ExtensionContext, is } } + void maybeShowMinVscodeWarning('1.83.0') + globals.machineId = await getMachineId() globals.awsContext = new DefaultAwsContext() globals.sdkClientBuilder = new DefaultAWSClientBuilder(globals.awsContext) diff --git a/packages/core/package.json b/packages/core/package.json index c549bbd9e53..74d0eb2011d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -5,7 +5,7 @@ "license": "Apache-2.0", "engines": { "npm": "^10.1.0", - "vscode": "^1.83.0" + "vscode": "^1.68.0" }, "exports": { ".": "./dist/src/extension.js", diff --git a/packages/core/src/extension.ts b/packages/core/src/extension.ts index 468aa6c61a9..778c90969b2 100644 --- a/packages/core/src/extension.ts +++ b/packages/core/src/extension.ts @@ -55,7 +55,7 @@ import { registerCommands } from './commands' // In web mode everything must be in a single file, so things like the endpoints file will not be available. // The following imports the endpoints file, which causes webpack to bundle it in the final output file import endpoints from '../resources/endpoints.json' -import { getLogger, setupUninstallHandler } from './shared' +import { getLogger, maybeShowMinVscodeWarning, setupUninstallHandler } from './shared' import { showViewLogsMessage } from './shared/utilities/messages' disableAwsSdkWarning() @@ -102,6 +102,8 @@ export async function activateCommon( getLogger().error('fs.init: invalid home directory given by env vars: %O', homeDirLogs) } + void maybeShowMinVscodeWarning('1.83.0') + if (isCloud9()) { vscode.window.withProgress = wrapWithProgressForCloud9(globals.outputChannel) context.subscriptions.push( diff --git a/packages/core/src/shared/extensionStartup.ts b/packages/core/src/shared/extensionStartup.ts index 3770fa65825..d10c194d503 100644 --- a/packages/core/src/shared/extensionStartup.ts +++ b/packages/core/src/shared/extensionStartup.ts @@ -6,14 +6,43 @@ import * as _ from 'lodash' import * as path from 'path' import * as vscode from 'vscode' +import * as semver from 'semver' import * as nls from 'vscode-nls' import { BaseTemplates } from './templates/baseTemplates' import { fs } from '../shared/fs/fs' -import { getIdeProperties, isCloud9, isCn } from './extensionUtilities' +import { getIdeProperties, getIdeType, isAmazonQ, isCloud9, isCn, productName } from './extensionUtilities' +import * as localizedText from './localizedText' +import { AmazonQPromptSettings, ToolkitPromptSettings } from './settings' const localize = nls.loadMessageBundle() +/** + * Shows a (suppressible) warning if the current vscode version is older than `minVscode`. + */ +export async function maybeShowMinVscodeWarning(minVscode: string) { + const settings = isAmazonQ() ? AmazonQPromptSettings.instance : ToolkitPromptSettings.instance + if (!(await settings.isPromptEnabled('minIdeVersion'))) { + return + } + const updateButton = `Update ${vscode.env.appName}` + if (getIdeType() === 'vscode' && semver.lt(vscode.version, minVscode)) { + void vscode.window + .showWarningMessage( + `${productName()} will soon require VS Code ${minVscode} or newer. The currently running version ${vscode.version} will no longer receive updates.`, + updateButton, + localizedText.dontShow + ) + .then(async (resp) => { + if (resp === updateButton) { + await vscode.commands.executeCommand('update.checkForUpdate') + } else if (resp === localizedText.dontShow) { + void settings.disablePrompt('minIdeVersion') + } + }) + } +} + /** * Helper function to show a webview containing the quick start page * diff --git a/packages/core/src/shared/extensionUtilities.ts b/packages/core/src/shared/extensionUtilities.ts index a0c7bbd9bb9..1b30c22bbc8 100644 --- a/packages/core/src/shared/extensionUtilities.ts +++ b/packages/core/src/shared/extensionUtilities.ts @@ -58,36 +58,29 @@ export function commandsPrefix(): string { return isAmazonQ() ? 'Amazon Q' : getIdeProperties().company } -export enum IDE { - vscode, - cloud9, - sagemaker, - unknown, -} - let computeRegion: string | undefined = notInitialized -export function getIdeType(): IDE { +export function getIdeType(): 'vscode' | 'cloud9' | 'sagemaker' | 'unknown' { const settings = DevSettings.instance if ( vscode.env.appName === cloud9Appname || vscode.env.appName === cloud9CnAppname || settings.get('forceCloud9', false) ) { - return IDE.cloud9 + return 'cloud9' } if (vscode.env.appName === sageMakerAppname) { - return IDE.sagemaker + return 'sagemaker' } // Theia doesn't necessarily have all env properties // so we should be defensive and assume appName is nullable. if (vscode.env.appName?.startsWith(vscodeAppname)) { - return IDE.vscode + return 'vscode' } - return IDE.unknown + return 'unknown' } interface IdeProperties { @@ -112,12 +105,12 @@ export function getIdeProperties(): IdeProperties { } switch (getIdeType()) { - case IDE.cloud9: + case 'cloud9': if (isCn()) { return createCloud9Properties(localize('AWS.title.cn', 'Amazon')) } return createCloud9Properties(company) - case IDE.sagemaker: + case 'sagemaker': if (isCn()) { // check for cn region return createSageMakerProperties(localize('AWS.title.cn', 'Amazon')) @@ -155,7 +148,7 @@ function createCloud9Properties(company: string): IdeProperties { * Decides if the current system is (the specified flavor of) Cloud9. */ export function isCloud9(flavor: 'classic' | 'codecatalyst' | 'any' = 'any'): boolean { - const cloud9 = getIdeType() === IDE.cloud9 + const cloud9 = getIdeType() === 'cloud9' if (!cloud9 || flavor === 'any') { return cloud9 } diff --git a/packages/core/src/shared/index.ts b/packages/core/src/shared/index.ts index a31c647e226..e60d18f84ff 100644 --- a/packages/core/src/shared/index.ts +++ b/packages/core/src/shared/index.ts @@ -14,7 +14,8 @@ export { activate as activateTelemetry } from './telemetry/activation' export { DefaultAwsContext } from './awsContext' export { DefaultAWSClientBuilder, ServiceOptions } from './awsClientBuilder' export { Settings } from './settings' -export { initializeComputeRegion } from './extensionUtilities' +export * from './extensionUtilities' +export * from './extensionStartup' export { RegionProvider } from './regions/regionProvider' export { Commands } from './vscode/commands2' export { getMachineId } from './vscode/env' diff --git a/packages/core/src/shared/sam/activation.ts b/packages/core/src/shared/sam/activation.ts index 4ae45aee103..22e3016bedf 100644 --- a/packages/core/src/shared/sam/activation.ts +++ b/packages/core/src/shared/sam/activation.ts @@ -25,7 +25,7 @@ import * as goLensProvider from '../codelens/goCodeLensProvider' import { SamTemplateCodeLensProvider } from '../codelens/samTemplateCodeLensProvider' import * as jsLensProvider from '../codelens/typescriptCodeLensProvider' import { ExtContext, VSCODE_EXTENSION_ID } from '../extensions' -import { getIdeProperties, getIdeType, IDE, isCloud9 } from '../extensionUtilities' +import { getIdeProperties, getIdeType, isCloud9 } from '../extensionUtilities' import { getLogger } from '../logger/logger' import { PerfLog } from '../logger/perfLogger' import { NoopWatcher } from '../fs/watchedFiles' @@ -324,7 +324,7 @@ async function createYamlExtensionPrompt(): Promise { // not have a marketplace or contain the YAML plugin. if ( (await settings.isPromptEnabled('yamlExtPrompt')) && - getIdeType() === IDE.vscode && + getIdeType() === 'vscode' && !vscode.extensions.getExtension(VSCODE_EXTENSION_ID.yaml) ) { // Disposed immediately after showing one, so the user isn't prompted diff --git a/packages/core/src/shared/settings-amazonq.gen.ts b/packages/core/src/shared/settings-amazonq.gen.ts index 1579e16227c..4fbe8ab0005 100644 --- a/packages/core/src/shared/settings-amazonq.gen.ts +++ b/packages/core/src/shared/settings-amazonq.gen.ts @@ -17,6 +17,7 @@ export const amazonqSettings = { "codeWhispererConnectionExpired": {}, "amazonQWelcomePage": {}, "amazonQSessionConfigurationMessage": {}, + "minIdeVersion": {}, "ssoCacheError": {} }, "amazonQ.showInlineCodeSuggestionsWithCodeReferences": {}, diff --git a/packages/core/src/shared/settings-toolkit.gen.ts b/packages/core/src/shared/settings-toolkit.gen.ts index 2d33c3300c5..ea291352701 100644 --- a/packages/core/src/shared/settings-toolkit.gen.ts +++ b/packages/core/src/shared/settings-toolkit.gen.ts @@ -37,6 +37,7 @@ export const toolkitSettings = { "samcliConfirmDevStack": {}, "remoteConnected": {}, "codeCatalystConnectionExpired": {}, + "minIdeVersion": {}, "ssoCacheError": {} }, "aws.experiments": { diff --git a/packages/core/src/test/shared/extensionUtilities.test.ts b/packages/core/src/test/shared/extensionUtilities.test.ts index 5acc9b0f205..255455a54f1 100644 --- a/packages/core/src/test/shared/extensionUtilities.test.ts +++ b/packages/core/src/test/shared/extensionUtilities.test.ts @@ -18,10 +18,20 @@ import { InstanceIdentity } from '../../shared/clients/ec2MetadataClient' import { extensionVersion } from '../../shared/vscode/env' import { sleep } from '../../shared/utilities/timeoutUtils' import globals from '../../shared/extensionGlobals' -import { createQuickStartWebview } from '../../shared/extensionStartup' +import { createQuickStartWebview, maybeShowMinVscodeWarning } from '../../shared/extensionStartup' import { fs } from '../../shared' +import { getTestWindow } from './vscode/window' describe('extensionUtilities', function () { + it('maybeShowMinVscodeWarning', async () => { + const testVscodeVersion = '99.0.0' + await maybeShowMinVscodeWarning(testVscodeVersion) + const expectedMsg = + /will soon require .* 99\.0\.0 or newer. The currently running version .* will no longer receive updates./ + const msg = await getTestWindow().waitForMessage(expectedMsg) + msg.close() + }) + describe('createQuickStartWebview', async function () { let context: FakeExtensionContext let tempDir: string | undefined diff --git a/packages/toolkit/.changes/next-release/Deprecation-2df766d2-cbec-4fdc-bb69-80f90d9d15ef.json b/packages/toolkit/.changes/next-release/Deprecation-2df766d2-cbec-4fdc-bb69-80f90d9d15ef.json new file mode 100644 index 00000000000..78d58a5fbe6 --- /dev/null +++ b/packages/toolkit/.changes/next-release/Deprecation-2df766d2-cbec-4fdc-bb69-80f90d9d15ef.json @@ -0,0 +1,4 @@ +{ + "type": "Deprecation", + "description": "The next release of this extension will require VS Code 1.83.0 or newer." +} diff --git a/packages/toolkit/.changes/next-release/Feature-7dfff66e-77a0-478d-8b74-6f3990b85a16.json b/packages/toolkit/.changes/next-release/Feature-7dfff66e-77a0-478d-8b74-6f3990b85a16.json new file mode 100644 index 00000000000..021933ef072 --- /dev/null +++ b/packages/toolkit/.changes/next-release/Feature-7dfff66e-77a0-478d-8b74-6f3990b85a16.json @@ -0,0 +1,4 @@ +{ + "type": "Feature", + "description": "Show a one-time warning if new VS Code is required" +} diff --git a/packages/toolkit/package.json b/packages/toolkit/package.json index 3e957178a01..43acf33053c 100644 --- a/packages/toolkit/package.json +++ b/packages/toolkit/package.json @@ -53,7 +53,7 @@ "browser": "./dist/src/extensionWeb", "engines": { "npm": "^10.1.0", - "vscode": "^1.83.0" + "vscode": "^1.68.0" }, "scripts": { "vscode:prepublish": "npm run clean && npm run buildScripts && webpack --mode production", @@ -225,6 +225,10 @@ "type": "boolean", "default": false }, + "minIdeVersion": { + "type": "boolean", + "default": false + }, "ssoCacheError": { "type": "boolean", "default": false