Refactor and simplify Gradle Plugin Portal publishing configuration

* Instead of disabling the `signing` plugin when we need to publish,
  use a more granular workaround: delete and re-create the `archives`
  configuration (there's a bug in the `signing` plugin: we can't clear
  that configuration due to a bad `whenObjectRemoved` callback failing
  on instances of `Signature`, and we used to disable signing due to
  this bug).

* Translate the Groovy script into a Kotlin file and a part of buildSrc.

* Introduce a project-wide mechanism for publishing prebuilt JARs – a
  property which will now point to a Maven repository root.
  This allows us to get rid of module-specific options that we need to
  specify for deployment, and instead simplify the configuration to a
  single project-wide option.

(cherry picked from commit 79095e1)
diff --git a/build.gradle.kts b/build.gradle.kts
index 20ab918..ac4f862 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -36,7 +36,6 @@
     }
 
     dependencies {
-        classpath("com.gradle.publish:plugin-publish-plugin:0.9.7")
         classpath(kotlinDep("gradle-plugin", bootstrapKotlinVersion))
         classpath("net.sf.proguard:proguard-gradle:5.3.3")
     }
@@ -243,7 +242,6 @@
 
 apply {
     from("libraries/commonConfiguration.gradle")
-    from("libraries/configureGradleTools.gradle")
 }
 
 apply {
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
index 854f3fc..d2e6c5c 100644
--- a/buildSrc/build.gradle.kts
+++ b/buildSrc/build.gradle.kts
@@ -56,6 +56,7 @@
         maven(url = it)
     }
     maven(url = "https://repo.gradle.org/gradle/libs-releases-local") // for native-platform
+    maven(url = "https://plugins.gradle.org/m2/") // for Gradle plugin publishing plugin
     jcenter()
 }
 
@@ -69,6 +70,7 @@
     // Shadow plugin is used in many projects of the main build. Once it's no longer used in buildSrc, please move this dependency to the root project
     compile("com.github.jengelman.gradle.plugins:shadow:${property("versions.shadow")}")
     compile("org.ow2.asm:asm-all:6.0_BETA")
