[release] prepare v0.41.4 release

ea9ff879 extension/CHANGELOG.md: add the entry for v0.41.4
d1cde8cd extension/src/welcome: readd the fix for go.showWelcome handling
cfc795c4 Revert "extension/src/welcome: fix 'go.showWelcome' setting interpretation"

Change-Id: Iebf964dacaaa47e02c7219aafc2d7c8e3d7bdfec
diff --git a/extension/CHANGELOG.md b/extension/CHANGELOG.md
index 38235e8..ca37327 100644
--- a/extension/CHANGELOG.md
+++ b/extension/CHANGELOG.md
@@ -1,3 +1,11 @@
+## v0.41.4 - 24 Apr, 2024
+
+This point release addresses a regression issue (spurious display of the Go welcome page)  within cloud-based IDEs.
+
+See the full
+[commit history](https://github.com/golang/vscode-go/compare/v0.41.3...v0.41.4)
+for detailed changes.
+
 ## v0.41.3 - 22 Apr, 2024
 
 This point release temporarily reverts the default remote debugging behavior to
diff --git a/extension/src/welcome.ts b/extension/src/welcome.ts
index d68ed75..f20379b 100644
--- a/extension/src/welcome.ts
+++ b/extension/src/welcome.ts
@@ -29,7 +29,17 @@
 				}
 			});
 		}
-		showGoWelcomePage();
+
+		// Show the Go welcome page on update unless one of the followings is true:
+		//   * the extension is running in Cloud IDE or
+		//   * the user explicitly opted out (go.showWelcome === false)
+		//
+		// It is difficult to write useful tests for this suppression logic
+		// without major refactoring or complicating tests to enable
+		// dependency injection or stubbing.
+		if (!extensionInfo.isInCloudIDE && getGoConfig().get('showWelcome') !== false) {
+			showGoWelcomePage();
+		}
 	}
 
 	public static currentPanel: WelcomePanel | undefined;
@@ -265,7 +275,7 @@
 
 	const savedGoExtensionVersion = getFromGlobalState(goExtensionVersionKey, '');
 
-	if (shouldShowGoWelcomePage(showVersions, goExtensionVersion, savedGoExtensionVersion)) {
+	if (hasNewsForNewVersion(showVersions, goExtensionVersion, savedGoExtensionVersion)) {
 		vscode.commands.executeCommand('go.welcome');
 	}
 	if (goExtensionVersion !== savedGoExtensionVersion) {
@@ -273,10 +283,7 @@
 	}
 }
 
