diff --git a/platform/build-scripts/downloader/src/org/jetbrains/intellij/build/dependencies/TeamCityHelper.kt b/platform/build-scripts/downloader/src/org/jetbrains/intellij/build/dependencies/TeamCityHelper.kt
index c124a78c1c5e..18bebb653213 100644
--- a/platform/build-scripts/downloader/src/org/jetbrains/intellij/build/dependencies/TeamCityHelper.kt
+++ b/platform/build-scripts/downloader/src/org/jetbrains/intellij/build/dependencies/TeamCityHelper.kt
@@ -8,7 +8,6 @@ import java.nio.file.Files
import java.nio.file.Path
import java.util.function.Supplier
-@Suppress("unused")
@ApiStatus.Internal
object TeamCityHelper {
val isUnderTeamCity = System.getenv("TEAMCITY_VERSION") != null
diff --git a/platform/build-scripts/intellij.platform.buildScripts.iml b/platform/build-scripts/intellij.platform.buildScripts.iml
index 9be64125aa88..9e826307afbb 100644
--- a/platform/build-scripts/intellij.platform.buildScripts.iml
+++ b/platform/build-scripts/intellij.platform.buildScripts.iml
@@ -166,5 +166,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/ApplicationInfoPropertiesImpl.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/ApplicationInfoPropertiesImpl.kt
index 83f0d585f445..7e5a7b17fcde 100644
--- a/platform/build-scripts/src/org/jetbrains/intellij/build/ApplicationInfoPropertiesImpl.kt
+++ b/platform/build-scripts/src/org/jetbrains/intellij/build/ApplicationInfoPropertiesImpl.kt
@@ -4,6 +4,7 @@ package org.jetbrains.intellij.build
import com.intellij.util.xml.dom.readXmlAsModel
import org.jetbrains.annotations.VisibleForTesting
import org.jetbrains.intellij.build.impl.BuildUtils
+import org.jetbrains.intellij.build.impl.logging.reportBuildProblem
import org.jetbrains.intellij.build.impl.readSnapshotBuildNumber
import org.jetbrains.jps.model.JpsProject
import java.nio.file.Files
@@ -94,15 +95,11 @@ class ApplicationInfoPropertiesImpl: ApplicationInfoProperties {
val expirationDate = buildDate.plus(30, ChronoUnit.DAYS)
val now = Instant.ofEpochMilli(System.currentTimeMillis())
if (expirationDate < now) {
- val msg = "Supplied build date is $buildDate, " +
- "so expiration date is in the past, " +
- "distribution won't be able to start"
- if (buildOptions.isInDevelopmentMode) {
- error(msg)
- }
- else {
- println("##teamcity[buildProblem description='$msg']")
- }
+ reportBuildProblem(
+ "Supplied build date is $buildDate, " +
+ "so expiration date is in the past, " +
+ "distribution won't be able to start"
+ )
}
}
majorReleaseDate == null || majorReleaseDate.startsWith("__") -> {
diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.kt
index 8af406a2e6f9..6ed1a9eacf26 100644
--- a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.kt
+++ b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.kt
@@ -12,6 +12,10 @@ import com.intellij.util.containers.MultiMap
import com.intellij.util.io.Compressor
import com.jetbrains.plugin.blockmap.core.BlockMap
import com.jetbrains.plugin.blockmap.core.FileHash
+import com.jetbrains.plugin.structure.base.plugin.PluginCreationFail
+import com.jetbrains.plugin.structure.base.plugin.PluginCreationSuccess
+import com.jetbrains.plugin.structure.base.plugin.PluginProblem
+import com.jetbrains.plugin.structure.intellij.plugin.IdePluginManager
import io.opentelemetry.api.common.AttributeKey
import io.opentelemetry.api.common.Attributes
import io.opentelemetry.api.trace.Span
@@ -25,6 +29,7 @@ import org.jetbrains.intellij.build.*
import org.jetbrains.intellij.build.TraceManager.spanBuilder
import org.jetbrains.intellij.build.dependencies.BuildDependenciesCommunityRoot
import org.jetbrains.intellij.build.fus.createStatisticsRecorderBundledMetadataProviderTask
+import org.jetbrains.intellij.build.impl.logging.reportBuildProblem
import org.jetbrains.intellij.build.impl.projectStructureMapping.*
import org.jetbrains.intellij.build.io.*
import org.jetbrains.intellij.build.tasks.ZipSource
@@ -50,6 +55,8 @@ import java.util.*
import java.util.concurrent.ConcurrentLinkedQueue
import java.util.function.Predicate
import java.util.stream.Collectors
+import kotlin.io.path.exists
+import kotlin.io.path.name
/**
* Assembles output of modules to platform JARs (in [BuildPaths.distAllDir]/lib directory),
@@ -161,6 +168,50 @@ class DistributionJARsBuilder {
}
}
+ private fun validatePlugin(path: Path, context: BuildContext) {
+ spanBuilder("plugin validation").setAttribute("path", "$path").useWithScope {
+ if (!path.exists()) {
+ it.addEvent("path doesn't exist, skipped")
+ return@useWithScope
+ }
+ var id: String? = null
+ val problems = when (val result = IdePluginManager.createManager().createPlugin(path)) {
+ is PluginCreationSuccess -> {
+ id = result.plugin.pluginId
+ result.unacceptableWarnings
+ }
+ is PluginCreationFail -> {
+ result.errorsAndWarnings
+ }
+ }
+ if (problems.isNotEmpty()) {
+ val msg = problems.joinToString(
+ prefix = "${id ?: path}: ",
+ separator = ". ",
+ transform = PluginProblem::message
+ )
+ when (id) {
+ // https://youtrack.jetbrains.com/issue/IDEA-308174
+ "androidx.compose.plugins.idea",
+ // https://youtrack.jetbrains.com/issue/IDEA-312410
+ "com.intellij.tasks",
+ // https://youtrack.jetbrains.com/issue/IDEA-312409
+ "org.jetbrains.plugins.sass",
+ // https://youtrack.jetbrains.com/issue/IDEA-312408
+ "org.toml.lang",
+ // https://youtrack.jetbrains.com/issue/IDEA-312407
+ "com.intellij.plugins.webcomponents",
+ // https://youtrack.jetbrains.com/issue/IDEA-312406
+ "cucumber-javascript",
+ // https://youtrack.jetbrains.com/issue/IDEA-312405
+ "com.jetbrains.plugins.yeoman"
+ -> context.messages.warning(msg)
+ else -> reportBuildProblem(msg, identity = "${id ?: path}")
+ }
+ }
+ }
+ }
+
// filter out jars with relative paths in name
val productModules: List
get() {
@@ -361,7 +412,7 @@ class DistributionJARsBuilder {
}
// buildPlugins pluginBuilt listener is called concurrently
- val pluginsToIncludeInCustomRepository = ConcurrentLinkedQueue()
+ val pluginSpecs = ConcurrentLinkedQueue()
val autoPublishPluginChecker = loadPluginAutoPublishList(context)
val prepareCustomPluginRepository = context.productProperties.productLayout.prepareCustomPluginRepositoryForPublishedPlugins &&
!context.isStepSkipped(BuildOptions.ARCHIVE_PLUGINS)
@@ -383,10 +434,8 @@ class DistributionJARsBuilder {
defaultPluginVersion
}
val destFile = targetDirectory.resolve("${plugin.directoryName}-$pluginVersion.zip")
- if (prepareCustomPluginRepository) {
- val pluginXml = moduleOutputPatcher.getPatchedPluginXml(plugin.mainModule)
- pluginsToIncludeInCustomRepository.add(PluginRepositorySpec(destFile, pluginXml))
- }
+ val pluginXml = moduleOutputPatcher.getPatchedPluginXml(plugin.mainModule)
+ pluginSpecs.add(PluginRepositorySpec(destFile, pluginXml))
dirToJar.add(NonBundledPlugin(pluginDirOrFile, destFile, !plugin.enableSymlinksAndExecutableResources))
}
@@ -399,21 +448,24 @@ class DistributionJARsBuilder {
targetDir = autoUploadingDir,
moduleOutputPatcher = moduleOutputPatcher,
context = context)
- if (prepareCustomPluginRepository) {
- pluginsToIncludeInCustomRepository.add(spec)
- }
+ pluginSpecs.add(spec)
}
+ for (item in buildKeymapPluginsTask.await()) {
+ pluginSpecs.add(PluginRepositorySpec(pluginZip = item.first, pluginXml = item.second))
+ }
if (prepareCustomPluginRepository) {
- for (item in buildKeymapPluginsTask.await()) {
- pluginsToIncludeInCustomRepository.add(PluginRepositorySpec(pluginZip = item.first, pluginXml = item.second))
- }
-
- val list = pluginsToIncludeInCustomRepository.sortedBy { it.pluginZip }
+ val list = pluginSpecs.sortedBy { it.pluginZip }
generatePluginRepositoryMetaFile(list, nonBundledPluginsArtifacts, context)
generatePluginRepositoryMetaFile(list.filter { it.pluginZip.startsWith(autoUploadingDir) }, autoUploadingDir, context)
}
-
+ pluginSpecs.forEach {
+ if (it.pluginZip.startsWith(autoUploadingDir)) {
+ launch {
+ validatePlugin(it.pluginZip, context)
+ }
+ }
+ }
mappings
}
}
diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/OsSpecificDistributionBuilder.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/OsSpecificDistributionBuilder.kt
index 22e2b7b6402a..9225431d3fd1 100644
--- a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/OsSpecificDistributionBuilder.kt
+++ b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/OsSpecificDistributionBuilder.kt
@@ -13,6 +13,8 @@ import org.jetbrains.intellij.build.BuildContext
import org.jetbrains.intellij.build.JvmArchitecture
import org.jetbrains.intellij.build.OsFamily
import org.jetbrains.intellij.build.TraceManager
+import org.jetbrains.intellij.build.dependencies.TeamCityHelper
+import org.jetbrains.intellij.build.impl.logging.reportBuildProblem
import java.io.BufferedInputStream
import java.nio.file.FileSystems
import java.nio.file.Files
@@ -66,10 +68,13 @@ interface OsSpecificDistributionBuilder {
.toSet()
if (unmatchedPatterns.isNotEmpty()) {
context.messages.warning(matchedFiles.joinToString(prefix = "Matched files ${distribution.name}:\n", separator = "\n"))
- val msg = unmatchedPatterns.joinToString(prefix = "Unmatched executable permissions patterns in ${distribution.name}: ") {
- patterns.getValue(it)
+ if (TeamCityHelper.isUnderTeamCity) {
+ reportBuildProblem(
+ unmatchedPatterns.joinToString(prefix = "Unmatched executable permissions patterns in ${distribution.name}: ") {
+ patterns.getValue(it)
+ }
+ )
}
- println("##teamcity[buildProblem description='$msg']")
}
}
}
diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/TestingTasksImpl.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/TestingTasksImpl.kt
index 81fe077374b8..519438a100b6 100644
--- a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/TestingTasksImpl.kt
+++ b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/TestingTasksImpl.kt
@@ -21,6 +21,7 @@ import org.jetbrains.intellij.build.*
import org.jetbrains.intellij.build.CompilationTasks.Companion.create
import org.jetbrains.intellij.build.TraceManager.spanBuilder
import org.jetbrains.intellij.build.causal.CausalProfilingOptions
+import org.jetbrains.intellij.build.impl.logging.reportBuildProblem
import org.jetbrains.intellij.build.io.runProcess
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType
import org.jetbrains.jps.incremental.ModuleBuildTarget
@@ -59,8 +60,8 @@ internal class TestingTasksImpl(private val context: CompilationContext, private
}
}
catch (e: Exception) {
- val description = e.message?.lineSequence()?.first()?.replace("'", "\"")
- println("##teamcity[buildProblem identity='${name.replace(" ", "_")}' description='$description']")
+ val description = e.message?.lineSequence()?.firstOrNull() ?: ""
+ reportBuildProblem(description, identity = name)
emptyList()
}
}
diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/logging/BuildMessagesImpl.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/logging/BuildMessagesImpl.kt
index 81e18b215045..66c6340d797b 100644
--- a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/logging/BuildMessagesImpl.kt
+++ b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/logging/BuildMessagesImpl.kt
@@ -4,8 +4,11 @@ package org.jetbrains.intellij.build.impl.logging
import com.intellij.diagnostic.telemetry.useWithScope
import com.intellij.openapi.util.ThrowableComputable
import com.intellij.util.containers.Stack
+import jetbrains.buildServer.messages.serviceMessages.ServiceMessage
+import org.jetbrains.annotations.ApiStatus.Internal
import org.jetbrains.intellij.build.*
import org.jetbrains.intellij.build.TraceManager.spanBuilder
+import org.jetbrains.intellij.build.dependencies.TeamCityHelper.isUnderTeamCity
import java.io.BufferedWriter
import java.io.PrintWriter
import java.io.StringWriter
@@ -15,6 +18,7 @@ import java.nio.file.StandardCopyOption
import java.nio.file.StandardOpenOption
import java.util.*
import java.util.function.Consumer
+import jetbrains.buildServer.messages.serviceMessages.ServiceMessageTypes.BUILD_PORBLEM as BUILD_PROBLEM
class BuildMessagesImpl private constructor(private val logger: BuildMessageLogger,
private val debugLogger: DebugLogger) : BuildMessages {
@@ -22,8 +26,7 @@ class BuildMessagesImpl private constructor(private val logger: BuildMessageLogg
companion object {
fun create(): BuildMessagesImpl {
- val underTeamCity = System.getenv("TEAMCITY_VERSION") != null
- val mainLoggerFactory = if (underTeamCity) TeamCityBuildMessageLogger.FACTORY else ConsoleBuildMessageLogger.FACTORY
+ val mainLoggerFactory = if (isUnderTeamCity) TeamCityBuildMessageLogger.FACTORY else ConsoleBuildMessageLogger.FACTORY
val debugLogger = DebugLogger()
return BuildMessagesImpl(logger = CompositeBuildMessageLogger(listOf(mainLoggerFactory(), debugLogger.createLogger())),
debugLogger = debugLogger)
@@ -206,3 +209,18 @@ private class PrintWriterBuildMessageLogger(
disposer.accept(this)
}
}
+
+@Internal
+fun reportBuildProblem(description: String, identity: String? = null) {
+ if (isUnderTeamCity) {
+ val attributes = mutableMapOf("description" to description)
+ if (identity != null) {
+ attributes["identity"] = identity
+ }
+ println(ServiceMessage.asString(BUILD_PROBLEM, attributes))
+ }
+ else {
+ error("$identity: $description")
+ }
+}
+
diff --git a/plugins/github/resources/META-INF/plugin.xml b/plugins/github/resources/META-INF/plugin.xml
index 7bcb19781c13..727ba149b919 100644
--- a/plugins/github/resources/META-INF/plugin.xml
+++ b/plugins/github/resources/META-INF/plugin.xml
@@ -5,7 +5,7 @@
Version Controls
GitHub.
+ Provides integration with GitHub.
- Specify your GitHub account to access all of your repositories from the IDE.
- Clone repositories, create and review pull requests, create gists, and much more.
diff --git a/plugins/hg4idea/src/META-INF/plugin.xml b/plugins/hg4idea/src/META-INF/plugin.xml
index f2a7c3c8a4e3..cc081f7af591 100644
--- a/plugins/hg4idea/src/META-INF/plugin.xml
+++ b/plugins/hg4idea/src/META-INF/plugin.xml
@@ -3,7 +3,7 @@
Mercurial
Mercurial version control system.
+ Allows working with Mercurial version control system.
The following features are available:
- Dedicated page under the Version Control node in the Settings/Preferences dialog.
diff --git a/python/pluginCore/resources/META-INF/plugin.xml b/python/pluginCore/resources/META-INF/plugin.xml
index 835179b84770..981d5f301f13 100644
--- a/python/pluginCore/resources/META-INF/plugin.xml
+++ b/python/pluginCore/resources/META-INF/plugin.xml
@@ -9,8 +9,8 @@
The Python plug-in provides smart editing for Python scripts. The feature set of the plugin
corresponds to PyCharm IDE Community Edition.
-PyCharm blog
-Discussion forum
+PyCharm blog
+Discussion forum
Issue tracker
]]>