diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2e586d9..1ac59ee 100755 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -70,7 +70,7 @@ jobs: echo "$CHANGELOG" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - ./gradlew listProductsReleases # prepare list of IDEs for Plugin Verifier + ./gradlew printProductsReleases # prepare list of IDEs for Plugin Verifier - name: Build plugin run: ./gradlew buildPlugin @@ -144,6 +144,7 @@ jobs: client-id: ${{ secrets.CIMON_CLIENT_ID }} secret: ${{ secrets.CIMON_SECRET }} allowed-hosts: > + download.jetbrains.com cache-redirector.jetbrains.com cdn.azul.com data.services.jetbrains.com @@ -158,10 +159,15 @@ jobs: - name: Maximize Build Space run: | + sudo docker image prune --all --force || true + sudo rm -rf /usr/share/dotnet sudo rm -rf /usr/local/lib/android sudo rm -rf /opt/ghc sudo rm -rf /usr/local/.ghcup + sudo rm -rf /opt/hostedtoolcache + sudo rm -rf /usr/share/swift + sudo rm -rf /usr/local/share/powershell sudo apt-get remove -y '^aspnetcore-.*' || echo "::warning::The command [sudo apt-get remove -y '^aspnetcore-.*'] failed to complete successfully. Proceeding..." sudo apt-get remove -y '^dotnet-.*' --fix-missing || echo "::warning::The command [sudo apt-get remove -y '^dotnet-.*' --fix-missing] failed to complete successfully. Proceeding..." @@ -175,8 +181,6 @@ jobs: sudo apt-get autoremove -y || echo "::warning::The command [sudo apt-get autoremove -y] failed to complete successfully. Proceeding..." sudo apt-get clean || echo "::warning::The command [sudo apt-get clean] failed to complete successfully. Proceeding..." - sudo docker image prune --all --force || true - - name: Fetch Sources uses: actions/checkout@v4 @@ -195,10 +199,10 @@ jobs: uses: actions/cache@v3 with: path: ${{ needs.build.outputs.pluginVerifierHomeDir }}/ides - key: plugin-verifier-${{ hashFiles('build/listProductsReleases.txt') }} + key: plugin-verifier-${{ hashFiles('build/printProductsReleases.txt') }} - name: Run Plugin Verification tasks - run: ./gradlew runPluginVerifier -Dplugin.verifier.home.dir=${{ needs.build.outputs.pluginVerifierHomeDir }} + run: ./gradlew verifyPlugin -Dplugin.verifier.home.dir=${{ needs.build.outputs.pluginVerifierHomeDir }} - name: Collect Plugin Verifier Result if: ${{ always() }} diff --git a/build.gradle.kts b/build.gradle.kts index c3deb2a..358a039 100755 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -19,6 +19,10 @@ version = properties("pluginVersion").get() // Configure project's dependencies repositories { mavenCentral() + + intellijPlatform { + defaultRepositories() + } } // Dependencies are managed with Gradle version catalog - read more: https://docs.gradle.org/current/userguide/platforms.html#sub:version-catalog @@ -26,6 +30,13 @@ dependencies { implementation(libs.annotations) implementation(libs.jackson) implementation(libs.flexmark) + + intellijPlatform { + intellijIdeaCommunity(properties("platformVersion")) + // Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html + // Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 + bundledPlugin("com.intellij.java") + } } // Set the JVM language level used to build the project. We are using Java 17 for 2022.2+. @@ -40,16 +51,71 @@ java { } } -// Configure Gradle IntelliJ Plugin - read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html -intellij { - pluginName = properties("pluginName") - version = properties("platformVersion") - type = properties("platformType") +intellijPlatform { + projectName = project.name + + // required for Auto-Reload development mode + buildSearchableOptions = false + + pluginConfiguration { + name = properties("pluginName").get() + version = properties("pluginVersion").get() + + ideaVersion { + sinceBuild = properties("pluginSinceBuild") + untilBuild = properties("pluginUntilBuild") + } + + description = providers.fileContents(layout.projectDirectory.file("README.md")).asText.map { + val start = "" + val end = "" + + with(it.lines()) { + if (!containsAll(listOf(start, end))) { + throw GradleException("Plugin description section not found in README.md:\n$start ... $end") + } + subList(indexOf(start) + 1, indexOf(end)).joinToString("\n").let(::markdownToHTML) + } + } + + val changelog = project.changelog // local variable for configuration cache compatibility + // Get the latest available change notes from the changelog file + changeNotes = properties("pluginVersion").map { pluginVersion -> + with(changelog) { + renderItem( + (getOrNull(pluginVersion) ?: getUnreleased()) + .withHeader(false) + .withEmptySections(false), + Changelog.OutputType.HTML, + ) + } + } + } + + publishing { + token = environment("PUBLISH_TOKEN") + // The pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3 + // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more: + // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel + channels.set( + properties("pluginVersion").map { pluginVersion: String -> + val channel = pluginVersion.substringAfter('-', "default").substringBefore('.') + listOf(channel) + } + ) + } - // Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file. - plugins = properties("platformPlugins").map { it.split(',').map(String::trim).filter(String::isNotEmpty) } + signing { + certificateChain = environment("CERTIFICATE_CHAIN") + privateKey = environment("PRIVATE_KEY") + password = environment("PRIVATE_KEY_PASSWORD") + } - updateSinceUntilBuild = false + pluginVerification { + ides { + recommended() + } + } } // Configure Gradle Changelog Plugin - read more: https://github.com/JetBrains/gradle-changelog-plugin @@ -86,70 +152,33 @@ tasks { gradleVersion = properties("gradleVersion").get() } - patchPluginXml { - version = properties("pluginVersion") - sinceBuild = properties("pluginSinceBuild") - untilBuild = properties("pluginUntilBuild") - - // Extract the section from README.md and provide for the plugin's manifest - pluginDescription = providers.fileContents(layout.projectDirectory.file("README.md")).asText.map { - val start = "" - val end = "" - - with(it.lines()) { - if (!containsAll(listOf(start, end))) { - throw GradleException("Plugin description section not found in README.md:\n$start ... $end") - } - subList(indexOf(start) + 1, indexOf(end)).joinToString("\n").let(::markdownToHTML) - } - } - - val changelog = project.changelog // local variable for configuration cache compatibility - // Get the latest available change notes from the changelog file - changeNotes = properties("pluginVersion").map { pluginVersion -> - with(changelog) { - renderItem( - (getOrNull(pluginVersion) ?: getUnreleased()) - .withHeader(false) - .withEmptySections(false), - Changelog.OutputType.HTML, - ) - } - } - } - - // Configure UI tests plugin - // Read more: https://github.com/JetBrains/intellij-ui-test-robot - runIdeForUiTests { - systemProperty("robot-server.port", "8082") - systemProperty("ide.mac.message.dialogs.as.sheets", "false") - systemProperty("jb.privacy.policy.text", "") - systemProperty("jb.consents.confirmation.enabled", "false") - } - runIde { - systemProperty("idea.log.debug.categories", "com.cycode.plugin") - } - - signPlugin { - certificateChain = environment("CERTIFICATE_CHAIN") - privateKey = environment("PRIVATE_KEY") - password = environment("PRIVATE_KEY_PASSWORD") + jvmArgumentProviders += CommandLineArgumentProvider { + listOf( + "-Didea.log.debug.categories=com.cycode.plugin" + ) + } } +} - publishPlugin { - dependsOn("patchChangelog") - dependsOn("sentryUploadSourceBundleJava") - token = environment("PUBLISH_TOKEN") - // The pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3 - // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more: - // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel - channels = - properties("pluginVersion").map { listOf(it.split('-').getOrElse(1) { "default" }.split('.').first()) } +val runIdeForUiTests by intellijPlatformTesting.runIde.registering { + task { + jvmArgumentProviders += CommandLineArgumentProvider { + listOf( + "-Drobot-server.port=8082", + "-Dide.mac.message.dialogs.as.sheets=false", + "-Djb.privacy.policy.text=", + "-Djb.consents.confirmation.enabled=false", + ) } + } - buildSearchableOptions { - // required for Auto-Reload development mode - enabled = false - } + plugins { + robotServerPlugin() + } } + +tasks.named("publishPlugin") { + dependsOn("patchChangelog") + dependsOn("sentryUploadSourceBundleJava") +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index dbbd8fd..92f42f8 100755 --- a/gradle.properties +++ b/gradle.properties @@ -7,22 +7,18 @@ pluginRepositoryUrl = https://github.com/cycodehq/intellij-platform-plugin pluginVersion = 2.6.0 # Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html -pluginSinceBuild = 231 -pluginUntilBuild = 252.* +pluginSinceBuild = 241 +pluginUntilBuild = 253.* -# IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension -platformType = IC +# IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin.html # 2021.1 - Apple Silicon support + fixes for development on Apple Silicon # 2022.3 - minimum version for IntelliJ Platform Gradle Plugin (2.x) # 2023.1 - allows to fix "com.intellij.diagnostic.PluginException: `ActionUpdateThread.OLD_EDT` is deprecated blabla" -platformVersion = 2023.1 - -# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html -# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 -platformPlugins = com.intellij.java +# 2024.1 - allows to fix "com.cycode.plugin.services.ServicesKt" compatibility issues +platformVersion = 2024.1 # Gradle Releases -> https://github.com/gradle/gradle/releases -gradleVersion = 8.4 +gradleVersion = 8.14.1 # Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib kotlin.stdlib.default.dependency = false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 80f6193..54c2bd5 100755 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,9 +6,9 @@ flexmark = "0.64.8" # plugins dokka = "1.9.20" -kotlin = "2.0.10" +kotlin = "2.2.0" changelog = "2.2.1" -gradleIntelliJPlugin = "1.17.4" # the latest before 2.0 with a lot of breaking changes +gradleIntelliJPlugin = "2.10.4" kover = "0.7.3" sentry = "4.11.0" @@ -20,7 +20,7 @@ flexmark = { group = "com.vladsch.flexmark", name = "flexmark-all", version.ref [plugins] changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" } dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } -gradleIntelliJPlugin = { id = "org.jetbrains.intellij", version.ref = "gradleIntelliJPlugin" } +gradleIntelliJPlugin = { id = "org.jetbrains.intellij.platform", version.ref = "gradleIntelliJPlugin" } kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } sentry = { id = "io.sentry.jvm.gradle", version.ref = "sentry" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3fa8f86..002b867 100755 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/src/main/kotlin/com/cycode/plugin/cli/CliWrapper.kt b/src/main/kotlin/com/cycode/plugin/cli/CliWrapper.kt index 8817f5f..c56a29b 100644 --- a/src/main/kotlin/com/cycode/plugin/cli/CliWrapper.kt +++ b/src/main/kotlin/com/cycode/plugin/cli/CliWrapper.kt @@ -92,11 +92,13 @@ class CliWrapper(val workDirectory: String? = null) { } if (T::class == Unit::class) { + @Suppress("UNCHECKED_CAST") return CliResult.Success(Unit) as CliResult } try { val result: T = mapper.readValue(stdout) + @Suppress("UNCHECKED_CAST") return CliResult.Success(result) } catch (e: Exception) { thisLogger().warn("Failed to parse success CLI output: $stdout", e) diff --git a/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/treeView/components/detectionNodeContextMenu/DetectionNodeContextMenu.kt b/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/treeView/components/detectionNodeContextMenu/DetectionNodeContextMenu.kt index 3a3686b..8a9205e 100644 --- a/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/treeView/components/detectionNodeContextMenu/DetectionNodeContextMenu.kt +++ b/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/treeView/components/detectionNodeContextMenu/DetectionNodeContextMenu.kt @@ -14,7 +14,6 @@ import com.intellij.openapi.ui.popup.LightweightWindowEvent import com.intellij.openapi.util.text.StringUtil.convertLineSeparators import com.intellij.openapi.util.text.StringUtil.first import com.intellij.ui.ColoredListCellRenderer -import com.intellij.vcs.commit.message.CommitMessageInspectionProfile.getSubjectRightMargin import org.jetbrains.annotations.Nls import java.awt.event.MouseEvent import javax.swing.JList @@ -121,7 +120,7 @@ class DetectionNodeContextMenu( return } - val rightMargin = getSubjectRightMargin(project) + val rightMargin = 50 JBPopupFactory.getInstance().createPopupChooserBuilder(options) .setVisibleRowCount(7) .setSelectionMode(SINGLE_SELECTION) diff --git a/src/main/kotlin/com/cycode/plugin/services/DownloadService.kt b/src/main/kotlin/com/cycode/plugin/services/DownloadService.kt index 0db916f..a4ee05a 100644 --- a/src/main/kotlin/com/cycode/plugin/services/DownloadService.kt +++ b/src/main/kotlin/com/cycode/plugin/services/DownloadService.kt @@ -7,7 +7,7 @@ import io.sentry.Sentry import java.io.BufferedInputStream import java.io.File import java.io.FileOutputStream -import java.net.URL +import java.net.URI import java.nio.file.Files @@ -22,7 +22,7 @@ class DownloadService { thisLogger().warn("Retrieving $url") try { - val urlObj = URL(url) + val urlObj = URI(url).toURL() val connection = urlObj.openConnection() connection.connect() @@ -53,7 +53,7 @@ class DownloadService { thisLogger().warn("Temp path: ${tempFile.absolutePath}") try { - val urlObj = URL(url) + val urlObj = URI(url).toURL() val connection = urlObj.openConnection() connection.connect() diff --git a/src/main/kotlin/com/cycode/plugin/services/GithubReleaseService.kt b/src/main/kotlin/com/cycode/plugin/services/GithubReleaseService.kt index 4cd9396..be97e7f 100644 --- a/src/main/kotlin/com/cycode/plugin/services/GithubReleaseService.kt +++ b/src/main/kotlin/com/cycode/plugin/services/GithubReleaseService.kt @@ -6,7 +6,7 @@ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.readValue import com.intellij.openapi.components.Service import io.sentry.Sentry -import java.net.URL +import java.net.URI data class GitHubReleaseAsset( @@ -29,7 +29,7 @@ class GithubReleaseService { private fun getJson(url: String): String? { try { - val urlObj = URL(url) + val urlObj = URI(url).toURL() val connection = urlObj.openConnection() connection.setRequestProperty("Accept", "application/vnd.github.v3+json") diff --git a/src/main/kotlin/com/cycode/plugin/services/Services.kt b/src/main/kotlin/com/cycode/plugin/services/Services.kt index f3116c3..4800f6a 100644 --- a/src/main/kotlin/com/cycode/plugin/services/Services.kt +++ b/src/main/kotlin/com/cycode/plugin/services/Services.kt @@ -1,6 +1,6 @@ package com.cycode.plugin.services -import com.intellij.openapi.components.ServiceManager.getService +import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.service import com.intellij.openapi.project.Project @@ -10,7 +10,7 @@ inline fun getCycodeService(project: Project? = null): T { return project.service() } - return getService(T::class.java) + return ApplicationManager.getApplication().service() } fun pluginState(project: Project? = null): CycodePersistentStateService = getCycodeService(project) diff --git a/src/main/kotlin/com/cycode/plugin/settings/ApplicationSettingsConfigurable.kt b/src/main/kotlin/com/cycode/plugin/settings/ApplicationSettingsConfigurable.kt index 562a891..8da912f 100644 --- a/src/main/kotlin/com/cycode/plugin/settings/ApplicationSettingsConfigurable.kt +++ b/src/main/kotlin/com/cycode/plugin/settings/ApplicationSettingsConfigurable.kt @@ -7,9 +7,8 @@ import com.cycode.plugin.services.pluginSettings import com.intellij.openapi.options.SearchableConfigurable import com.intellij.openapi.project.Project import java.io.File -import java.net.MalformedURLException import java.net.URISyntaxException -import java.net.URL +import java.net.URI import javax.swing.JComponent @@ -41,11 +40,9 @@ class ApplicationSettingsConfigurable(val project: Project) : SearchableConfigur private fun isValidUrl(url: String): Boolean { return try { - // toURI() method is important here as it ensures that any URL string that complies with RFC 2396 - URL(url).toURI() + // URI is important here as it ensures that any URL string complies with RFC 2396 + URI(url) true - } catch (e: MalformedURLException) { - false } catch (e: URISyntaxException) { false } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 33dc23e..6ec120e 100755 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -12,7 +12,7 @@ + anchor="bottom" icon="com.cycode.plugin.icons.PluginIcons"/>