+    compile("com.gradle.publish:plugin-publish-plugin:0.9.10")
 }
 
 samWithReceiver {
diff --git a/buildSrc/src/main/kotlin/gradlePluginPortalPublishing.kt b/buildSrc/src/main/kotlin/gradlePluginPortalPublishing.kt
new file mode 100644
index 0000000..15b47db
--- /dev/null
+++ b/buildSrc/src/main/kotlin/gradlePluginPortalPublishing.kt
@@ -0,0 +1,59 @@
+import com.gradle.publish.PluginBundleExtension
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.the
+
+/*
+ * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
+ * that can be found in the license/LICENSE.txt file.
+ */
+
+fun Project.publishToGradlePluginPortal() {
+    apply { plugin("com.gradle.plugin-publish") }
+
+    val prebuiltJarPath: String? =
+        // Support the old way of specifying pre-built JARs per-project:
+        project.findProperty("${project.name}-jar")?.toString() ?:
+        // And the new way: using the 'prebuiltMavenRepo' property as a path to a  Maven repo root:
+        project.findProperty("prebuiltMavenRepo")?.let { prebuiltMavenRepo ->
+            val subfolder = project.group.toString().replace(".", "/") + "/" + project.name + "/" + version
+            val jarName = "${project.name}-$version.jar"
+            "$prebuiltMavenRepo/$subfolder/$jarName"
+        }
+
+    if (prebuiltJarPath != null) {
+        println("Dropping archives and using pre-built artifact for ${project.name}: $prebuiltJarPath")
+
+        // Removing and re-creating the configuration is required due to a bug in the Gradle `signing` plugin,
+        // it adds a callback for `archives` items deletion which breaks when its own `Signature` artifacts are deleted
+        configurations.remove(configurations.getByName("archives"))
+        configurations.create("archives")
+
+        artifacts.add("archives", file(prebuiltJarPath)) {
+            name = project.name
+       }
+    }
+
+    findProperty("publishPluginsVersion")?.let { publishPluginsVersion ->
+        configurations.getByName("archives").artifacts.all {
+            version = publishPluginsVersion
+        }
+    }
+
+    tasks.getByName("publishPlugins").doFirst {
+        val kotlinVersion = property("kotlinVersion").toString()
+        require(!kotlinVersion.endsWith("SNAPSHOT")) {
+            "Kotlin version is a snapshot version $kotlinVersion. Snapshot versions should not be published."
+        }
+    }
+
+    the<PluginBundleExtension>().apply {
+        website = "https://kotlinlang.org/"
+        vcsUrl = "https://github.com/JetBrains/kotlin/"
+        description = "Kotlin plugins for Gradle"
+        tags = listOf("kotlin")
+
+        mavenCoordinates {
+            groupId = "org.jetbrains.kotlin"
+        }
+    }
+}
diff --git a/buildSrc/src/main/kotlin/plugins/PublishedKotlinModule.kt b/buildSrc/src/main/kotlin/plugins/PublishedKotlinModule.kt
index 2bf5fd8..5df2713 100644
--- a/buildSrc/src/main/kotlin/plugins/PublishedKotlinModule.kt
+++ b/buildSrc/src/main/kotlin/plugins/PublishedKotlinModule.kt
@@ -30,20 +30,18 @@
 
             plugins.apply("maven")
 
-            if (!project.hasProperty("prebuiltJar")) {
-                plugins.apply("signing")
+            plugins.apply("signing")
 
-                val signingRequired = project.findProperty("signingRequired")?.toString()?.toBooleanOrNull()
-                                      ?: project.property("isSonatypeRelease") as Boolean
+            val signingRequired = project.findProperty("signingRequired")?.toString()?.toBooleanOrNull()
+                                  ?: project.property("isSonatypeRelease") as Boolean
 
-                configure<SigningExtension> {
-                    isRequired = signingRequired
-                    sign(configurations["archives"])
-                }
+            configure<SigningExtension> {
+                isRequired = signingRequired
+                sign(configurations["archives"])
+            }
 
-                (tasks.getByName("signArchives") as Sign).apply {
-                    enabled = signingRequired
-                }
+            (tasks.getByName("signArchives") as Sign).apply {
+                enabled = signingRequired
             }
 
             fun MavenResolver.configurePom() {
diff --git a/libraries/commonConfiguration.gradle b/libraries/commonConfiguration.gradle
index 453f243..f5732ca 100644
--- a/libraries/commonConfiguration.gradle
+++ b/libraries/commonConfiguration.gradle
@@ -125,17 +125,15 @@
     project.configure(project) {
         apply plugin: 'maven'
 
-        if (!project.hasProperty('prebuiltJar')) {
-            apply plugin: 'signing'
+        apply plugin: 'signing'
 
-            signing {
-                required { (project.properties["signingRequired"] ?: project.isSonatypeRelease) }
-                sign configurations.archives
-            }
+        signing {
+            required { (project.properties["signingRequired"] ?: project.isSonatypeRelease) }
+            sign configurations.archives
+        }
 
-            signArchives {
-                enabled signing.required
-            }
+        signArchives {
+            enabled signing.required
         }
 
         uploadArchives {
diff --git a/libraries/configureGradleTools.gradle b/libraries/configureGradleTools.gradle
deleted file mode 100644
index 0ab7acc..0000000
--- a/libraries/configureGradleTools.gradle
+++ /dev/null
@@ -1,38 +0,0 @@
-
-configure([project(':kotlin-gradle-plugin'), project(':kotlin-allopen'), project(':kotlin-noarg')]) { project ->
-    apply plugin: 'com.gradle.plugin-publish'
-
-    afterEvaluate {
-        if (project.hasProperty('publishPluginsVersion')) {
-            configurations.archives.artifacts.all {
-                version = project.getProperty('publishPluginsVersion')
-            }
-        }
-
-        if (project.hasProperty("${project.name}-jar")) {
-            println("Using pre-built artifact for ${project.name}")
-            configurations.archives.artifacts.clear()
-
-            artifacts {
-                archives(file(project.getProperty("${project.name}-jar"))) {
-                    name project.name
-                }
-            }
-        }
-
-        publishPlugins.doFirst {
-            assert !kotlinVersion.contains('SNAPSHOT')
-        }
-
-        pluginBundle {
-            website = 'https://kotlinlang.org/'
-            vcsUrl = 'https://github.com/JetBrains/kotlin/'
-            description = 'Kotlin plugins for Gradle'
-            tags = ['kotlin']
-
-            mavenCoordinates {
-                groupId = "org.jetbrains.kotlin"
-            }
-        }
-    }
-}
diff --git a/libraries/tools/kotlin-allopen/build.gradle b/libraries/tools/kotlin-allopen/build.gradle
index bc2b760..e541359 100644
--- a/libraries/tools/kotlin-allopen/build.gradle
+++ b/libraries/tools/kotlin-allopen/build.gradle
@@ -33,6 +33,8 @@
     archives javadocJar
 }
 
+GradlePluginPortalPublishingKt.publishToGradlePluginPortal(project)
+
 pluginBundle {
     plugins {
         kotlinAllopenPlugin {
diff --git a/libraries/tools/kotlin-gradle-plugin/build.gradle b/libraries/tools/kotlin-gradle-plugin/build.gradle
index f6467b1..dd7b1e5 100644
--- a/libraries/tools/kotlin-gradle-plugin/build.gradle
+++ b/libraries/tools/kotlin-gradle-plugin/build.gradle
@@ -128,6 +128,8 @@
     includes = ["${projectDir}/Module.md"]
 }
 
+GradlePluginPortalPublishingKt.publishToGradlePluginPortal(project)
+
 pluginBundle {
     plugins {
         kotlinJvmPlugin {
diff --git a/libraries/tools/kotlin-noarg/build.gradle b/libraries/tools/kotlin-noarg/build.gradle
index 8cc6ccf..93e779f 100644
--- a/libraries/tools/kotlin-noarg/build.gradle
+++ b/libraries/tools/kotlin-noarg/build.gradle
@@ -39,6 +39,8 @@
     archives javadocJar
 }
 
+GradlePluginPortalPublishingKt.publishToGradlePluginPortal(project)
+
 pluginBundle {
     plugins {
         kotlinNoargPlugin {