diff --git a/.github/workflows/deploy_jvm.yml b/.github/workflows/deploy_jvm.yml index 047a7df015..ffbe6aa0b6 100644 --- a/.github/workflows/deploy_jvm.yml +++ b/.github/workflows/deploy_jvm.yml @@ -13,10 +13,10 @@ on: type: string env: - GODOT_KOTLIN_GPG_PRIVATE_KEY_ASCII: ${{ secrets.GODOT_KOTLIN_GPG_PRIVATE_KEY_ASCII }} + GODOT_KOTLIN_GPG_PRIVATE_KEY_ASCII: ${{ secrets.GODOT_KOTLIN_GPG_PRIVATE_KEY_ASCII_CLEANED }} # TODO: remove old key and rename this one once we're sure that the new deployment works GODOT_KOTLIN_GPG_KEY_PASSPHRASE: ${{ secrets.GODOT_KOTLIN_GPG_KEY_PASSPHRASE }} - GODOT_KOTLIN_MAVEN_CENTRAL_TOKEN_USERNAME: ${{ secrets.GODOT_KOTLIN_MAVEN_CENTRAL_TOKEN_USERNAME }} - GODOT_KOTLIN_MAVEN_CENTRAL_TOKEN_PASSWORD: ${{ secrets.GODOT_KOTLIN_MAVEN_CENTRAL_TOKEN_PASSWORD }} + GODOT_KOTLIN_MAVEN_CENTRAL_PORTAL_TOKEN_USERNAME: ${{ secrets.GODOT_KOTLIN_MAVEN_CENTRAL_PORTAL_TOKEN_USERNAME }} # TODO: remove old username and password from secrets once we're sure the deployment works + GODOT_KOTLIN_MAVEN_CENTRAL_PORTAL_TOKEN_PASSWORD: ${{ secrets.GODOT_KOTLIN_MAVEN_CENTRAL_PORTAL_TOKEN_PASSWORD }} # TODO: remove old username and password from secrets once we're sure the deployment works GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }} GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }} GODOT_KOTLIN_INTELLIJ_PLUGIN_PUBLISH: ${{secrets.GODOT_KOTLIN_INTELLIJ_PLUGIN_PUBLISH }} @@ -47,6 +47,14 @@ jobs: with: cache-read-only: ${{ github.ref != 'refs/heads/master' }} + - name: Setup publish gradle properties + shell: sh + run: | + echo "mavenCentralUsername=$GODOT_KOTLIN_MAVEN_CENTRAL_PORTAL_TOKEN_USERNAME" >> ~/.gradle/gradle.properties + echo "mavenCentralPassword=$GODOT_KOTLIN_MAVEN_CENTRAL_PORTAL_TOKEN_PASSWORD" >> ~/.gradle/gradle.properties + echo "signingInMemoryKey=$GODOT_KOTLIN_GPG_PRIVATE_KEY_ASCII" >> ~/.gradle/gradle.properties + echo "signingInMemoryKeyPassword=$GODOT_KOTLIN_GPG_KEY_PASSPHRASE" >> ~/.gradle/gradle.properties + - name: Publish common shell: sh run: | diff --git a/kt/build-logic/convention/build.gradle.kts b/kt/build-logic/convention/build.gradle.kts index b67b6876a8..cc86ff0e54 100644 --- a/kt/build-logic/convention/build.gradle.kts +++ b/kt/build-logic/convention/build.gradle.kts @@ -12,6 +12,7 @@ kotlin { dependencies { compileOnly(kotlin("gradle-plugin", version = libs.versions.kotlin.get())) implementation(libs.grgit) + implementation(libs.maven.publish) } gradlePlugin { diff --git a/kt/build-logic/convention/src/main/kotlin/publish/PublishToMavenCentralPlugin.kt b/kt/build-logic/convention/src/main/kotlin/publish/PublishToMavenCentralPlugin.kt index 6765345134..fd31c313d8 100644 --- a/kt/build-logic/convention/src/main/kotlin/publish/PublishToMavenCentralPlugin.kt +++ b/kt/build-logic/convention/src/main/kotlin/publish/PublishToMavenCentralPlugin.kt @@ -1,83 +1,45 @@ + package publish +import com.vanniktech.maven.publish.MavenPublishBaseExtension +import com.vanniktech.maven.publish.MavenPublishPlugin +import com.vanniktech.maven.publish.SonatypeHost import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.plugins.JavaPluginExtension import org.gradle.api.publish.PublishingExtension import org.gradle.api.publish.maven.MavenPublication -import org.gradle.api.tasks.SourceSetContainer -import org.gradle.jvm.tasks.Jar import org.gradle.plugins.signing.Sign -import org.gradle.plugins.signing.SigningExtension +@Suppress("unused") // false positive class PublishToMavenCentralPlugin : Plugin { override fun apply(target: Project) { - target.plugins.apply("maven-publish") - - val ossrhUser = target.propOrEnv("GODOT_KOTLIN_MAVEN_CENTRAL_TOKEN_USERNAME") - val ossrhPassword = target.propOrEnv("GODOT_KOTLIN_MAVEN_CENTRAL_TOKEN_PASSWORD") - val signingKey = target.propOrEnv("GODOT_KOTLIN_GPG_PRIVATE_KEY_ASCII") - val signingPassword = target.propOrEnv("GODOT_KOTLIN_GPG_KEY_PASSPHRASE") - val canSign = ossrhUser != null && ossrhPassword != null && signingKey != null && signingPassword != null - - if (canSign) { - target.plugins.apply("signing") - target.logger.info("Will sign artifact for project \"${target.name}\" and setup publishing") - } else { - target.logger.warn("Cannot sign project \"${target.name}\" as credentials are missing. Will not setup signing and remote publishing credentials. Publishing will only work to maven local!") - } - - target.afterEvaluate { project -> - val isReleaseMode = !(project.version as String).endsWith("-SNAPSHOT") - - if (canSign) { // for local development, If missing in CI it will fail later on deploy so we would notice the issue then - project.extensions.configure(SigningExtension::class.java) { signingExtension -> - signingExtension.useInMemoryPgpKeys(signingKey, signingPassword) - project.extensions.findByType(PublishingExtension::class.java)?.publications?.all { publication -> - signingExtension.sign(publication) - } - } - } + target.plugins.apply(org.gradle.api.publish.maven.plugins.MavenPublishPlugin::class.java) - project.extensions.getByType(JavaPluginExtension::class.java).apply { - withSourcesJar() - withJavadocJar() - } + target.afterEvaluate { evaluatedProject -> + val mavenCentralUser = target.propOrEnv("GODOT_KOTLIN_MAVEN_CENTRAL_PORTAL_TOKEN_USERNAME") ?: target.propOrEnv("mavenCentralUsername") + val mavenCentralPassword = target.propOrEnv("GODOT_KOTLIN_MAVEN_CENTRAL_PORTAL_TOKEN_PASSWORD") ?: target.propOrEnv("mavenCentralPassword") + val gpgInMemoryKey = target.propOrEnv("GODOT_KOTLIN_GPG_PRIVATE_KEY_ASCII") ?: target.propOrEnv("signingInMemoryKey") + val gpgPassword = target.propOrEnv("GODOT_KOTLIN_GPG_KEY_PASSPHRASE") ?: target.propOrEnv("signingInMemoryKeyPassword") - project.extensions.getByType(PublishingExtension::class.java).apply { - repositories.apply { - maven { mavenArtifactRepository -> - val targetRepo = if (isReleaseMode) { - "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/" - } else { - "https://s01.oss.sonatype.org/content/repositories/snapshots/" - } - mavenArtifactRepository.setUrl(targetRepo) + val canSign = mavenCentralUser != null && mavenCentralPassword != null && gpgInMemoryKey != null && gpgPassword != null - if (canSign) { - mavenArtifactRepository.credentials { passwordCredentials -> - passwordCredentials.username = ossrhUser - passwordCredentials.password = ossrhPassword - } - } - } - } + target.extensions.getByType(PublishingExtension::class.java).apply { publications { publicationContainer -> publicationContainer.all { publication -> if (publication is MavenPublication) { publication.groupId = "com.utopia-rise" val artifactId = publication.artifactId - publication.artifactId = if (artifactId.isNullOrEmpty()) project.name else artifactId - publication.version = project.version as String + publication.artifactId = if (artifactId.isNullOrEmpty()) target.name else artifactId + publication.version = target.version as String publication.pom { mavenPom -> mavenPom.url.set("https://github.com/utopia-rise/godot-kotlin-jvm.git") if (mavenPom.name.getOrElse("").isNullOrEmpty()) { - mavenPom.name.set(project.name) + mavenPom.name.set(target.name) } if (mavenPom.description.getOrElse("").isNullOrEmpty()) { - mavenPom.description.set(project.description ?: "Godot kotlin jvm module") + mavenPom.description.set(target.description ?: "Godot kotlin jvm module") } mavenPom.scm { mavenPomScm -> @@ -127,20 +89,33 @@ class PublishToMavenCentralPlugin : Plugin { } } + if (canSign) { - project - .tasks - .filter { task -> task.name.startsWith("publish") } - .forEach { task -> - task.dependsOn(project.tasks.withType(Sign::class.java)) - } + evaluatedProject.logger.info("Will sign artifact for project \"${evaluatedProject.name}\" and setup publishing") + + evaluatedProject.pluginManager.apply(MavenPublishPlugin::class.java) + evaluatedProject.extensions.getByType(MavenPublishBaseExtension::class.java).apply { + publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) + signAllPublications() + } + + target.afterEvaluate { + target + .tasks + .filter { task -> task.name.startsWith("publish") } + .forEach { task -> + task.dependsOn(target.tasks.withType(Sign::class.java)) + } + } + } else { + evaluatedProject.logger.warn("Cannot sign project \"${evaluatedProject.name}\" as credentials are missing. Will not setup signing and remote publishing credentials. Publishing will only work to maven local!") } } } } fun Project.propOrEnv(name: String): String? { - var property: String? = findProperty(name) as String? + var property: String? = findProperty(name) as? String? if (property == null) { property = System.getenv(name) } diff --git a/kt/gradle/libs.versions.toml b/kt/gradle/libs.versions.toml index 83b927fc71..c9ac1a6931 100644 --- a/kt/gradle/libs.versions.toml +++ b/kt/gradle/libs.versions.toml @@ -21,6 +21,7 @@ jacksonDataFormatXml = "2.18.2" # https://mvnrepository.com/artifact/com.fasterx grgit = "5.3.0" # https://github.com/ajoberstar/grgit/releases gradlePublish = "1.3.1" # https://plugins.gradle.org/plugin/com.gradle.plugin-publish +maven-publish="0.32.0" # https://github.com/vanniktech/gradle-maven-publish-plugin/releases changelog = "2.2.1" # https://github.com/JetBrains/gradle-changelog-plugin/releases gradleIntelliJPlugin = "2.3.0" # https://github.com/JetBrains/intellij-platform-gradle-plugin/releases @@ -41,6 +42,8 @@ jacksonDataFormatXml = { module = "com.fasterxml.jackson.dataformat:jackson-data grgit = { module = "org.ajoberstar.grgit:grgit-gradle", version.ref = "grgit" } ideaSync = { module = "org.jetbrains.gradle.plugin.idea-ext:org.jetbrains.gradle.plugin.idea-ext.gradle.plugin", version.ref = "ideaSync" } +maven-publish = { group = "com.vanniktech", name = "gradle-maven-publish-plugin", version.ref = "maven-publish" } # needed for publishing to new maven central repositories + [plugins] changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" } gradleIntelliJPlugin = { id = "org.jetbrains.intellij.platform", version.ref = "gradleIntelliJPlugin" }