From a8e796fa9bf5c93db54c8212a27e24bbf8d50446 Mon Sep 17 00:00:00 2001 From: Ruiming <15029672963@163.com> Date: Thu, 21 May 2026 16:49:44 +0800 Subject: [PATCH 1/5] Fixed issue 322: app modernization -> GitHub Copilot modernization. --- .../toolkit/intellij/appmod/common/AppModPluginInstaller.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/common/AppModPluginInstaller.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/common/AppModPluginInstaller.java index 3640832996..1fe69136f1 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/common/AppModPluginInstaller.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/common/AppModPluginInstaller.java @@ -107,8 +107,8 @@ public static void showInstallConfirmation(@Nonnull Project project, boolean for : "Install this plugin to automate migrating your apps to Azure with Copilot."; } else { message = forUpgrade - ? "To upgrade your apps, you'll need two plugins: GitHub Copilot and app modernization." - : "To migrate to Azure, you'll need two plugins: GitHub Copilot and app modernization."; + ? "To upgrade your apps, you'll need two plugins: GitHub Copilot and GitHub Copilot modernization." + : "To migrate to Azure, you'll need two plugins: GitHub Copilot and GitHub Copilot modernization."; } AppModUtils.logTelemetryEvent("plugin." + action + ".install-prompt-shown", Map.of("copilotInstalled", String.valueOf(copilotInstalled))); if (Messages.showOkCancelDialog(project, message, title, "Install", "Cancel", Messages.getQuestionIcon()) == Messages.OK) { From 89b4242e7880cb5ff540bf18cd1150ce81e981d2 Mon Sep 17 00:00:00 2001 From: Ruiming <15029672963@163.com> Date: Thu, 21 May 2026 17:11:27 +0800 Subject: [PATCH 2/5] Update for code review. --- .../toolkit/intellij/appmod/common/AppModPluginInstaller.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/common/AppModPluginInstaller.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/common/AppModPluginInstaller.java index 1fe69136f1..75972cddeb 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/common/AppModPluginInstaller.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/common/AppModPluginInstaller.java @@ -107,8 +107,8 @@ public static void showInstallConfirmation(@Nonnull Project project, boolean for : "Install this plugin to automate migrating your apps to Azure with Copilot."; } else { message = forUpgrade - ? "To upgrade your apps, you'll need two plugins: GitHub Copilot and GitHub Copilot modernization." - : "To migrate to Azure, you'll need two plugins: GitHub Copilot and GitHub Copilot modernization."; + ? "To upgrade your apps, you'll need to install GitHub Copilot modernization." + : "To migrate to Azure, you'll need to install GitHub Copilot modernization."; } AppModUtils.logTelemetryEvent("plugin." + action + ".install-prompt-shown", Map.of("copilotInstalled", String.valueOf(copilotInstalled))); if (Messages.showOkCancelDialog(project, message, title, "Install", "Cancel", Messages.getQuestionIcon()) == Messages.OK) { From e66cce36f7deb8deaab6674880c036831a55e931 Mon Sep 17 00:00:00 2001 From: Ruiming <15029672963@163.com> Date: Tue, 26 May 2026 15:26:28 +0800 Subject: [PATCH 3/5] Fixed https://github.com/devdiv-microsoft/appmod-intellij/issues/324. --- .../javaupgrade/service/JavaVersionNotificationService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/service/JavaVersionNotificationService.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/service/JavaVersionNotificationService.java index 4ea59332a0..ffc8ee3dab 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/service/JavaVersionNotificationService.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/service/JavaVersionNotificationService.java @@ -48,7 +48,7 @@ public class JavaVersionNotificationService { private static final String NOTIFICATIONS_ENABLED_KEY = "azure.toolkit.java.version.notifications.enabled"; private static final String DEFERRED_UNTIL_KEY = "azure.toolkit.java.version.deferred_until"; private static final long DEFER_INTERVAL_MS = 10 * 24 * 60 * 60 * 1000L; // 10 days in milliseconds - private static final String DEFAULT_MODEL_NAME = "Claude Sonnet 4.5"; + private static final String DEFAULT_MODEL_NAME = "Claude Sonnet 4.6"; // GitHub Copilot plugin ID private static final String COPILOT_PLUGIN_ID = "com.github.copilot"; From ca957427126a07899edf3c45c06a2a9ffb484ead Mon Sep 17 00:00:00 2001 From: Ruiming <15029672963@163.com> Date: Fri, 29 May 2026 17:12:11 +0800 Subject: [PATCH 4/5] Fixed https://github.com/devdiv-microsoft/appmod-intellij/issues/325. --- .../action/UpgradeActionRegistrar.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/UpgradeActionRegistrar.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/UpgradeActionRegistrar.java index d0d58a23ce..a41c567e7e 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/UpgradeActionRegistrar.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/UpgradeActionRegistrar.java @@ -6,10 +6,15 @@ package com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.action; import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.ActionPopupMenu; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.actionSystem.Separator; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.actionSystem.ex.ActionPopupMenuListener; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.ProjectActivity; import com.microsoft.azure.toolkit.intellij.appmod.common.AppModPluginInstaller; @@ -21,6 +26,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.concurrent.atomic.AtomicBoolean; + /** * Registers the Upgrade action into the GitHub Copilot context menu at runtime. * This is needed because the Copilot plugin creates its context menu groups dynamically. @@ -31,17 +38,67 @@ public class UpgradeActionRegistrar implements ProjectActivity { private static final String UPGRADE_ACTION_ID = "AzureToolkit.JavaUpgradeContextMenu"; private static final String PROJECT_VIEW_POPUP_MENU = "ProjectViewPopupMenu"; + // Application-level guard so we install the popup listener only once per IDE process, + // even if multiple projects are opened (this ProjectActivity runs per-project). + private static final AtomicBoolean POPUP_LISTENER_INSTALLED = new AtomicBoolean(false); + @Nullable @Override public Object execute(@NotNull Project project, @NotNull Continuation continuation) { try{ + // Eager attempt: works on 2nd+ project open within the same IDE process, + // after the GitHub Copilot plugin has populated its dynamic submenu. discoverAndRegisterAction(); + // Lazy fallback (fixes the first-open race): re-attempt the registration + // every time the Project View popup is created. The Copilot submenu is + // guaranteed to exist by the time the user right-clicks, and the call + // is cheap + idempotent thanks to the containsAction guard. + installLazyRegistrationListener(); } catch (Throwable e) { log.error("Failed to register Upgrade action in Copilot context menu.", e); } return Unit.INSTANCE; } + /** + * Installs an application-scoped {@link ActionPopupMenuListener} (only once per IDE + * process) that re-runs {@link #discoverAndRegisterAction()} whenever the Project + * View popup menu is opened. This is the lazy fallback for the first project open + * after IDE launch, where {@link ProjectActivity}s from us and from the GitHub Copilot + * plugin race and our discovery can miss Copilot's not-yet-created submenu. + */ + private void installLazyRegistrationListener() { + if (!POPUP_LISTENER_INSTALLED.compareAndSet(false, true)) { + return; + } + try { + ActionManagerEx.getInstanceEx().addActionPopupMenuListener(new ActionPopupMenuListener() { + @Override + public void actionPopupMenuCreated(@NotNull ActionPopupMenu menu) { + // Only react to the Project View right-click popup; ignore all + // other popups (editor, tool windows, etc.) to keep this cheap. + if (!ActionPlaces.PROJECT_VIEW_POPUP.equals(menu.getPlace())) { + return; + } + try { + discoverAndRegisterAction(); + } catch (Throwable ex) { + log.warn("Lazy registration of Upgrade action into Copilot submenu failed.", ex); + } + } + + @Override + public void actionPopupMenuReleased(@NotNull ActionPopupMenu menu) { + // no-op + } + }, ApplicationManager.getApplication()); + } catch (Throwable e) { + // Roll back the flag so a later project open can try installing again. + POPUP_LISTENER_INSTALLED.set(false); + log.warn("Failed to install lazy registration listener for Upgrade action.", e); + } + } + private void discoverAndRegisterAction() { // Only proceed if Copilot plugin is installed if (!AppModPluginInstaller.isCopilotInstalled()) { From 383911ad71fd811e9f9cb92ba46f457c0856473d Mon Sep 17 00:00:00 2001 From: Ruiming <15029672963@163.com> Date: Mon, 1 Jun 2026 15:58:08 +0800 Subject: [PATCH 5/5] Readjustment for fix of issue 325. Now the `(Install GitHub Copilot Mordenization)` suffix doesn't unexpectedly repeat evertime hovering the level 1 menu "GitHub Copilot". --- .../action/CveFixDependencyInProblemsViewAction.java | 5 ++++- .../javaupgrade/action/JavaUpgradeContextMenuAction.java | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/CveFixDependencyInProblemsViewAction.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/CveFixDependencyInProblemsViewAction.java index ca1fc05af1..04d776deb3 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/CveFixDependencyInProblemsViewAction.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/CveFixDependencyInProblemsViewAction.java @@ -93,8 +93,11 @@ public void update(@NotNull AnActionEvent e) { } e.getPresentation().setEnabledAndVisible(true); // e.getPresentation().setText(SCAN_AND_RESOLVE_CVES_WITH_COPILOT_DISPLAY_NAME); + final String baseText = getTemplatePresentation().getText(); if (!AppModPluginInstaller.isAppModPluginInstalled()) { - e.getPresentation().setText(e.getPresentation().getText() + AppModPluginInstaller.TO_INSTALL_APP_MODE_PLUGIN); + e.getPresentation().setText(baseText + AppModPluginInstaller.TO_INSTALL_APP_MODE_PLUGIN); + } else { + e.getPresentation().setText(baseText); } } catch (Throwable ex) { // In case of any error, hide the action diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/JavaUpgradeContextMenuAction.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/JavaUpgradeContextMenuAction.java index 4f56c35018..c22103f974 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/JavaUpgradeContextMenuAction.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/JavaUpgradeContextMenuAction.java @@ -56,8 +56,11 @@ public void update(@NotNull AnActionEvent e) { isMavenBuildFile(file) || isGradleBuildFile(file); } + final String baseText = getTemplatePresentation().getText(); if (!isAppModPluginInstalled()) { - e.getPresentation().setText(e.getPresentation().getText() + TO_INSTALL_APP_MODE_PLUGIN); + e.getPresentation().setText(baseText + TO_INSTALL_APP_MODE_PLUGIN); + } else { + e.getPresentation().setText(baseText); } if (visible){ AppModUtils.logTelemetryEvent("showJavaUpgradeContextMenuAction", Map.of("appmodPluginInstalled", String.valueOf(isAppModPluginInstalled())));