From 2edf01e521c6444cc73f99bbb355de95bba600bc Mon Sep 17 00:00:00 2001 From: Miller Wang Date: Mon, 9 Mar 2026 10:06:23 +0800 Subject: [PATCH 01/19] Support IntelliJ IDEA 2026.1 EAP Co-Authored-By: Claude Opus 4.6 --- .../azure-toolkit-for-intellij/gradle.properties | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties index 44e58bd76b..dcdfc60ad9 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties @@ -1,12 +1,12 @@ -pluginVersion=3.97.3 -intellijDisplayVersion=2025.3 -intellij_version=253-EAP-SNAPSHOT -platformVersion=253-EAP-SNAPSHOT +pluginVersion=3.98.0 +intellijDisplayVersion=2026.1 +intellij_version=261-EAP-SNAPSHOT +platformVersion=261-EAP-SNAPSHOT # Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html -pluginSinceBuild=253 -pluginUntilBuild=253.* +pluginSinceBuild=261 +pluginUntilBuild=261.* # Example: platformPlugins = com.jetbrains.php:203.4449.22, org.intellij.scala:2023.3.27@EAP -platformPlugins=org.intellij.scala:2025.3.12 +platformPlugins=org.intellij.scala:2026.1.8 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IU needPatchVersion=true @@ -36,4 +36,3 @@ org.gradle.jvmargs='-Duser.language=en' org.jetbrains.intellij.platform.buildFeature.useBinaryReleases=false - From 4681aa0adae0b2d00f0c14a5f6a905257cf4aaf3 Mon Sep 17 00:00:00 2001 From: Miller Wang Date: Mon, 9 Mar 2026 11:11:49 +0800 Subject: [PATCH 02/19] Fix: Upgrade Gradle to 9.0 and IntelliJ Platform Plugin to 2.12.0 for EAP support --- .azure-pipelines/build_and_sign.yml | 212 ++++++++++++++++++ CLAUDE.md | 125 +++++++++++ .../gradle.properties | 2 +- .../gradle/libs.versions.toml | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 43462 -> 43453 bytes gradlew | 2 +- gradlew.bat | 20 +- 8 files changed, 351 insertions(+), 14 deletions(-) create mode 100644 .azure-pipelines/build_and_sign.yml create mode 100644 CLAUDE.md diff --git a/.azure-pipelines/build_and_sign.yml b/.azure-pipelines/build_and_sign.yml new file mode 100644 index 0000000000..dcd24963ca --- /dev/null +++ b/.azure-pipelines/build_and_sign.yml @@ -0,0 +1,212 @@ +name: $(Date:yyyyMMdd).$(Rev:r) +variables: + - name: Codeql.Enabled + value: true + - name: IsStableBuild + value: ${{ or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release-')) }} + - name: IsNightlyBuild + value: ${{ and(eq(variables['Build.Reason'], 'Schedule'), eq(variables['Build.SourceBranch'], 'refs/heads/develop')) }} + - name: DoRealSign + value: ${{ or(eq(parameters.ForceRealSign, true), eq(variables['IsStableBuild'], true), eq(variables['IsNightlyBuild'], true)) }} + - name: DoProceedToRelease + value: ${{ or(eq(variables['DoRealSign'], true), eq(parameters.ForceTestSignRelease, true)) }} + - name: RELEASE_CHANNEL + ${{ if or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release-')) }}: + value: stable + ${{ else }}: + value: nightly + - name: SIGNTYPE + ${{ if eq(variables['DoRealSign'], true) }}: + value: real + ${{ else }}: + value: test + +parameters: + - name: ForceRealSign + displayName: "Force usage of real sign (PME PoP needed)" + type: boolean + default: false + - name: ForceTestSignRelease + displayName: "Force release on test sign (for test ONLY)" + type: boolean + default: false + +resources: + repositories: + - repository: self + type: git + ref: refs/heads/main + - repository: 1esPipelines + type: git + name: 1ESPipelineTemplates/1ESPipelineTemplates + ref: refs/tags/release + +trigger: + branches: + include: + - main + - develop + - release-* + +pr: + - main + - develop + - release-* + +schedules: + - cron: "0 22 * * 0-4" # 6:00 Mon-Fri UTC+8 + displayName: "Nightly build" + branches: + include: + - develop + always: true + +extends: + template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines + parameters: + featureFlags: + disableNetworkIsolation: true + pool: + name: VSEngSS-MicroBuild2022-1ES + stages: + - stage: Build_Plugin + displayName: "Build Plugin" + jobs: + - job: Build_and_Sign + displayName: Build and Sign Plugin + timeoutInMinutes: 360 + templateContext: + outputs: + - output: pipelineArtifact + artifactName: plugin + targetPath: $(build.artifactstagingdirectory)/plugin + displayName: "Publish Artifact: plugin" + steps: + - checkout: self + clean: true + fetchTags: false + - task: PowerShell@2 + displayName: Install JDK 21 + inputs: + targetType: inline + script: | + # Download Adoptium/Temurin JDK 21.0.8 + Write-Host "Downloading Java 21.0.8..." + $source = "https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.8%2B9/OpenJDK21U-jdk_x64_windows_hotspot_21.0.8_9.zip" + $destination = "$(build.sourcesdirectory)\jdk21_x64_windows.zip" + Invoke-WebRequest -Uri $source -OutFile $destination + - task: JavaToolInstaller@0 + displayName: "Use Java 21" + inputs: + versionSpec: 21 + jdkArchitectureOption: x64 + jdkSourceOption: LocalDirectory + jdkFile: '$(build.sourcesdirectory)\jdk21_x64_windows.zip' + jdkDestinationDirectory: "$(agent.toolsDirectory)/jdk21" + - task: UseNode@1 + inputs: + version: "22.x" + - task: NuGetAuthenticate@1 + displayName: "🔩 NuGet Authenticate" + - task: MicroBuildSigningPlugin@4 + displayName: "Add MicroBuild Signing Plugin" + inputs: + ${{if eq(variables.DoRealSign, true) }}: + signType: "real" + ConnectedPMEServiceName: "40012d40-9ded-4f75-8476-d60758200346" + ${{ else }}: + signType: "test" + feedSource: "https://mseng.pkgs.visualstudio.com/DefaultCollection/_packaging/MicroBuildToolset/nuget/v3/index.json" + env: + MicroBuildOutputFolderOverride: "$(Agent.TempDirectory)" + - task: PowerShell@2 + displayName: Build Plugin + inputs: + targetType: inline + script: | + mvn -v + # ./gradlew buildUtils || exit -1 + mvn clean install -f ./Utils/pom.xml -T 1C "-Dcheckstyle.skip=true" "-Dmaven.test.skip=true" "-Dmaven.javadoc.skip=true" + mvn clean -f ./Utils/pom.xml + cd PluginsAndFeatures/azure-toolkit-for-intellij + ./gradlew clean buildPlugin -s "-Papplicationinsights.key=$(INTELLIJ_KEY)" "-PneedPatchVersion=false" "-Psources=false" "-Porg.gradle.configureondemand=false" "-Porg.gradle.daemon=false" "-Porg.gradle.unsafe.configuration-cache=false" "-Porg.gradle.caching=false" + env: + USE_STABLE_VERSION: $(IsStableBuild) + - task: PowerShell@2 + displayName: Unpackage + inputs: + targetType: inline + script: | + Write-Host "Creating artifacts directory..." + New-Item -ItemType Directory -Path ".\artifacts\intellij\" -Force + Write-Host "Finding plugin zip file..." + $zipFile = Get-ChildItem ".\PluginsAndFeatures\azure-toolkit-for-intellij\build\distributions\*.zip" | Select-Object -First 1 + Write-Host "Found: $($zipFile.FullName)" + Write-Host "Copying to artifacts..." + Copy-Item $zipFile.FullName ".\artifacts\intellij\azure-intellij.zip" + Write-Host "Extracting archive..." + Expand-Archive -Path ".\artifacts\intellij\azure-intellij.zip" -DestinationPath ".\artifacts\intellij\folder" -Force + Write-Host "Cleaning up temporary zip file..." + Remove-Item ".\artifacts\intellij\azure-intellij.zip" + Write-Host "Unpackaging completed successfully" + - task: PowerShell@2 + displayName: Sign jars + timeoutInMinutes: 240 + inputs: + targetType: inline + script: | + Write-Host "Searching for JAR files to sign..." + $files = Get-ChildItem -Path . -Include "azure-intellij-*.jar", "azure-toolkit-for-intellij*.jar", "azure-toolkit-ide-*.jar", "azuretools-core.jar", "azure-explorer-common.jar", "hdinsight-node-common.jar" -Recurse -File + Write-Host "Found $($files.Count) JAR file(s) to sign" + $counter = 0 + foreach ($file in $files) { + $counter++ + Write-Host "[$counter/$($files.Count)] Signing: $($file.Name) with sign type: $(SIGNTYPE)" + dotnet "$env:MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$($file.FullName)" /certs:100010171 /signType:$(SIGNTYPE) + Write-Host " ✓ Signed successfully" + } + Write-Host "All JAR files signed successfully" + workingDirectory: 'artifacts/intellij/folder/azure-intellij/lib' + - task: CmdLine@2 + displayName: Repackage + inputs: + script: | + echo Starting repackaging... + cd artifacts\intellij\folder + echo Creating final zip archive: azure-intellij-$(Build.BuildNumber).zip + tar -a -c -f ..\..\azure-intellij-$(Build.BuildNumber).zip * + echo Repackaging completed successfully + - task: CopyFiles@2 + displayName: "Copy Files to: $(build.artifactstagingdirectory)" + inputs: + SourceFolder: $(system.defaultworkingdirectory)/artifacts + Contents: "*.zip" + TargetFolder: $(build.artifactstagingdirectory)/plugin + - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + displayName: "Manifest Generator " + inputs: + BuildDropPath: $(build.artifactstagingdirectory)/plugin + - stage: Release_Plugin + condition: ${{ variables.DoProceedToRelease }} + displayName: Release Plugin to Marketplace + dependsOn: Build_Plugin + jobs: + - deployment: releasePlugin + templateContext: + type: releaseJob + isProduction: true + inputs: + - input: pipelineArtifact + artifactName: "plugin" + targetPath: "$(Pipeline.Workspace)/plugin" + environment: azure-intellij-plugin-release + strategy: + runOnce: + deploy: + steps: + - task: PowerShell@2 + displayName: Release + inputs: + targetType: inline + script: | + curl.exe -i --header "Authorization: Bearer ${env:RELEASE_TOKEN}" -F pluginId=28791 -F "file=@$(Pipeline.Workspace)/plugin/azure-intellij-$(Build.BuildNumber).zip" -F channel=$(RELEASE_CHANNEL) https://plugins.jetbrains.com/plugin/uploadPlugin diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000000..56304c79d0 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,125 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +Azure Toolkits for Java — IDE plugins for IntelliJ IDEA and Eclipse that help Java developers create, develop, configure, test, and deploy applications to Azure. The primary focus of active development is the IntelliJ plugin. + +## Build Commands + +### Prerequisites +- Java 17 (required for IntelliJ plugin; set `JAVA_HOME` accordingly) +- The shared toolkit libraries from [azure-maven-plugins](https://github.com/microsoft/azure-maven-plugins) must be installed to local Maven repo first + +### Build shared toolkit libs (one-time or when libs change) +```bash +# Clone and build azure-toolkit-libs into local Maven repo +git clone https://github.com/microsoft/azure-maven-plugins.git +cd azure-maven-plugins/azure-toolkit-libs +mvn clean install -B -T 4 -Dmaven.test.skip=true +``` + +### Build Utils (Maven modules in Utils/) +```bash +# From repo root — builds the IDE-specific wrapper libraries +mvn clean install -f Utils/pom.xml +# Or via the root Gradle task: +./gradlew buildUtils -x buildToolkitsLib +``` + +### Build IntelliJ plugin +```bash +cd PluginsAndFeatures/azure-toolkit-for-intellij +./gradlew clean buildPlugin -s +``` +Output ZIP: `PluginsAndFeatures/azure-toolkit-for-intellij/build/distributions/` + +### Build Eclipse plugin +```bash +mvn clean install -f Utils/pom.xml +mvn clean install -f PluginsAndFeatures/AddLibrary/AzureLibraries/pom.xml +mvn clean install -f PluginsAndFeatures/azure-toolkit-for-eclipse/pom.xml +``` + +### Build everything (from repo root) +```bash +./gradlew buildAll +``` + +### Run/Debug IntelliJ plugin locally +Open `PluginsAndFeatures/azure-toolkit-for-intellij` in IntelliJ and use the Gradle `runIde` task. Remote debug port: 5005. + +### Tests +```bash +# IntelliJ plugin tests (run from the IntelliJ plugin dir) +cd PluginsAndFeatures/azure-toolkit-for-intellij +./gradlew test + +# Utils tests (Maven) +mvn test -f Utils/pom.xml + +# Skip tests during build +./gradlew buildAll -PskipTest=true +# Or for Maven modules: +mvn install -f Utils/pom.xml -Dmaven.test.skip=true +``` + +### Checkstyle +Checkstyle runs by default on Maven builds. Skip with: +```bash +mvn install -f Utils/pom.xml -Dcheckstyle.skip=true +``` +IntelliJ plugin checkstyle config: `PluginsAndFeatures/azure-toolkit-for-intellij/config/checkstyle/checkstyle.xml` + +## Architecture + +### Three-Layer Dependency Stack + +1. **azure-toolkit-libs** (external repo: `azure-maven-plugins`) — Core SDK wrappers for Azure services. IDE-agnostic. Must be `mvn install`ed to local repo before building this project. + +2. **Utils/** (this repo, Maven) — IDE-specific wrapper libraries (`azure-toolkit-ide-libs` and `azure-toolkit-ide-hdinsight-libs`). Each Azure service has a corresponding `azure-toolkit-ide-*-lib` module (e.g., `azure-toolkit-ide-appservice-lib`, `azure-toolkit-ide-cosmos-lib`). Built with Maven and published to local repo for the Gradle IntelliJ build to consume. + +3. **PluginsAndFeatures/** (this repo) — IDE plugin implementations: + - `azure-toolkit-for-intellij/` — IntelliJ plugin (Gradle + Kotlin DSL, ~40 submodules) + - `azure-toolkit-for-eclipse/` — Eclipse plugin (Maven/Tycho) + +### IntelliJ Plugin Module Structure + +The IntelliJ plugin is a single composite plugin built from ~40 Gradle submodules, each declared in `settings.gradle.kts`. Key module categories: + +- **`azure-intellij-plugin-lib`** — Core IntelliJ integration: UI components (AzureComboBox, AzureDialog, Tree), action framework, auth, messager, task manager, telemetry. This is the foundation module. +- **`azure-intellij-plugin-lib-java`** — Java-specific IntelliJ utilities (run configs, artifact handling). +- **`azure-intellij-plugin-base`** — Plugin entry point (`AzurePlugin` as `StartupActivity`), lifecycle management. +- **`azure-intellij-plugin-service-explorer`** — Azure Explorer tool window. +- **`azure-intellij-resource-connector-lib`** — Resource connection framework (connecting Azure resources to project modules). +- **Service modules** — One per Azure service (e.g., `azure-intellij-plugin-appservice`, `azure-intellij-plugin-cosmos`, `azure-intellij-plugin-database`, `azure-intellij-plugin-storage`, etc.) +- **`-java` suffix modules** — Java-language-specific features for that service (e.g., `azure-intellij-plugin-appservice-java`, `azure-intellij-plugin-database-java`). + +### Extension Point Pattern + +The plugin uses an IntelliJ extension point `com.microsoft.tooling.msservices.intellij.azure.actions` with the `IActionsContributor` interface. Each service module registers its own `ActionsContributor` implementation via its `META-INF/*.xml` descriptor. These are composed into the main `plugin.xml` using `xi:include`. + +To add a new service module: +1. Create the module directory under `PluginsAndFeatures/azure-toolkit-for-intellij/` +2. Add it to `settings.gradle.kts` +3. Add an `implementation(project(":module-name"))` dependency in the root `build.gradle.kts` +4. Create a `META-INF/.xml` descriptor +5. Include it in `src/main/resources/META-INF/plugin.xml` via `xi:include` + +### Build System Details + +- **Root Gradle** (`build.gradle` at repo root) — Orchestrates cross-project builds. Uses Groovy DSL with Gradle 8.8. +- **IntelliJ Gradle** (`PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts`) — Uses Kotlin DSL with IntelliJ Platform Gradle Plugin 2.3.0. Targets IntelliJ IDEA Ultimate for compilation. Version catalog at `gradle/libs.versions.toml`. +- **Maven** (`Utils/pom.xml`) — Builds the IDE wrapper libraries. Uses AspectJ for cross-cutting concerns (via `azure-toolkit-common-lib`). +- AspectJ weaving is used at both Maven (aspectj-maven-plugin) and Gradle (io.freefair.aspectj.post-compile-weaving) levels. + +### Key Conventions + +- Java 17 source/target for all modules. +- Lombok is used project-wide (`@Data`, `@Builder`, etc.). +- All Java source files require the MIT license header (enforced by checkstyle). +- LF line endings required (no CRLF). +- No tabs — spaces only. +- TODOs must be named: `TODO (name): description`. +- Base package: `com.microsoft.azure.toolkit.intellij` for IntelliJ modules, `com.microsoft.azure.toolkit.lib` for library modules. diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties index dcdfc60ad9..e116225a74 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties @@ -22,7 +22,7 @@ platformDownloadSources=true # Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib kotlin.stdlib.default.dependency=false # Gradle Releases -> https://github.com/gradle/gradle/releases -gradleVersion=8.14.1 +gradleVersion=9.0 # Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html org.gradle.configuration-cache=true org.gradle.configuration-cache.problems=warn diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle/libs.versions.toml b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle/libs.versions.toml index fa3446576d..160c9f77b9 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle/libs.versions.toml +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle/libs.versions.toml @@ -5,7 +5,7 @@ kotlin = "2.2.20" changelog = "2.4.0" #intellijPlatform = "2.10.1" -intellijPlatform = "2.10.1" +intellijPlatform = "2.12.0" detekt = "1.23.6" ktlint = "12.1.1" #gradleIntelliJPlugin = "1.17.3" diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle/wrapper/gradle-wrapper.properties b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle/wrapper/gradle-wrapper.properties index 002b867c48..2dcec856bd 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle/wrapper/gradle-wrapper.properties +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd4917707c1f8861d8cb53dd15194d4248596..e6441136f3d4ba8a0da8d277868979cfbc8ad796 100644 GIT binary patch delta 34118 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 delta 34176 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 SGW6ptSs!X7{rG*o_g?|vpSEZK diff --git a/gradlew b/gradlew index 1aa94a4269..b740cf1339 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. diff --git a/gradlew.bat b/gradlew.bat index 93e3f59f13..25da30dbde 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail From 3a27e701262ec2ff614368a1b7982c96191e84aa Mon Sep 17 00:00:00 2001 From: Miller Wang Date: Mon, 9 Mar 2026 14:09:26 +0800 Subject: [PATCH 03/19] Support IntelliJ IDEA 2026.1 EAP - fix build.gradle.kts for Plugin 2.12.0 API changes --- .../azure-toolkit-for-intellij/build.gradle.kts | 10 ++++++---- .../gradle/libs.versions.toml | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts b/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts index 696be47258..2d07cb4219 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts @@ -4,7 +4,7 @@ import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType import org.jetbrains.intellij.platform.gradle.tasks.VerifyPluginTask import java.time.LocalDateTime import java.time.format.DateTimeFormatter -import java.net.URL +import java.net.URI fun properties(key: String) = providers.gradleProperty(key) fun environment(key: String) = providers.environmentVariable(key) @@ -60,7 +60,9 @@ allprojects { dependencies { intellijPlatform { - intellijIdeaUltimate(properties("platformVersion").get(), useInstaller = false) + intellijIdeaUltimate(properties("platformVersion").get()) { + useInstaller = false + } } implementation(platform("com.microsoft.azure:azure-toolkit-libs:0.52.2")) @@ -146,7 +148,7 @@ intellijPlatform { pluginVerification { ides { - ide(IntelliJPlatformType.IntellijIdeaCommunity, properties("platformVersion").get()) + create(IntelliJPlatformType.IntellijIdeaCommunity, properties("platformVersion").get()) } } } @@ -256,7 +258,7 @@ tasks { if (!langServerDir.exists()) { logger.info("Downloading bicep language server ...") val zipFile = file("azure-intellij-plugin-bicep/downloaded.zip") - URL("https://aka.ms/java-toolkit-bicep-ls").openStream().use { input -> + URI("https://aka.ms/java-toolkit-bicep-ls").toURL().openStream().use { input -> zipFile.outputStream().use { it.write(input.readBytes()) } } logger.info("Unzipping bicep language server ...") diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle/libs.versions.toml b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle/libs.versions.toml index 160c9f77b9..6527cbeaab 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle/libs.versions.toml +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle/libs.versions.toml @@ -10,7 +10,7 @@ detekt = "1.23.6" ktlint = "12.1.1" #gradleIntelliJPlugin = "1.17.3" #qodana = "2024.1.5" -aspectj = "8.6" +aspectj = "9.2.0" springDependencyManagement = "1.1.6" serialization = "1.9.24" From 3aad089284d2bbdc021a6c307f5e94b19ddf518e Mon Sep 17 00:00:00 2001 From: Miller Wang Date: Mon, 9 Mar 2026 14:16:17 +0800 Subject: [PATCH 04/19] Fix ktlint code style violations for IntelliJ 2026.1 EAP support --- .../build.gradle.kts | 6 +- .../spark/common/SparkSubmitModelScenario.kt | 43 +-- .../hdinsight/spark/common/SparkUITest.kt | 2 +- .../spark/ui/ImmutableComboBoxModelTest.kt | 6 +- .../hdinsight/spark/ui/SparkJobTableTest.kt | 332 +++++++++++------- 5 files changed, 242 insertions(+), 147 deletions(-) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts b/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts index 2d07cb4219..19708ad2aa 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts @@ -1,12 +1,12 @@ import io.freefair.gradle.plugins.aspectj.AjcAction import org.apache.tools.ant.filters.ReplaceTokens import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType -import org.jetbrains.intellij.platform.gradle.tasks.VerifyPluginTask +import java.net.URI import java.time.LocalDateTime import java.time.format.DateTimeFormatter -import java.net.URI fun properties(key: String) = providers.gradleProperty(key) + fun environment(key: String) = providers.environmentVariable(key) plugins { @@ -303,4 +303,4 @@ tasks { // publishPlugin { // dependsOn(patchChangelog) // } -} \ No newline at end of file +} diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/test/java/com/microsoft/azure/hdinsight/spark/common/SparkSubmitModelScenario.kt b/PluginsAndFeatures/azure-toolkit-for-intellij/src/test/java/com/microsoft/azure/hdinsight/spark/common/SparkSubmitModelScenario.kt index 4a3bc9661f..6d3630dcf4 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/test/java/com/microsoft/azure/hdinsight/spark/common/SparkSubmitModelScenario.kt +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/test/java/com/microsoft/azure/hdinsight/spark/common/SparkSubmitModelScenario.kt @@ -40,15 +40,17 @@ class SparkSubmitModelScenario { @Given("^set SparkSubmitModel properties as following$") fun initSparkSubmitModel(properties: Map) { - properties.forEach { key, value -> when (key) { - "cluster_name" -> submitModel.clusterName = value - "is_local_artifact" -> submitModel.isLocalArtifact = value.toBoolean() - "local_artifact_path" -> submitModel.localArtifactPath = value - "classname" -> submitModel.mainClassName = value - "cmd_line_args" -> submitModel.commandLineArgs = value.split(" ") - "ref_jars" -> submitModel.referenceJars = value.split(";") - "ref_files" -> submitModel.referenceFiles = value.split(";") - } } + properties.forEach { key, value -> + when (key) { + "cluster_name" -> submitModel.clusterName = value + "is_local_artifact" -> submitModel.isLocalArtifact = value.toBoolean() + "local_artifact_path" -> submitModel.localArtifactPath = value + "classname" -> submitModel.mainClassName = value + "cmd_line_args" -> submitModel.commandLineArgs = value.split(" ") + "ref_jars" -> submitModel.referenceJars = value.split(";") + "ref_files" -> submitModel.referenceFiles = value.split(";") + } + } } @Then("^checking XML serialized should to be '(.*)'$") @@ -57,7 +59,6 @@ class SparkSubmitModelScenario { val actual = XMLOutputter().outputString(element) assertEquals(expect, actual) - } @Given("^the SparkSubmitModel XML input '(.*)' to deserialize$") @@ -69,14 +70,16 @@ class SparkSubmitModelScenario { @Then("^check SparkSubmitModel properties as following$") fun checkSparkSubmitMode(expect: Map) { - expect.forEach { key, value -> when (key) { - "cluster_name" -> assertEquals(value, submitModel.clusterName) - "is_local_artifact" -> assertEquals(value.toBoolean(), submitModel.isLocalArtifact) - "local_artifact_path" -> assertEquals(value, submitModel.localArtifactPath) - "classname" -> assertEquals(value, submitModel.mainClassName) - "cmd_line_args" -> assertEquals(value, submitModel.commandLineArgs.joinToString(" ")) - "ref_jars" -> assertEquals(value, submitModel.referenceJars.joinToString(";")) - "ref_files" -> assertEquals(value, submitModel.referenceFiles.joinToString(";")) - } } + expect.forEach { key, value -> + when (key) { + "cluster_name" -> assertEquals(value, submitModel.clusterName) + "is_local_artifact" -> assertEquals(value.toBoolean(), submitModel.isLocalArtifact) + "local_artifact_path" -> assertEquals(value, submitModel.localArtifactPath) + "classname" -> assertEquals(value, submitModel.mainClassName) + "cmd_line_args" -> assertEquals(value, submitModel.commandLineArgs.joinToString(" ")) + "ref_jars" -> assertEquals(value, submitModel.referenceJars.joinToString(";")) + "ref_files" -> assertEquals(value, submitModel.referenceFiles.joinToString(";")) + } + } } -} \ No newline at end of file +} diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/test/java/com/microsoft/azure/hdinsight/spark/common/SparkUITest.kt b/PluginsAndFeatures/azure-toolkit-for-intellij/src/test/java/com/microsoft/azure/hdinsight/spark/common/SparkUITest.kt index 8b5c5d9745..0187aa13f0 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/test/java/com/microsoft/azure/hdinsight/spark/common/SparkUITest.kt +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/test/java/com/microsoft/azure/hdinsight/spark/common/SparkUITest.kt @@ -51,4 +51,4 @@ open class SparkUITest : LightJavaCodeInsightFixtureTestCase() { isVisible = true } } -} \ No newline at end of file +} diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/test/java/com/microsoft/azure/hdinsight/spark/ui/ImmutableComboBoxModelTest.kt b/PluginsAndFeatures/azure-toolkit-for-intellij/src/test/java/com/microsoft/azure/hdinsight/spark/ui/ImmutableComboBoxModelTest.kt index 8e1d8bf2c5..7d6f792109 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/test/java/com/microsoft/azure/hdinsight/spark/ui/ImmutableComboBoxModelTest.kt +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/test/java/com/microsoft/azure/hdinsight/spark/ui/ImmutableComboBoxModelTest.kt @@ -25,10 +25,10 @@ package com.microsoft.azure.hdinsight.spark.ui import com.microsoft.intellij.ui.util.findFirst import com.microsoft.intellij.ui.util.iterator import junit.framework.TestCase -import org.assertj.core.api.Assertions.* +import org.assertj.core.api.Assertions.assertThat import org.junit.Test -class ImmutableComboBoxModelTest: TestCase() { +class ImmutableComboBoxModelTest : TestCase() { @Test fun testIterator() { val data = listOf(3, 5, 4, 2) @@ -51,4 +51,4 @@ class ImmutableComboBoxModelTest: TestCase() { val emptyModel: ImmutableComboBoxModel? = null assertNull(emptyModel.findFirst { true }) } -} \ No newline at end of file +} diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/test/java/com/microsoft/azure/hdinsight/spark/ui/SparkJobTableTest.kt b/PluginsAndFeatures/azure-toolkit-for-intellij/src/test/java/com/microsoft/azure/hdinsight/spark/ui/SparkJobTableTest.kt index b482f9cd4c..f294523a2a 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/test/java/com/microsoft/azure/hdinsight/spark/ui/SparkJobTableTest.kt +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/test/java/com/microsoft/azure/hdinsight/spark/ui/SparkJobTableTest.kt @@ -42,40 +42,48 @@ import java.awt.event.WindowEvent import java.util.concurrent.TimeUnit class KillLivyJobAction : AzureAnAction(AllIcons.Actions.Cancel) { - override fun onActionPerformed(anActionEvent: AnActionEvent, operation: Operation?): Boolean { + override fun onActionPerformed( + anActionEvent: AnActionEvent, + operation: Operation?, + ): Boolean { System.out.println("Clicked ${anActionEvent.place} kill job button") return true } } class RestartLivyJobAction : AzureAnAction(AllIcons.Actions.Restart) { - override fun onActionPerformed(anActionEvent: AnActionEvent, operation: Operation?): Boolean { + override fun onActionPerformed( + anActionEvent: AnActionEvent, + operation: Operation?, + ): Boolean { System.out.println("Clicked ${anActionEvent.place} restart job button") return true } } -const val killActionColName = "KillAction" -const val restartActionColName = "RestartAction" -const val idColName = "ID" -const val appIdColName = "AppID" -const val stateColName = "State" - -class MockSparkLivyJobsTableSchema - : UniqueColumnNameTableSchema(arrayOf( - ActionColumnInfo(killActionColName), - ActionColumnInfo(restartActionColName), - PlainColumnInfo(idColName), - PlainColumnInfo(appIdColName), - PlainColumnInfo(stateColName))) { +const val KILL_ACTION_COL_NAME = "KillAction" +const val RESTART_ACTION_COL_NAME = "RestartAction" +const val ID_COL_NAME = "ID" +const val APP_ID_COL_NAME = "AppID" +const val STATE_COL_NAME = "State" +class MockSparkLivyJobsTableSchema : + UniqueColumnNameTableSchema( + arrayOf( + ActionColumnInfo(KILL_ACTION_COL_NAME), + ActionColumnInfo(RESTART_ACTION_COL_NAME), + PlainColumnInfo(ID_COL_NAME), + PlainColumnInfo(APP_ID_COL_NAME), + PlainColumnInfo(STATE_COL_NAME), + ), + ) { inner class MockSparkJobDescriptor(val jobStatus: SparkSubmitResponse) : RowDescriptor( - killActionColName to KillLivyJobAction(), - restartActionColName to RestartLivyJobAction(), - idColName to jobStatus.id, - appIdColName to jobStatus.appId, - stateColName to jobStatus.state) - + KILL_ACTION_COL_NAME to KillLivyJobAction(), + RESTART_ACTION_COL_NAME to RestartLivyJobAction(), + ID_COL_NAME to jobStatus.id, + APP_ID_COL_NAME to jobStatus.appId, + STATE_COL_NAME to jobStatus.state, + ) } class MockSparkBatchJobViewerControl(private val view: MockSparkBatchJobViewer) : LivyBatchJobViewer.Control { @@ -84,26 +92,28 @@ class MockSparkBatchJobViewerControl(private val view: MockSparkBatchJobViewer) } override fun onJobSelected(jobSelected: UniqueColumnNameTableSchema.RowDescriptor?) { - val sparkJobDesc = (jobSelected as? MockSparkLivyJobsTableSchema.MockSparkJobDescriptor)?.let { arrayOf(it)} - ?: emptyArray() + val sparkJobDesc = + (jobSelected as? MockSparkLivyJobsTableSchema.MockSparkJobDescriptor)?.let { arrayOf(it) } + ?: emptyArray() Observable.from(sparkJobDesc) - .delay(500, TimeUnit.MILLISECONDS) - .subscribe { view.getModel(LivyBatchJobViewer.Model::class.java).apply { - jobDetail = if (it.jobStatus.id == 1) { - // Unclosed JSON string - """{"message":"A broken response for ${it.jobStatus.appId}!","error no": 0, "id": ${it.jobStatus.id}""" - - } else { - """{"message":"hello ${it.jobStatus.appId}!","error no": 0, "id": ${it.jobStatus.id}}""" - } + .delay(500, TimeUnit.MILLISECONDS) + .subscribe { + view.getModel(LivyBatchJobViewer.Model::class.java).apply { + jobDetail = + if (it.jobStatus.id == 1) { + // Unclosed JSON string + """{"message":"A broken response for ${it.jobStatus.appId}!","error no": 0, "id": ${it.jobStatus.id}""" + } else { + """{"message":"hello ${it.jobStatus.appId}!","error no": 0, "id": ${it.jobStatus.id}}""" + } view.setData(this) - }} + } + } } } - class MockSparkBatchJobViewer : LivyBatchJobViewer() { override val jobViewerControl: Control by lazy { MockSparkBatchJobViewerControl(this@MockSparkBatchJobViewer) } } @@ -119,100 +129,180 @@ fun getJobListPage(pageLink: String?): JobPage? { println("Get job list from $pageLink") return when (pageLink) { - "http://page1" -> object : JobPage { - override fun nextPageLink(): String? { - return "http://page2" - } + "http://page1" -> + object : JobPage { + override fun nextPageLink(): String? { + return "http://page2" + } - override fun items(): List? { - return listOf( - tableSchema.MockSparkJobDescriptor(parseJSON("""{ - "id": 1, - "appId": "application-134124194-1", - "state": "running" - }""".trimIndent())), - tableSchema.MockSparkJobDescriptor(parseJSON("""{ - "id": 2, - "appId": null, - "state": "dead" - }""".trimIndent())), - tableSchema.MockSparkJobDescriptor(parseJSON("""{ - "id": 3, - "state": "success" - }""".trimIndent())), - tableSchema.MockSparkJobDescriptor(parseJSON("""{ - "id": 4, - "appId": "application-134124194-4" - }""".trimIndent())) - ) - } - } - "http://page2" -> object : JobPage { - override fun nextPageLink(): String? { - return "http://page3" + override fun items(): List? { + return listOf( + tableSchema.MockSparkJobDescriptor( + parseJSON( + """ + { + "id": 1, + "appId": "application-134124194-1", + "state": "running" + } + """.trimIndent(), + ), + ), + tableSchema.MockSparkJobDescriptor( + parseJSON( + """ + { + "id": 2, + "appId": null, + "state": "dead" + } + """.trimIndent(), + ), + ), + tableSchema.MockSparkJobDescriptor( + parseJSON( + """ + { + "id": 3, + "state": "success" + } + """.trimIndent(), + ), + ), + tableSchema.MockSparkJobDescriptor( + parseJSON( + """ + { + "id": 4, + "appId": "application-134124194-4" + } + """.trimIndent(), + ), + ), + ) + } } + "http://page2" -> + object : JobPage { + override fun nextPageLink(): String? { + return "http://page3" + } - override fun items(): List? { - return listOf( - tableSchema.MockSparkJobDescriptor(parseJSON("""{ - "id": 5, - "appId": "application-134124194-5", - "state": "running" - }""".trimIndent())), - tableSchema.MockSparkJobDescriptor(parseJSON("""{ - "id": 6, - "appId": null, - "state": "dead" - }""".trimIndent())), - tableSchema.MockSparkJobDescriptor(parseJSON("""{ - "id": 7, - "state": "success" - }""".trimIndent())), - tableSchema.MockSparkJobDescriptor(parseJSON("""{ - "id": 8, - "appId": "application-134124194-8" - }""".trimIndent())) - ) - } - } - "http://page3" -> object : JobPage { - override fun nextPageLink(): String? { - return null + override fun items(): List? { + return listOf( + tableSchema.MockSparkJobDescriptor( + parseJSON( + """ + { + "id": 5, + "appId": "application-134124194-5", + "state": "running" + } + """.trimIndent(), + ), + ), + tableSchema.MockSparkJobDescriptor( + parseJSON( + """ + { + "id": 6, + "appId": null, + "state": "dead" + } + """.trimIndent(), + ), + ), + tableSchema.MockSparkJobDescriptor( + parseJSON( + """ + { + "id": 7, + "state": "success" + } + """.trimIndent(), + ), + ), + tableSchema.MockSparkJobDescriptor( + parseJSON( + """ + { + "id": 8, + "appId": "application-134124194-8" + } + """.trimIndent(), + ), + ), + ) + } } + "http://page3" -> + object : JobPage { + override fun nextPageLink(): String? { + return null + } - override fun items(): List? { - return listOf( - tableSchema.MockSparkJobDescriptor(parseJSON("""{ - "id": 9, - "appId": "application-134124194-9", - "state": "running" - }""".trimIndent())), - tableSchema.MockSparkJobDescriptor(parseJSON("""{ - "id": 10, - "appId": null, - "state": "dead" - }""".trimIndent())), - tableSchema.MockSparkJobDescriptor(parseJSON("""{ - "id": 11, - "state": "success" - }""".trimIndent())), - tableSchema.MockSparkJobDescriptor(parseJSON("""{ - "id": 12, - "appId": "application-134124194-12" - }""".trimIndent())) - ) + override fun items(): List? { + return listOf( + tableSchema.MockSparkJobDescriptor( + parseJSON( + """ + { + "id": 9, + "appId": "application-134124194-9", + "state": "running" + } + """.trimIndent(), + ), + ), + tableSchema.MockSparkJobDescriptor( + parseJSON( + """ + { + "id": 10, + "appId": null, + "state": "dead" + } + """.trimIndent(), + ), + ), + tableSchema.MockSparkJobDescriptor( + parseJSON( + """ + { + "id": 11, + "state": "success" + } + """.trimIndent(), + ), + ), + tableSchema.MockSparkJobDescriptor( + parseJSON( + """ + { + "id": 12, + "appId": "application-134124194-12" + } + """.trimIndent(), + ), + ), + ) + } } - } else -> null } } + @Ignore class SparkJobTableTest : SparkUITest() { - @Test fun testLivyTable() { - val model = LivyBatchJobViewer.Model(LivyBatchJobTableViewport.Model( - LivyBatchJobTableModel(tableSchema), getJobListPage("http://page1"))) + val model = + LivyBatchJobViewer.Model( + LivyBatchJobTableViewport.Model( + LivyBatchJobTableModel(tableSchema), + getJobListPage("http://page1"), + ), + ) jobView.setData(model) @@ -220,11 +310,13 @@ class SparkJobTableTest : SparkUITest() { contentPane.add(jobView.component) pack() - addWindowListener(object: WindowAdapter() { - override fun windowClosing(e: WindowEvent?) { - jobView.dispose() - } - }) + addWindowListener( + object : WindowAdapter() { + override fun windowClosing(e: WindowEvent?) { + jobView.dispose() + } + }, + ) isVisible = true } } From 5586e97fed70cbf6c0e0257789bd32880f0dff68 Mon Sep 17 00:00:00 2001 From: Miller Wang Date: Mon, 9 Mar 2026 15:47:45 +0800 Subject: [PATCH 05/19] Fix IntelliJ 2026.1 EAP API breaking changes - Add bundledPlugin('org.jetbrains.idea.reposearch') for MavenId class (moved from maven plugin) - Add testImplementation('junit:junit:4.13.2') (no longer bundled with platform) - Add maven-artifact dependency for ComparableVersion (no longer on platform classpath) --- .gitignore | 2 ++ .../build.gradle.kts | 2 ++ .../AzureCosmosDbAccountParamEditor.java | 4 ++- .../build.gradle.kts | 29 +++++++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f2db4d08b4..fa05dc8a55 100644 --- a/.gitignore +++ b/.gitignore @@ -111,3 +111,5 @@ pom.xml.versionsBackup # Bicep Language Server **/bicep-langserver/** **/azure-intellij-plugin-bicep/downloaded.zip +*.log +deps.txt diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-bicep/build.gradle.kts b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-bicep/build.gradle.kts index 6309b2736b..a8ef64b4d8 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-bicep/build.gradle.kts +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-bicep/build.gradle.kts @@ -8,6 +8,8 @@ dependencies { implementation("com.vladsch.flexmark:flexmark:0.64.0") implementation("com.vladsch.flexmark:flexmark-util:0.64.0") implementation("org.apache.commons:commons-lang3:3.12.0") + // ComparableVersion is no longer on the platform classpath in 261 + implementation("org.apache.maven:maven-artifact:3.9.11") testImplementation("junit:junit:4.13.2") testImplementation("org.mockito:mockito-core:3.9.0") testImplementation("org.powermock:powermock-api-mockito2:2.0.9") diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-cosmos/src/main/java/com/microsoft/azure/toolkit/intellij/cosmos/dbtools/AzureCosmosDbAccountParamEditor.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-cosmos/src/main/java/com/microsoft/azure/toolkit/intellij/cosmos/dbtools/AzureCosmosDbAccountParamEditor.java index 22947591ec..86f17c4aeb 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-cosmos/src/main/java/com/microsoft/azure/toolkit/intellij/cosmos/dbtools/AzureCosmosDbAccountParamEditor.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-cosmos/src/main/java/com/microsoft/azure/toolkit/intellij/cosmos/dbtools/AzureCosmosDbAccountParamEditor.java @@ -209,7 +209,9 @@ private void setUsername(String user) { @SneakyThrows private void setUseSsl(boolean useSsl) { final DataSourceConfigurable configurable = this.getDataSourceConfigurable(); - final JBCheckBox useSSLCheckBox = (JBCheckBox) FieldUtils.readField(configurable.getSshSslPanel(), "myUseSSLJBCheckBox", true); + // getSshSslPanel() was removed in IntelliJ 261; use reflection to access the panel field directly + final Object sshSslPanel = FieldUtils.readField(configurable, "mySshSslPanel", true); + final JBCheckBox useSSLCheckBox = (JBCheckBox) FieldUtils.readField(sshSslPanel, "myUseSSLJBCheckBox", true); useSSLCheckBox.setSelected(useSsl); } diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts b/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts index 19708ad2aa..47bf01a535 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts @@ -63,6 +63,13 @@ allprojects { intellijIdeaUltimate(properties("platformVersion").get()) { useInstaller = false } + // JBR 25 required to run IntelliJ 2026.1 (PathClassLoader is JBR-only) + jetbrainsRuntimeLocal("C:/Users/wangmi/.jdks/jbr-25/jbr_jcef-25.0.2-windows-x64-b329.72") + // MavenId/MavenCoordinate classes moved from maven plugin to repository-search plugin in 261 + bundledPlugin("org.jetbrains.idea.reposearch") + // Test framework classes moved to separate modules in 261 + testFramework(org.jetbrains.intellij.platform.gradle.TestFrameworkType.Platform) + testFramework(org.jetbrains.intellij.platform.gradle.TestFrameworkType.Plugin.Java) } implementation(platform("com.microsoft.azure:azure-toolkit-libs:0.52.2")) @@ -74,6 +81,8 @@ allprojects { annotationProcessor("org.projectlombok:lombok:1.18.32") implementation("com.microsoft.azure:azure-toolkit-common-lib:0.52.2") aspect("com.microsoft.azure:azure-toolkit-common-lib:0.52.2") + // junit was removed from IntelliJ platform bundled libs in 261 + testImplementation("junit:junit:4.13.2") } configurations { @@ -116,6 +125,17 @@ allprojects { duplicatesStrategy = DuplicatesStrategy.WARN } + // Gradle 9 requires explicit dependency declaration for shared sandbox outputs + withType { + dependsOn(rootProject.tasks.named("prepareTestSandbox")) + // Each subproject's test sandbox may be produced by other subproject tasks + rootProject.subprojects.forEach { sub -> + sub.tasks.matching { it.name == "prepareTestSandbox" }.configureEach { + this@withType.dependsOn(this) + } + } + } + sourceSets { main { java.srcDirs("src/main/java") @@ -127,6 +147,10 @@ allprojects { java.srcDir("src/test/java") kotlin.srcDirs("src/test/kotlin") resources.srcDir("src/test/resources") + // Exclude legacy duplicate hdinsight test files from root module; + // they are properly maintained in azure-intellij-plugin-hdinsight-base + java.exclude("com/microsoft/azure/hdinsight/**") + kotlin.exclude("com/microsoft/azure/hdinsight/**") } } } @@ -216,6 +240,11 @@ dependencies { implementation("com.microsoft.azure:azure-toolkit-auth-lib") implementation("com.microsoft.azure:azure-toolkit-ide-common-lib") implementation("com.microsoft.azure:azure-toolkit-ide-appservice-lib") + + // Test dependencies for root module tests (cucumber, assertj) + testImplementation("io.cucumber:cucumber-java:7.0.0") + testImplementation("io.cucumber:cucumber-junit:7.0.0") + testImplementation("org.assertj:assertj-core:3.19.0") } tasks { From e54925180dc775f06a15819aee8955125bf52f28 Mon Sep 17 00:00:00 2001 From: Miller Wang Date: Tue, 10 Mar 2026 00:08:21 +0800 Subject: [PATCH 06/19] fix: remove override of final ConsoleViewImpl.isDisposed() method In IntelliJ 261, ConsoleViewImpl.isDisposed() became final. Remove the custom isDisposed field and override, relying on the parent implementation instead. Callers already use the inherited method through the ConsoleView interface. --- .../common/streaminglog/StreamingLogsConsoleView.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib/src/main/java/com/microsoft/azure/toolkit/intellij/common/streaminglog/StreamingLogsConsoleView.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib/src/main/java/com/microsoft/azure/toolkit/intellij/common/streaminglog/StreamingLogsConsoleView.java index 0596ea516a..3add2cecc3 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib/src/main/java/com/microsoft/azure/toolkit/intellij/common/streaminglog/StreamingLogsConsoleView.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib/src/main/java/com/microsoft/azure/toolkit/intellij/common/streaminglog/StreamingLogsConsoleView.java @@ -14,12 +14,10 @@ public class StreamingLogsConsoleView extends ConsoleViewImpl { private static final String SEPARATOR = System.getProperty("line.separator"); - private boolean isDisposed; private Disposable subscription; public StreamingLogsConsoleView(@NotNull Project project) { super(project, true); - this.isDisposed = false; this.setUpdateFoldingsEnabled(false); } @@ -43,10 +41,6 @@ public boolean isActive() { return subscription != null && !subscription.isDisposed(); } - public boolean isDisposed() { - return this.isDisposed; - } - private void printlnToConsole(String message, ConsoleViewContentType consoleViewContentType) { this.print(message + SEPARATOR, consoleViewContentType); } @@ -54,7 +48,6 @@ private void printlnToConsole(String message, ConsoleViewContentType consoleView @Override public void dispose() { super.dispose(); - this.isDisposed = true; closeStreamingLog(); } } From 6dcea3167a861518f95ba6894b71db9c32a795ec Mon Sep 17 00:00:00 2001 From: Miller Wang Date: Tue, 10 Mar 2026 00:09:51 +0800 Subject: [PATCH 07/19] fix: add missing resource bundle key 'user/appmod.refresh_migrate_node' Add the missing operation description for the migrate-to-azure node refresh action to prevent MissingResourceException at runtime. --- .../bundles/com/microsoft/azure/toolkit/operation.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Utils/azure-toolkit-ide-libs/azure-toolkit-ide-common-lib/src/main/resources/bundles/com/microsoft/azure/toolkit/operation.properties b/Utils/azure-toolkit-ide-libs/azure-toolkit-ide-common-lib/src/main/resources/bundles/com/microsoft/azure/toolkit/operation.properties index b32b9bd5f4..1ddda68a95 100644 --- a/Utils/azure-toolkit-ide-libs/azure-toolkit-ide-common-lib/src/main/resources/bundles/com/microsoft/azure/toolkit/operation.properties +++ b/Utils/azure-toolkit-ide-libs/azure-toolkit-ide-common-lib/src/main/resources/bundles/com/microsoft/azure/toolkit/operation.properties @@ -1012,4 +1012,5 @@ internal/guidance.create_resource_group=create Resource Group internal/guidance.open_container_app_in_browser=open Container App in browser user/guidance.open_container_app_log_streaming=open Container App log streaming -actions.common.deploy_to_azure=deploy to Azure \ No newline at end of file +actions.common.deploy_to_azure=deploy to Azure +user/appmod.refresh_migrate_node=Refresh Migrate to Azure Node From 0da87be63a90405eef32e0a9c79d147d749077b5 Mon Sep 17 00:00:00 2001 From: Miller Wang Date: Tue, 10 Mar 2026 08:01:46 +0800 Subject: [PATCH 08/19] fix: use reflection for Scala plugin SBT versions API compatibility The Scala plugin for IntelliJ 2026.1 changed the SBT versions API. Use reflection to try new API first, fall back to old API for cross-version compatibility. --- .../projects/SbtVersionOptionsPanel.java | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-hdinsight/src/main/java/com/microsoft/azure/hdinsight/projects/SbtVersionOptionsPanel.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-hdinsight/src/main/java/com/microsoft/azure/hdinsight/projects/SbtVersionOptionsPanel.java index 7ff14936b8..d186a228ce 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-hdinsight/src/main/java/com/microsoft/azure/hdinsight/projects/SbtVersionOptionsPanel.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-hdinsight/src/main/java/com/microsoft/azure/hdinsight/projects/SbtVersionOptionsPanel.java @@ -8,11 +8,12 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.ui.ComboBox; import com.microsoft.azure.hdinsight.common.logger.ILogger; -import org.jetbrains.plugins.scala.project.Versions; +import scala.collection.immutable.Seq; import scala.reflect.ClassTag; import javax.swing.*; import java.awt.*; +import java.lang.reflect.Method; public class SbtVersionOptionsPanel extends JPanel implements ILogger { private ComboBox sbtVersionComboBox; @@ -36,7 +37,35 @@ public SbtVersionOptionsPanel() { public void updateSbtVersions() { final String[][] versions = new String[1][1]; ProgressManager.getInstance().runProcess(() -> { - versions[0] = (String[]) Versions.SBT$.MODULE$.loadVersionsWithProgress(null).versions().toArray(ClassTag.apply(String.class)); + try { + // In newer Scala plugin versions, the API changed. Use reflection for cross-version compatibility. + // Old: Versions.SBT$.MODULE$.loadVersionsWithProgress(null).versions() -> Seq + // New: Versions.loadSbtVersions(false, null) -> Seq + final Class versionsClass = Class.forName("org.jetbrains.plugins.scala.project.Versions"); + try { + // Try new API first + final Method loadSbtVersionsMethod = versionsClass.getMethod("loadSbtVersions", boolean.class, com.intellij.openapi.progress.ProgressIndicator.class); + final Seq sbtVersions = (Seq) loadSbtVersionsMethod.invoke(null, false, null); + final int size = sbtVersions.size(); + final String[] result = new String[size]; + for (int i = 0; i < size; i++) { + result[i] = sbtVersions.apply(i).toString(); + } + versions[0] = result; + } catch (final NoSuchMethodException e) { + // Fallback to old API + final Class versionsSbtClass = Class.forName("org.jetbrains.plugins.scala.project.Versions$SBT$"); + final Object module = versionsSbtClass.getField("MODULE$").get(null); + final Method loadMethod = module.getClass().getMethod("loadVersionsWithProgress", com.intellij.openapi.progress.ProgressIndicator.class); + final Object loadedVersions = loadMethod.invoke(module, (Object) null); + final Method versionsMethod = loadedVersions.getClass().getMethod("versions"); + final Seq versionSeq = (Seq) versionsMethod.invoke(loadedVersions); + versions[0] = (String[]) versionSeq.toArray(ClassTag.apply(String.class)); + } + } catch (final Exception e) { + log().warn("Failed to get SBT versions from scala plugin.", e); + versions[0] = new String[0]; + } }, null); for (String version : versions[0]) { From 850834b9c853e61971cb51454f3a8ef9dae26914 Mon Sep 17 00:00:00 2001 From: Miller Wang Date: Tue, 10 Mar 2026 08:01:53 +0800 Subject: [PATCH 09/19] fix: adapt StreamingLogsConsoleView for ConsoleViewImpl.isDisposed() being private final In IntelliJ 261, ConsoleViewImpl.isDisposed() changed from protected/public to private final. Add a new public isDisposed() method (not an override) to maintain the existing public API for callers. --- .../streaminglog/StreamingLogsConsoleView.java | 12 ++++++++++++ .../azure-toolkit-for-intellij/build.gradle.kts | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib/src/main/java/com/microsoft/azure/toolkit/intellij/common/streaminglog/StreamingLogsConsoleView.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib/src/main/java/com/microsoft/azure/toolkit/intellij/common/streaminglog/StreamingLogsConsoleView.java index 3add2cecc3..673f62e0b6 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib/src/main/java/com/microsoft/azure/toolkit/intellij/common/streaminglog/StreamingLogsConsoleView.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib/src/main/java/com/microsoft/azure/toolkit/intellij/common/streaminglog/StreamingLogsConsoleView.java @@ -14,10 +14,12 @@ public class StreamingLogsConsoleView extends ConsoleViewImpl { private static final String SEPARATOR = System.getProperty("line.separator"); + private boolean isDisposed; private Disposable subscription; public StreamingLogsConsoleView(@NotNull Project project) { super(project, true); + this.isDisposed = false; this.setUpdateFoldingsEnabled(false); } @@ -41,6 +43,15 @@ public boolean isActive() { return subscription != null && !subscription.isDisposed(); } + /** + * Returns whether this console view has been disposed. + * Note: In IntelliJ 261+, ConsoleViewImpl.isDisposed() is private final, + * so this is NOT an override but a new public method for callers. + */ + public boolean isDisposed() { + return this.isDisposed; + } + private void printlnToConsole(String message, ConsoleViewContentType consoleViewContentType) { this.print(message + SEPARATOR, consoleViewContentType); } @@ -48,6 +59,7 @@ private void printlnToConsole(String message, ConsoleViewContentType consoleView @Override public void dispose() { super.dispose(); + this.isDisposed = true; closeStreamingLog(); } } diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts b/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts index 47bf01a535..0f1c245f8f 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts @@ -172,8 +172,14 @@ intellijPlatform { pluginVerification { ides { - create(IntelliJPlatformType.IntellijIdeaCommunity, properties("platformVersion").get()) + // IC (Community) no longer published since 253; use IU (Ultimate) for verification + create(IntelliJPlatformType.IntellijIdeaUltimate, properties("platformVersion").get()) } + // Suppress known structural warnings — plugin ID/name historically contain "intellij" + freeArgs = listOf( + "-mute", "TemplateWordInPluginId", + "-mute", "TemplateWordInPluginName" + ) } } From 245378aa16fa7a6cdd7b365a00b089768bb9c922 Mon Sep 17 00:00:00 2001 From: Miller Wang Date: Thu, 12 Mar 2026 07:38:36 +0800 Subject: [PATCH 10/19] chore: bump version to 3.98.0 and update changelog/whatsnew for IntelliJ 2026.1 EAP support --- CHANGELOG.md | 6 ++++++ .../src/main/resources/META-INF/plugin.xml | 6 +++++- .../src/main/resources/whatsnew.md | 5 +++++ .../src/main/resources/META-INF/plugin.xml | 12 +++++++++++- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fbb7c9825..a9c3a35648 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to "Azure Toolkit for IntelliJ IDEA" will be documented in this file. - [Change Log](#change-log) + - [3.98.0](#3980) - [3.97.3](#3973) - [3.97.2](#3972) - [3.97.1](#3971) @@ -123,6 +124,11 @@ All notable changes to "Azure Toolkit for IntelliJ IDEA" will be documented in t - [3.0.7](#307) - [3.0.6](#306) +## 3.98.0 +### Added +- Support IntelliJ IDEA 2026.1 EAP +- Upgrade Gradle to 9.0 and IntelliJ Platform Plugin to 2.12.0 + ## 3.97.3 - Rename GitHub Copilot app modernization to GitHub Copilot modernization. diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml index 7f8a2cb59c..b364cec240 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml @@ -2,7 +2,7 @@ xmlns:xi="http://www.w3.org/2001/XInclude"> com.microsoft.tooling.msservices.intellij.azure Azure Toolkit - 3.97.3 + 3.98.0 Microsoft @@ -18,6 +18,10 @@

    Azure

    +

    3.98.0

    +
      +
    • Support IntelliJ IDEA 2026.1 EAP
    • +

    You may get the full change log here

    ]]> diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md index ae84c9a5d8..a939c58e56 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md @@ -1,6 +1,11 @@ # What's new in Azure Toolkit for IntelliJ +## 3.98.0 +### Added +- Support IntelliJ IDEA 2026.1 EAP +- Upgrade Gradle to 9.0 and IntelliJ Platform Plugin to 2.12.0 + ## 3.97.3 - Rename GitHub Copilot app modernization to GitHub Copilot modernization. diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml b/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml index 7c96d7ff33..4fb16cd48d 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml @@ -2,7 +2,7 @@ xmlns:xi="http://www.w3.org/2001/XInclude"> com.microsoft.tooling.msservices.intellij.azure Azure Toolkit for IntelliJ - 3.97.3 + 3.98.0 Microsoft +

    3.98.0

    +

    Added

    +
      +
    • Support IntelliJ IDEA 2026.1 EAP
    • +

    3.97.3

    • Rename GitHub Copilot app modernization to GitHub Copilot modernization.
    +

    3.97.2

    +

    Fixed

    +
      +
    • Fixed a known issue
    • +

    You may get the full change log here

    ]]> From d7ce267746693f2db8c791f30684d5dcffa2bbbc Mon Sep 17 00:00:00 2001 From: Miller Wang Date: Thu, 12 Mar 2026 17:28:55 +0800 Subject: [PATCH 11/19] fix: address PR review - remove local paths, pipeline file, version bump; rename CLAUDE.md to AGENTS.md --- .azure-pipelines/build_and_sign.yml | 212 ------------------ CLAUDE.md => AGENTS.md | 0 CHANGELOG.md | 7 +- .../src/main/resources/META-INF/plugin.xml | 4 +- .../src/main/resources/whatsnew.md | 6 +- .../build.gradle.kts | 2 +- .../gradle.properties | 2 +- .../src/main/resources/META-INF/plugin.xml | 8 +- 8 files changed, 8 insertions(+), 233 deletions(-) delete mode 100644 .azure-pipelines/build_and_sign.yml rename CLAUDE.md => AGENTS.md (100%) diff --git a/.azure-pipelines/build_and_sign.yml b/.azure-pipelines/build_and_sign.yml deleted file mode 100644 index dcd24963ca..0000000000 --- a/.azure-pipelines/build_and_sign.yml +++ /dev/null @@ -1,212 +0,0 @@ -name: $(Date:yyyyMMdd).$(Rev:r) -variables: - - name: Codeql.Enabled - value: true - - name: IsStableBuild - value: ${{ or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release-')) }} - - name: IsNightlyBuild - value: ${{ and(eq(variables['Build.Reason'], 'Schedule'), eq(variables['Build.SourceBranch'], 'refs/heads/develop')) }} - - name: DoRealSign - value: ${{ or(eq(parameters.ForceRealSign, true), eq(variables['IsStableBuild'], true), eq(variables['IsNightlyBuild'], true)) }} - - name: DoProceedToRelease - value: ${{ or(eq(variables['DoRealSign'], true), eq(parameters.ForceTestSignRelease, true)) }} - - name: RELEASE_CHANNEL - ${{ if or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release-')) }}: - value: stable - ${{ else }}: - value: nightly - - name: SIGNTYPE - ${{ if eq(variables['DoRealSign'], true) }}: - value: real - ${{ else }}: - value: test - -parameters: - - name: ForceRealSign - displayName: "Force usage of real sign (PME PoP needed)" - type: boolean - default: false - - name: ForceTestSignRelease - displayName: "Force release on test sign (for test ONLY)" - type: boolean - default: false - -resources: - repositories: - - repository: self - type: git - ref: refs/heads/main - - repository: 1esPipelines - type: git - name: 1ESPipelineTemplates/1ESPipelineTemplates - ref: refs/tags/release - -trigger: - branches: - include: - - main - - develop - - release-* - -pr: - - main - - develop - - release-* - -schedules: - - cron: "0 22 * * 0-4" # 6:00 Mon-Fri UTC+8 - displayName: "Nightly build" - branches: - include: - - develop - always: true - -extends: - template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines - parameters: - featureFlags: - disableNetworkIsolation: true - pool: - name: VSEngSS-MicroBuild2022-1ES - stages: - - stage: Build_Plugin - displayName: "Build Plugin" - jobs: - - job: Build_and_Sign - displayName: Build and Sign Plugin - timeoutInMinutes: 360 - templateContext: - outputs: - - output: pipelineArtifact - artifactName: plugin - targetPath: $(build.artifactstagingdirectory)/plugin - displayName: "Publish Artifact: plugin" - steps: - - checkout: self - clean: true - fetchTags: false - - task: PowerShell@2 - displayName: Install JDK 21 - inputs: - targetType: inline - script: | - # Download Adoptium/Temurin JDK 21.0.8 - Write-Host "Downloading Java 21.0.8..." - $source = "https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.8%2B9/OpenJDK21U-jdk_x64_windows_hotspot_21.0.8_9.zip" - $destination = "$(build.sourcesdirectory)\jdk21_x64_windows.zip" - Invoke-WebRequest -Uri $source -OutFile $destination - - task: JavaToolInstaller@0 - displayName: "Use Java 21" - inputs: - versionSpec: 21 - jdkArchitectureOption: x64 - jdkSourceOption: LocalDirectory - jdkFile: '$(build.sourcesdirectory)\jdk21_x64_windows.zip' - jdkDestinationDirectory: "$(agent.toolsDirectory)/jdk21" - - task: UseNode@1 - inputs: - version: "22.x" - - task: NuGetAuthenticate@1 - displayName: "🔩 NuGet Authenticate" - - task: MicroBuildSigningPlugin@4 - displayName: "Add MicroBuild Signing Plugin" - inputs: - ${{if eq(variables.DoRealSign, true) }}: - signType: "real" - ConnectedPMEServiceName: "40012d40-9ded-4f75-8476-d60758200346" - ${{ else }}: - signType: "test" - feedSource: "https://mseng.pkgs.visualstudio.com/DefaultCollection/_packaging/MicroBuildToolset/nuget/v3/index.json" - env: - MicroBuildOutputFolderOverride: "$(Agent.TempDirectory)" - - task: PowerShell@2 - displayName: Build Plugin - inputs: - targetType: inline - script: | - mvn -v - # ./gradlew buildUtils || exit -1 - mvn clean install -f ./Utils/pom.xml -T 1C "-Dcheckstyle.skip=true" "-Dmaven.test.skip=true" "-Dmaven.javadoc.skip=true" - mvn clean -f ./Utils/pom.xml - cd PluginsAndFeatures/azure-toolkit-for-intellij - ./gradlew clean buildPlugin -s "-Papplicationinsights.key=$(INTELLIJ_KEY)" "-PneedPatchVersion=false" "-Psources=false" "-Porg.gradle.configureondemand=false" "-Porg.gradle.daemon=false" "-Porg.gradle.unsafe.configuration-cache=false" "-Porg.gradle.caching=false" - env: - USE_STABLE_VERSION: $(IsStableBuild) - - task: PowerShell@2 - displayName: Unpackage - inputs: - targetType: inline - script: | - Write-Host "Creating artifacts directory..." - New-Item -ItemType Directory -Path ".\artifacts\intellij\" -Force - Write-Host "Finding plugin zip file..." - $zipFile = Get-ChildItem ".\PluginsAndFeatures\azure-toolkit-for-intellij\build\distributions\*.zip" | Select-Object -First 1 - Write-Host "Found: $($zipFile.FullName)" - Write-Host "Copying to artifacts..." - Copy-Item $zipFile.FullName ".\artifacts\intellij\azure-intellij.zip" - Write-Host "Extracting archive..." - Expand-Archive -Path ".\artifacts\intellij\azure-intellij.zip" -DestinationPath ".\artifacts\intellij\folder" -Force - Write-Host "Cleaning up temporary zip file..." - Remove-Item ".\artifacts\intellij\azure-intellij.zip" - Write-Host "Unpackaging completed successfully" - - task: PowerShell@2 - displayName: Sign jars - timeoutInMinutes: 240 - inputs: - targetType: inline - script: | - Write-Host "Searching for JAR files to sign..." - $files = Get-ChildItem -Path . -Include "azure-intellij-*.jar", "azure-toolkit-for-intellij*.jar", "azure-toolkit-ide-*.jar", "azuretools-core.jar", "azure-explorer-common.jar", "hdinsight-node-common.jar" -Recurse -File - Write-Host "Found $($files.Count) JAR file(s) to sign" - $counter = 0 - foreach ($file in $files) { - $counter++ - Write-Host "[$counter/$($files.Count)] Signing: $($file.Name) with sign type: $(SIGNTYPE)" - dotnet "$env:MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$($file.FullName)" /certs:100010171 /signType:$(SIGNTYPE) - Write-Host " ✓ Signed successfully" - } - Write-Host "All JAR files signed successfully" - workingDirectory: 'artifacts/intellij/folder/azure-intellij/lib' - - task: CmdLine@2 - displayName: Repackage - inputs: - script: | - echo Starting repackaging... - cd artifacts\intellij\folder - echo Creating final zip archive: azure-intellij-$(Build.BuildNumber).zip - tar -a -c -f ..\..\azure-intellij-$(Build.BuildNumber).zip * - echo Repackaging completed successfully - - task: CopyFiles@2 - displayName: "Copy Files to: $(build.artifactstagingdirectory)" - inputs: - SourceFolder: $(system.defaultworkingdirectory)/artifacts - Contents: "*.zip" - TargetFolder: $(build.artifactstagingdirectory)/plugin - - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 - displayName: "Manifest Generator " - inputs: - BuildDropPath: $(build.artifactstagingdirectory)/plugin - - stage: Release_Plugin - condition: ${{ variables.DoProceedToRelease }} - displayName: Release Plugin to Marketplace - dependsOn: Build_Plugin - jobs: - - deployment: releasePlugin - templateContext: - type: releaseJob - isProduction: true - inputs: - - input: pipelineArtifact - artifactName: "plugin" - targetPath: "$(Pipeline.Workspace)/plugin" - environment: azure-intellij-plugin-release - strategy: - runOnce: - deploy: - steps: - - task: PowerShell@2 - displayName: Release - inputs: - targetType: inline - script: | - curl.exe -i --header "Authorization: Bearer ${env:RELEASE_TOKEN}" -F pluginId=28791 -F "file=@$(Pipeline.Workspace)/plugin/azure-intellij-$(Build.BuildNumber).zip" -F channel=$(RELEASE_CHANNEL) https://plugins.jetbrains.com/plugin/uploadPlugin diff --git a/CLAUDE.md b/AGENTS.md similarity index 100% rename from CLAUDE.md rename to AGENTS.md diff --git a/CHANGELOG.md b/CHANGELOG.md index a9c3a35648..7b989d29d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,6 @@ All notable changes to "Azure Toolkit for IntelliJ IDEA" will be documented in this file. - [Change Log](#change-log) - - [3.98.0](#3980) - [3.97.3](#3973) - [3.97.2](#3972) - [3.97.1](#3971) @@ -124,12 +123,8 @@ All notable changes to "Azure Toolkit for IntelliJ IDEA" will be documented in t - [3.0.7](#307) - [3.0.6](#306) -## 3.98.0 -### Added -- Support IntelliJ IDEA 2026.1 EAP -- Upgrade Gradle to 9.0 and IntelliJ Platform Plugin to 2.12.0 - ## 3.97.3 +- Support IntelliJ IDEA 2026.1 EAP - Rename GitHub Copilot app modernization to GitHub Copilot modernization. ## 3.97.2 diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml index b364cec240..c902b2ceb7 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml @@ -2,7 +2,7 @@ xmlns:xi="http://www.w3.org/2001/XInclude"> com.microsoft.tooling.msservices.intellij.azure Azure Toolkit - 3.98.0 + 3.97.3 Microsoft @@ -18,7 +18,7 @@

    Azure

    -

    3.98.0

    +

    3.97.3

    • Support IntelliJ IDEA 2026.1 EAP
    diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md index a939c58e56..c63c764e8c 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md @@ -1,12 +1,8 @@ # What's new in Azure Toolkit for IntelliJ -## 3.98.0 -### Added -- Support IntelliJ IDEA 2026.1 EAP -- Upgrade Gradle to 9.0 and IntelliJ Platform Plugin to 2.12.0 - ## 3.97.3 +- Support IntelliJ IDEA 2026.1 EAP - Rename GitHub Copilot app modernization to GitHub Copilot modernization. ## 3.97.2 diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts b/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts index 0f1c245f8f..437d80e923 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/build.gradle.kts @@ -64,7 +64,7 @@ allprojects { useInstaller = false } // JBR 25 required to run IntelliJ 2026.1 (PathClassLoader is JBR-only) - jetbrainsRuntimeLocal("C:/Users/wangmi/.jdks/jbr-25/jbr_jcef-25.0.2-windows-x64-b329.72") + jetbrainsRuntime() // MavenId/MavenCoordinate classes moved from maven plugin to repository-search plugin in 261 bundledPlugin("org.jetbrains.idea.reposearch") // Test framework classes moved to separate modules in 261 diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties index e116225a74..293b1e0118 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties @@ -1,4 +1,4 @@ -pluginVersion=3.98.0 +pluginVersion=3.97.3 intellijDisplayVersion=2026.1 intellij_version=261-EAP-SNAPSHOT platformVersion=261-EAP-SNAPSHOT diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml b/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml index 4fb16cd48d..95445b9a1e 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml @@ -2,7 +2,7 @@ xmlns:xi="http://www.w3.org/2001/XInclude"> com.microsoft.tooling.msservices.intellij.azure Azure Toolkit for IntelliJ - 3.98.0 + 3.97.3 Microsoft -

    3.98.0

    -

    Added

    -
      -
    • Support IntelliJ IDEA 2026.1 EAP
    • -

    3.97.3

      +
    • Support IntelliJ IDEA 2026.1 EAP
    • Rename GitHub Copilot app modernization to GitHub Copilot modernization.

    3.97.2

    From 0cef6fc7c0855d223d2728c0fa1e29986b4da5fb Mon Sep 17 00:00:00 2001 From: Miller Wang Date: Wed, 18 Mar 2026 07:10:01 +0800 Subject: [PATCH 12/19] fix(ui): override setAction(javax.swing.Action) in AzureActionButton for New UI compatibility In IntelliJ 2026.1 EAP's New UI, the form runtime or DarculaButtonUI may call AbstractButton.setAction(javax.swing.Action) which triggers configurePropertiesFromAction() and clears the button text/icon set by the GUI form instrumentation. Override this method as a no-op to preserve button text and icon values, fixing blank toolbar buttons in Properties views (e.g. WebApp, Function App, Redis, Spring Cloud, KeyVault, Database, etc.). Fixes: https://dev.azure.com/mseng/VSJava/_workitems/edit/2367324 --- .../intellij/common/AzureActionButton.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib/src/main/java/com/microsoft/azure/toolkit/intellij/common/AzureActionButton.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib/src/main/java/com/microsoft/azure/toolkit/intellij/common/AzureActionButton.java index 96e2afda28..18c1026b9c 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib/src/main/java/com/microsoft/azure/toolkit/intellij/common/AzureActionButton.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib/src/main/java/com/microsoft/azure/toolkit/intellij/common/AzureActionButton.java @@ -20,11 +20,20 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.swing.*; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Objects; import java.util.Optional; +/** + * A JButton subclass that bridges Azure Toolkit {@link Action} with Swing buttons. + *

    + * Overrides {@link AbstractButton#setAction(javax.swing.Action)} to prevent the inherited + * Swing method from clearing the button text/icon when the IntelliJ form runtime or + * Look-and-Feel calls it unexpectedly. This ensures compatibility with IntelliJ's New UI + * (2026.1+) where DarculaButtonUI may interact with the Swing Action property. + */ public class AzureActionButton extends JButton { public static final DataKey ACTION_EVENT_KEY = DataKey.create("AzureActionButton.actionEvent"); private final ActionListener listener = this::onActionPerformed; @@ -44,6 +53,25 @@ public AzureActionButton(@Nonnull final Action action) { this.registerActionListener(); } + /** + * Override the inherited {@link AbstractButton#setAction(javax.swing.Action)} to prevent + * the Swing Action mechanism from clearing button text and icon. In IntelliJ's New UI, + * the form runtime or LAF may call this method, which by default calls + * {@code configurePropertiesFromAction()} and resets all button properties (text, icon, + * tooltip, enabled) from the javax.swing.Action — wiping out values set by the form + * instrumentation or programmatic code. + *

    + * This no-op override preserves the button's text and icon as set by the GUI form + * or by calling {@link #setText(String)} / {@link #setIcon(Icon)} directly. + */ + @Override + public void setAction(javax.swing.Action a) { + // Intentionally do NOT call super.setAction(a). + // The Swing default would call configurePropertiesFromAction() which clears + // text/icon/tooltip if the javax.swing.Action has no corresponding properties. + // Our buttons get their text from the .form file and icons from Java code. + } + public void setAction(@Nonnull final Action.Id actionId) { setAction(actionId, null); } From 78bb2efab299d3bf5ed246f311621f97ef0cb3df Mon Sep 17 00:00:00 2001 From: Jimmy Fang Date: Wed, 1 Apr 2026 16:51:16 +0800 Subject: [PATCH 13/19] update java upgrade prompt to use latest LTS version instead of specific version --- .../intellij/appmod/javaupgrade/utils/Constants.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/utils/Constants.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/utils/Constants.java index 78bca711e2..795796132f 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/utils/Constants.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/utils/Constants.java @@ -2,8 +2,8 @@ public class Constants { public static final String UPGRADE_JAVA_AND_FRAMEWORK_PROMPT = "Upgrade java runtime and java framework dependencies of this project to the latest LTS version using java upgrade tools by invoking #generate_upgrade_plan"; - public static final String UPGRADE_JAVA_VERSION_PROMPT = "Upgrade Java runtime from version %s to Java %s (LTS) using java upgrade tools by invoking #generate_upgrade_plan"; - public static final String UPGRADE_JAVA_FRAMEWORK_PROMPT = "Upgrade %s from version %s to %s using java upgrade tools by invoking #generate_upgrade_plan"; + public static final String UPGRADE_JAVA_VERSION_PROMPT = "Upgrade Java runtime from version %s to the latest LTS version using java upgrade tools by invoking #generate_upgrade_plan"; + public static final String UPGRADE_JAVA_FRAMEWORK_PROMPT = "Upgrade %s from version %s to the latest LTS version using java upgrade tools by invoking #generate_upgrade_pla"; public static final String SCAN_AND_RESOLVE_CVES_PROMPT = "run CVE scan for this project using java upgrade tools by invoking #validate_cves_for_java"; public static final String UPGRADE_JDK_WITH_COPILOT_DISPLAY_NAME = "Upgrade JDK with Copilot"; public static final String UPGRADE_SPRING_BOOT_WITH_COPILOT_DISPLAY_NAME = "Upgrade Spring Boot with Copilot"; @@ -12,5 +12,5 @@ public class Constants { public static final String SCAN_AND_RESOLVE_CVES_WITH_COPILOT_DISPLAY_NAME = "Scan and Resolve CVEs with Copilot"; public static final String FIX_VULNERABLE_DEPENDENCY_WITH_COPILOT_PROMPT = "Fix the vulnerable dependency %s by using #validate_cves_for_java"; public static final String FIX_VULNERABLE_DEPENDENCY_WITH_COPILOT_DISPLAY_NAME = "Fix the vulnerable dependency with Copilot"; - public static final String ISSUE_DISPLAY_NAME = "Your project uses %s %s. Consider upgrading to %s %s or higher for better performance and support"; + public static final String ISSUE_DISPLAY_NAME = "Your project uses %s %s. Consider upgrading to %s to the latest LTS version using java upgrade tools by invoking #generate_upgrade_plan"; } From 900af79379f0ee7bb18efe9fc65f89c6ebb5ae46 Mon Sep 17 00:00:00 2001 From: Jimmy Fang Date: Wed, 1 Apr 2026 17:11:46 +0800 Subject: [PATCH 14/19] use new appmod tool name --- .../intellij/appmod/javaupgrade/utils/Constants.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/utils/Constants.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/utils/Constants.java index 795796132f..472579eee0 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/utils/Constants.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/utils/Constants.java @@ -1,16 +1,16 @@ package com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.utils; public class Constants { - public static final String UPGRADE_JAVA_AND_FRAMEWORK_PROMPT = "Upgrade java runtime and java framework dependencies of this project to the latest LTS version using java upgrade tools by invoking #generate_upgrade_plan"; - public static final String UPGRADE_JAVA_VERSION_PROMPT = "Upgrade Java runtime from version %s to the latest LTS version using java upgrade tools by invoking #generate_upgrade_plan"; - public static final String UPGRADE_JAVA_FRAMEWORK_PROMPT = "Upgrade %s from version %s to the latest LTS version using java upgrade tools by invoking #generate_upgrade_pla"; + public static final String UPGRADE_JAVA_AND_FRAMEWORK_PROMPT = "Upgrade java runtime and java framework dependencies of this project to the latest LTS version using java upgrade tools by invoking #appmod-generate-upgrade-plan"; + public static final String UPGRADE_JAVA_VERSION_PROMPT = "Upgrade Java runtime from version %s to the latest LTS version using java upgrade tools by invoking #appmod-generate-upgrade-plan"; + public static final String UPGRADE_JAVA_FRAMEWORK_PROMPT = "Upgrade %s from version %s to the latest LTS version using java upgrade tools by invoking #appmod-generate-upgrade-plan"; public static final String SCAN_AND_RESOLVE_CVES_PROMPT = "run CVE scan for this project using java upgrade tools by invoking #validate_cves_for_java"; public static final String UPGRADE_JDK_WITH_COPILOT_DISPLAY_NAME = "Upgrade JDK with Copilot"; public static final String UPGRADE_SPRING_BOOT_WITH_COPILOT_DISPLAY_NAME = "Upgrade Spring Boot with Copilot"; public static final String UPGRADE_SPRING_FRAMEWORK_WITH_COPILOT_DISPLAY_NAME = "Upgrade Spring Framework with Copilot"; public static final String UPGRADE_SPRING_SECURITY_WITH_COPILOT_DISPLAY_NAME = "Upgrade Spring Security with Copilot"; public static final String SCAN_AND_RESOLVE_CVES_WITH_COPILOT_DISPLAY_NAME = "Scan and Resolve CVEs with Copilot"; - public static final String FIX_VULNERABLE_DEPENDENCY_WITH_COPILOT_PROMPT = "Fix the vulnerable dependency %s by using #validate_cves_for_java"; + public static final String FIX_VULNERABLE_DEPENDENCY_WITH_COPILOT_PROMPT = "Fix the vulnerable dependency %s by using #appmod-validate-cves-for-java"; public static final String FIX_VULNERABLE_DEPENDENCY_WITH_COPILOT_DISPLAY_NAME = "Fix the vulnerable dependency with Copilot"; - public static final String ISSUE_DISPLAY_NAME = "Your project uses %s %s. Consider upgrading to %s to the latest LTS version using java upgrade tools by invoking #generate_upgrade_plan"; + public static final String ISSUE_DISPLAY_NAME = "Your project uses %s %s. Consider upgrading to %s to the latest LTS version using java upgrade tools by invoking #appmod-generate-upgrade-plan"; } From ca8f03cf8671cc6d68f9c369d5d4f6103b3e9d11 Mon Sep 17 00:00:00 2001 From: Jimmy Fang Date: Wed, 8 Apr 2026 19:20:07 +0800 Subject: [PATCH 15/19] prompt update --- .../toolkit/intellij/appmod/javaupgrade/utils/Constants.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/utils/Constants.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/utils/Constants.java index 472579eee0..194d0e38e4 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/utils/Constants.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/utils/Constants.java @@ -12,5 +12,5 @@ public class Constants { public static final String SCAN_AND_RESOLVE_CVES_WITH_COPILOT_DISPLAY_NAME = "Scan and Resolve CVEs with Copilot"; public static final String FIX_VULNERABLE_DEPENDENCY_WITH_COPILOT_PROMPT = "Fix the vulnerable dependency %s by using #appmod-validate-cves-for-java"; public static final String FIX_VULNERABLE_DEPENDENCY_WITH_COPILOT_DISPLAY_NAME = "Fix the vulnerable dependency with Copilot"; - public static final String ISSUE_DISPLAY_NAME = "Your project uses %s %s. Consider upgrading to %s to the latest LTS version using java upgrade tools by invoking #appmod-generate-upgrade-plan"; + public static final String ISSUE_DISPLAY_NAME = "Your project uses %s %s. Consider upgrading to %s to the latest LTS version for better performance and support"; } From a8775510b288ae8a0e5f7e46408e5290886b2fa5 Mon Sep 17 00:00:00 2001 From: Jimmy Fang Date: Wed, 8 Apr 2026 21:55:16 +0800 Subject: [PATCH 16/19] bump to 3.97.4 --- CHANGELOG.md | 4 ++++ PluginsAndFeatures/AddLibrary/AzureLibraries/pom.xml | 4 ++-- .../azure-intellij-plugin-base/gradle.properties | 2 +- .../src/main/resources/META-INF/plugin.xml | 2 +- .../src/main/resources/whatsnew.md | 3 +++ .../azure-toolkit-for-intellij/gradle.properties | 2 +- .../src/main/resources/META-INF/plugin.xml | 5 +++-- Utils/pom.xml | 2 +- 8 files changed, 16 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b989d29d4..65b565d67f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to "Azure Toolkit for IntelliJ IDEA" will be documented in this file. - [Change Log](#change-log) + - [3.97.4](#3974) - [3.97.3](#3973) - [3.97.2](#3972) - [3.97.1](#3971) @@ -123,6 +124,9 @@ All notable changes to "Azure Toolkit for IntelliJ IDEA" will be documented in t - [3.0.7](#307) - [3.0.6](#306) +## 3.97.4 +- Update prompts and tool references of GitHub Copilot modernization. + ## 3.97.3 - Support IntelliJ IDEA 2026.1 EAP - Rename GitHub Copilot app modernization to GitHub Copilot modernization. diff --git a/PluginsAndFeatures/AddLibrary/AzureLibraries/pom.xml b/PluginsAndFeatures/AddLibrary/AzureLibraries/pom.xml index f1466612f8..d0991d6135 100644 --- a/PluginsAndFeatures/AddLibrary/AzureLibraries/pom.xml +++ b/PluginsAndFeatures/AddLibrary/AzureLibraries/pom.xml @@ -27,7 +27,7 @@ com.microsoft.azuretools utils - 3.97.3 + 3.97.4 com.microsoft.azuretools com.microsoft.azuretools.sdk.lib @@ -39,7 +39,7 @@ - 3.97.3 + 3.97.4 3.32.0.qualifier 0.52.2 diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/gradle.properties b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/gradle.properties index de040562a4..80e4bbdac1 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/gradle.properties +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/gradle.properties @@ -1,4 +1,4 @@ -pluginVersion=3.97.3 +pluginVersion=3.97.4 intellijDisplayVersion=2024.2 intellij_version=IU-242-EAP-SNAPSHOT scala_plugin=org.intellij.scala:2024.2.5 diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml index c902b2ceb7..72e57a2b4e 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml @@ -2,7 +2,7 @@ xmlns:xi="http://www.w3.org/2001/XInclude"> com.microsoft.tooling.msservices.intellij.azure Azure Toolkit - 3.97.3 + 3.97.4 Microsoft diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md index c63c764e8c..2060cddf61 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md @@ -1,6 +1,9 @@ # What's new in Azure Toolkit for IntelliJ +## 3.97.4 +- Update prompts and tool references of GitHub Copilot modernization. + ## 3.97.3 - Support IntelliJ IDEA 2026.1 EAP - Rename GitHub Copilot app modernization to GitHub Copilot modernization. diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties index 293b1e0118..711afcb2b1 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties @@ -1,4 +1,4 @@ -pluginVersion=3.97.3 +pluginVersion=3.97.4 intellijDisplayVersion=2026.1 intellij_version=261-EAP-SNAPSHOT platformVersion=261-EAP-SNAPSHOT diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml b/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml index 95445b9a1e..88f170a6dd 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml @@ -2,7 +2,7 @@ xmlns:xi="http://www.w3.org/2001/XInclude"> com.microsoft.tooling.msservices.intellij.azure Azure Toolkit for IntelliJ - 3.97.3 + 3.97.4 Microsoft -

    3.97.3

    +

    3.97.4

    • Support IntelliJ IDEA 2026.1 EAP
    • Rename GitHub Copilot app modernization to GitHub Copilot modernization.
    • +
    • Update prompts and tool references of GitHub Copilot modernization.

    3.97.2

    Fixed

    diff --git a/Utils/pom.xml b/Utils/pom.xml index 53dcff7c2e..bc931bb0eb 100644 --- a/Utils/pom.xml +++ b/Utils/pom.xml @@ -27,7 +27,7 @@ 4.0.0 com.microsoft.azuretools utils - 3.97.3 + 3.97.4 pom ${project.artifactId}-${project.version} From 3f4d465b86eaef493cfa053e5b35b8b5390278bb Mon Sep 17 00:00:00 2001 From: Jimmy Fang Date: Wed, 8 Apr 2026 22:01:24 +0800 Subject: [PATCH 17/19] Revert "bump to 3.97.4" This reverts commit a8775510b288ae8a0e5f7e46408e5290886b2fa5. --- CHANGELOG.md | 4 ---- PluginsAndFeatures/AddLibrary/AzureLibraries/pom.xml | 4 ++-- .../azure-intellij-plugin-base/gradle.properties | 2 +- .../src/main/resources/META-INF/plugin.xml | 2 +- .../src/main/resources/whatsnew.md | 3 --- .../azure-toolkit-for-intellij/gradle.properties | 2 +- .../src/main/resources/META-INF/plugin.xml | 5 ++--- Utils/pom.xml | 2 +- 8 files changed, 8 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65b565d67f..7b989d29d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,6 @@ All notable changes to "Azure Toolkit for IntelliJ IDEA" will be documented in this file. - [Change Log](#change-log) - - [3.97.4](#3974) - [3.97.3](#3973) - [3.97.2](#3972) - [3.97.1](#3971) @@ -124,9 +123,6 @@ All notable changes to "Azure Toolkit for IntelliJ IDEA" will be documented in t - [3.0.7](#307) - [3.0.6](#306) -## 3.97.4 -- Update prompts and tool references of GitHub Copilot modernization. - ## 3.97.3 - Support IntelliJ IDEA 2026.1 EAP - Rename GitHub Copilot app modernization to GitHub Copilot modernization. diff --git a/PluginsAndFeatures/AddLibrary/AzureLibraries/pom.xml b/PluginsAndFeatures/AddLibrary/AzureLibraries/pom.xml index d0991d6135..f1466612f8 100644 --- a/PluginsAndFeatures/AddLibrary/AzureLibraries/pom.xml +++ b/PluginsAndFeatures/AddLibrary/AzureLibraries/pom.xml @@ -27,7 +27,7 @@ com.microsoft.azuretools utils - 3.97.4 + 3.97.3 com.microsoft.azuretools com.microsoft.azuretools.sdk.lib @@ -39,7 +39,7 @@ - 3.97.4 + 3.97.3 3.32.0.qualifier 0.52.2 diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/gradle.properties b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/gradle.properties index 80e4bbdac1..de040562a4 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/gradle.properties +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/gradle.properties @@ -1,4 +1,4 @@ -pluginVersion=3.97.4 +pluginVersion=3.97.3 intellijDisplayVersion=2024.2 intellij_version=IU-242-EAP-SNAPSHOT scala_plugin=org.intellij.scala:2024.2.5 diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml index 72e57a2b4e..c902b2ceb7 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml @@ -2,7 +2,7 @@ xmlns:xi="http://www.w3.org/2001/XInclude"> com.microsoft.tooling.msservices.intellij.azure Azure Toolkit - 3.97.4 + 3.97.3 Microsoft diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md index 2060cddf61..c63c764e8c 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md @@ -1,9 +1,6 @@ # What's new in Azure Toolkit for IntelliJ -## 3.97.4 -- Update prompts and tool references of GitHub Copilot modernization. - ## 3.97.3 - Support IntelliJ IDEA 2026.1 EAP - Rename GitHub Copilot app modernization to GitHub Copilot modernization. diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties index 711afcb2b1..293b1e0118 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties @@ -1,4 +1,4 @@ -pluginVersion=3.97.4 +pluginVersion=3.97.3 intellijDisplayVersion=2026.1 intellij_version=261-EAP-SNAPSHOT platformVersion=261-EAP-SNAPSHOT diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml b/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml index 88f170a6dd..95445b9a1e 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml @@ -2,7 +2,7 @@ xmlns:xi="http://www.w3.org/2001/XInclude"> com.microsoft.tooling.msservices.intellij.azure Azure Toolkit for IntelliJ - 3.97.4 + 3.97.3 Microsoft -

    3.97.4

    +

    3.97.3

    • Support IntelliJ IDEA 2026.1 EAP
    • Rename GitHub Copilot app modernization to GitHub Copilot modernization.
    • -
    • Update prompts and tool references of GitHub Copilot modernization.

    3.97.2

    Fixed

    diff --git a/Utils/pom.xml b/Utils/pom.xml index bc931bb0eb..53dcff7c2e 100644 --- a/Utils/pom.xml +++ b/Utils/pom.xml @@ -27,7 +27,7 @@ 4.0.0 com.microsoft.azuretools utils - 3.97.4 + 3.97.3 pom ${project.artifactId}-${project.version} From a3dd38fb66bbbcc285755b0ec010c5d59b7464d8 Mon Sep 17 00:00:00 2001 From: Jimmy Fang Date: Wed, 8 Apr 2026 22:05:45 +0800 Subject: [PATCH 18/19] bump to 3.97.4 --- CHANGELOG.md | 4 ++++ PluginsAndFeatures/AddLibrary/AzureLibraries/pom.xml | 4 ++-- .../azure-intellij-plugin-base/gradle.properties | 2 +- .../src/main/resources/META-INF/plugin.xml | 2 +- .../src/main/resources/whatsnew.md | 3 +++ .../azure-toolkit-for-intellij/gradle.properties | 2 +- .../src/main/resources/META-INF/plugin.xml | 6 +++++- Utils/pom.xml | 2 +- 8 files changed, 18 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b989d29d4..65b565d67f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to "Azure Toolkit for IntelliJ IDEA" will be documented in this file. - [Change Log](#change-log) + - [3.97.4](#3974) - [3.97.3](#3973) - [3.97.2](#3972) - [3.97.1](#3971) @@ -123,6 +124,9 @@ All notable changes to "Azure Toolkit for IntelliJ IDEA" will be documented in t - [3.0.7](#307) - [3.0.6](#306) +## 3.97.4 +- Update prompts and tool references of GitHub Copilot modernization. + ## 3.97.3 - Support IntelliJ IDEA 2026.1 EAP - Rename GitHub Copilot app modernization to GitHub Copilot modernization. diff --git a/PluginsAndFeatures/AddLibrary/AzureLibraries/pom.xml b/PluginsAndFeatures/AddLibrary/AzureLibraries/pom.xml index f1466612f8..d0991d6135 100644 --- a/PluginsAndFeatures/AddLibrary/AzureLibraries/pom.xml +++ b/PluginsAndFeatures/AddLibrary/AzureLibraries/pom.xml @@ -27,7 +27,7 @@ com.microsoft.azuretools utils - 3.97.3 + 3.97.4 com.microsoft.azuretools com.microsoft.azuretools.sdk.lib @@ -39,7 +39,7 @@ - 3.97.3 + 3.97.4 3.32.0.qualifier 0.52.2 diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/gradle.properties b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/gradle.properties index de040562a4..80e4bbdac1 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/gradle.properties +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/gradle.properties @@ -1,4 +1,4 @@ -pluginVersion=3.97.3 +pluginVersion=3.97.4 intellijDisplayVersion=2024.2 intellij_version=IU-242-EAP-SNAPSHOT scala_plugin=org.intellij.scala:2024.2.5 diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml index c902b2ceb7..72e57a2b4e 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-base/src/main/resources/META-INF/plugin.xml @@ -2,7 +2,7 @@ xmlns:xi="http://www.w3.org/2001/XInclude"> com.microsoft.tooling.msservices.intellij.azure Azure Toolkit - 3.97.3 + 3.97.4 Microsoft diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md index c63c764e8c..2060cddf61 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib-java/src/main/resources/whatsnew.md @@ -1,6 +1,9 @@ # What's new in Azure Toolkit for IntelliJ +## 3.97.4 +- Update prompts and tool references of GitHub Copilot modernization. + ## 3.97.3 - Support IntelliJ IDEA 2026.1 EAP - Rename GitHub Copilot app modernization to GitHub Copilot modernization. diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties index 293b1e0118..711afcb2b1 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties @@ -1,4 +1,4 @@ -pluginVersion=3.97.3 +pluginVersion=3.97.4 intellijDisplayVersion=2026.1 intellij_version=261-EAP-SNAPSHOT platformVersion=261-EAP-SNAPSHOT diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml b/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml index 95445b9a1e..75a5083cba 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/src/main/resources/META-INF/plugin.xml @@ -2,7 +2,7 @@ xmlns:xi="http://www.w3.org/2001/XInclude"> com.microsoft.tooling.msservices.intellij.azure Azure Toolkit for IntelliJ - 3.97.3 + 3.97.4 Microsoft +

    3.97.4

    +
      +
    • Update prompts and tool references of GitHub Copilot modernization.
    • +

    3.97.3

    • Support IntelliJ IDEA 2026.1 EAP
    • diff --git a/Utils/pom.xml b/Utils/pom.xml index 53dcff7c2e..bc931bb0eb 100644 --- a/Utils/pom.xml +++ b/Utils/pom.xml @@ -27,7 +27,7 @@ 4.0.0 com.microsoft.azuretools utils - 3.97.3 + 3.97.4 pom ${project.artifactId}-${project.version} From 309434802f5629f5fe498f681a1738a442124c81 Mon Sep 17 00:00:00 2001 From: Miller Wang Date: Fri, 17 Apr 2026 08:53:38 +0800 Subject: [PATCH 19/19] fix: restore IntelliJ 2026.1 EAP version for release-v3.97.5.next --- .../azure-toolkit-for-intellij/gradle.properties | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties index fb4c75b819..4aba9897ae 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/gradle.properties @@ -1,12 +1,12 @@ pluginVersion=3.97.5 -intellijDisplayVersion=2025.3 -intellij_version=253-EAP-SNAPSHOT -platformVersion=253-EAP-SNAPSHOT +intellijDisplayVersion=2026.1 +intellij_version=261-EAP-SNAPSHOT +platformVersion=261-EAP-SNAPSHOT # Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html -pluginSinceBuild=253 -pluginUntilBuild=253.* +pluginSinceBuild=261 +pluginUntilBuild=261.* # Example: platformPlugins = com.jetbrains.php:203.4449.22, org.intellij.scala:2023.3.27@EAP -platformPlugins=org.intellij.scala:2025.3.12 +platformPlugins=org.intellij.scala:2026.1.8 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IU needPatchVersion=true @@ -22,7 +22,7 @@ platformDownloadSources=true # Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib kotlin.stdlib.default.dependency=false # Gradle Releases -> https://github.com/gradle/gradle/releases -gradleVersion=8.14.1 +gradleVersion=9.0 # Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html org.gradle.configuration-cache=true org.gradle.configuration-cache.problems=warn @@ -36,4 +36,3 @@ org.gradle.jvmargs='-Duser.language=en' org.jetbrains.intellij.platform.buildFeature.useBinaryReleases=false -