-export function shouldShowGoWelcomePage(showVersions: string[], newVersion: string, oldVersion: string): boolean {
-	if (!extensionInfo.isInCloudIDE && getGoConfig().get('showWelcome') === false) {
-		return false;
-	}
+export function hasNewsForNewVersion(showVersions: string[], newVersion: string, oldVersion: string): boolean {
 	if (newVersion === oldVersion) {
 		return false;
 	}
diff --git a/extension/test/integration/welcome.test.ts b/extension/test/integration/welcome.test.ts
index 72885ae..8a530c4 100644
--- a/extension/test/integration/welcome.test.ts
+++ b/extension/test/integration/welcome.test.ts
@@ -5,74 +5,56 @@
 
 import vscode = require('vscode');
 import assert from 'assert';
-import { shouldShowGoWelcomePage } from '../../src/welcome';
+import { hasNewsForNewVersion } from '../../src/welcome';
 import { extensionId } from '../../src/const';
 import { WelcomePanel } from '../../src/welcome';
-import sinon = require('sinon');
-import * as config from '../../src/config';
-import { MockCfg } from '../mocks/MockCfg';
 
 suite('WelcomePanel Tests', () => {
-	let sandbox: sinon.SinonSandbox;
-	setup(() => {
-		sandbox = sinon.createSandbox();
-	});
-	teardown(() => sandbox.restore());
-
-	// 0:showVersions, 1:newVersion, 2:oldVersion, 3: showWelcome, 4:expected
-	//
-	// If showWelcome is false, then expected has to be false.
-	// Otherwise, expected is true if (and only if) newVersion occurs in showVersions
-	// and is newer than oldVersion (as semantic versions).
-	type testCase = [string[], string, string, boolean, boolean];
+	// 0:showVersions, 1:newVersion, 2:oldVersion, 3:expected
+	type testCase = [string[], string, string, boolean];
 	const testCases: testCase[] = [
-		[[], '0.22.0', '0.0.0', true, false],
-		[[], '0.22.0', '0.21.0', true, false],
-		[[], '0.22.0', '0.22.0-rc.1', true, false],
-		[[], '0.22.0', '0.22.0', true, false],
-		[[], '0.22.0', '0.23.0', true, false],
+		[[], '0.22.0', '0.0.0', false],
+		[[], '0.22.0', '0.21.0', false],
+		[[], '0.22.0', '0.22.0-rc.1', false],
+		[[], '0.22.0', '0.22.0', false],
+		[[], '0.22.0', '0.23.0', false],
 
-		[['0.22.0'], '0.22.0', '0.0.0', true, true],
-		[['0.22.0'], '0.22.0', '0.0.0', false, false],
-		[['0.22.0'], '0.22.0', '0.21.0-rc.1', true, true],
-		[['0.22.0'], '0.22.0', '0.21.0', true, true],
-		[['0.22.0'], '0.22.0', '0.22.0-rc.1', true, true],
-		[['0.22.0'], '0.22.0', '0.22.0', true, false],
-		[['0.22.0'], '0.22.0', '0.22.1', true, false],
-		[['0.22.0'], '0.22.0', '0.23.0', true, false],
-		[['0.22.0'], '0.22.0', '1.0.0', true, false],
-		[['0.22.0'], '0.22.0', '2021.1.100', true, false],
+		[['0.22.0'], '0.22.0', '0.0.0', true],
+		[['0.22.0'], '0.22.0', '0.21.0-rc.1', true],
+		[['0.22.0'], '0.22.0', '0.21.0', true],
+		[['0.22.0'], '0.22.0', '0.22.0-rc.1', true],
+		[['0.22.0'], '0.22.0', '0.22.0', false],
+		[['0.22.0'], '0.22.0', '0.22.1', false],
+		[['0.22.0'], '0.22.0', '0.23.0', false],
+		[['0.22.0'], '0.22.0', '1.0.0', false],
+		[['0.22.0'], '0.22.0', '2021.1.100', false],
 
-		[['0.22.0'], '0.22.0-rc.2', '0.0.0', true, true],
-		[['0.22.0'], '0.22.0-rc.2', '0.21.0-rc.1', true, true],
-		[['0.22.0'], '0.22.0-rc.2', '0.21.0', true, true],
-		[['0.22.0'], '0.22.0-rc.2', '0.22.0-rc.1', true, true],
-		[['0.22.0'], '0.22.0-rc.2', '0.22.0-rc.2', true, false],
-		[['0.22.0'], '0.22.0-rc.2', '0.22.0-rc.3', true, true],
-		[['0.22.0'], '0.22.0-rc.2', '0.22.0', true, true],
-		[['0.22.0'], '0.22.0-rc.2', '0.22.1', true, false],
-		[['0.22.0'], '0.22.0-rc.2', '0.23.0', true, false],
-		[['0.22.0'], '0.22.0-rc.2', '1.0.0', true, false],
-		[['0.22.0'], '0.22.0-rc.2', '2021.1.100', true, false],
+		[['0.22.0'], '0.22.0-rc.2', '0.0.0', true],
+		[['0.22.0'], '0.22.0-rc.2', '0.21.0-rc.1', true],
+		[['0.22.0'], '0.22.0-rc.2', '0.21.0', true],
+		[['0.22.0'], '0.22.0-rc.2', '0.22.0-rc.1', true],
+		[['0.22.0'], '0.22.0-rc.2', '0.22.0-rc.2', false],
+		[['0.22.0'], '0.22.0-rc.2', '0.22.0-rc.3', true],
+		[['0.22.0'], '0.22.0-rc.2', '0.22.0', true],
+		[['0.22.0'], '0.22.0-rc.2', '0.22.1', false],
+		[['0.22.0'], '0.22.0-rc.2', '0.23.0', false],
+		[['0.22.0'], '0.22.0-rc.2', '1.0.0', false],
+		[['0.22.0'], '0.22.0-rc.2', '2021.1.100', false],
 
-		[['0.22.0'], '0.22.1', '0.0.0', true, false],
-		[['0.22.0'], '0.22.1', '0.21.0-rc.1', true, false],
-		[['0.22.0'], '0.22.1', '0.21.0', true, false],
-		[['0.22.0'], '0.22.1', '0.22.0-rc.1', true, false],
-		[['0.22.0'], '0.22.1', '0.22.0', true, false],
-		[['0.22.0'], '0.22.1', '0.23.0', true, false],
-		[['0.22.0'], '0.22.1', '1.0.0', true, false],
-		[['0.22.0'], '0.22.1', '2021.1.100', true, false]
+		[['0.22.0'], '0.22.1', '0.0.0', false],
+		[['0.22.0'], '0.22.1', '0.21.0-rc.1', false],
+		[['0.22.0'], '0.22.1', '0.21.0', false],
+		[['0.22.0'], '0.22.1', '0.22.0-rc.1', false],
+		[['0.22.0'], '0.22.1', '0.22.0', false],
+		[['0.22.0'], '0.22.1', '0.23.0', false],
+		[['0.22.0'], '0.22.1', '1.0.0', false],
+		[['0.22.0'], '0.22.1', '2021.1.100', false]
 	];
 	testCases.forEach((c: testCase) => {
-		const [showVersions, newVersion, oldVersion, showWelcome, expected] = c;
-		test(`shouldShowGoWelcomePage(${JSON.stringify(
-			showVersions
-		)}, ${newVersion}, ${oldVersion}, (showWelcome=${showWelcome}))`, () => {
-			const goConfig = new MockCfg([]);
-			sandbox.stub(config, 'getGoConfig').returns(goConfig);
-			sinon.stub(goConfig, 'get').withArgs('showWelcome').returns(showWelcome);
-			assert.strictEqual(shouldShowGoWelcomePage(showVersions, newVersion, oldVersion), expected);
+		const [showVersions, newVersion, oldVersion, expected] = c;
+
+		test(`shouldShowGoWelcomePage(${JSON.stringify(showVersions)}, ${newVersion}, ${oldVersion})`, () => {
+			assert.strictEqual(hasNewsForNewVersion(showVersions, newVersion, oldVersion), expected);
 		});
 	});
 });