Skip to content

Commit

Permalink
Maven Central Sync implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
natario1 committed Jun 5, 2024
1 parent 96f261e commit f7fb8f3
Show file tree
Hide file tree
Showing 25 changed files with 918 additions and 290 deletions.
68 changes: 68 additions & 0 deletions .idea/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 10 additions & 9 deletions deployer/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
@file:Suppress("UnstableApiUsage")

import io.deepmedia.tools.deployer.impl.SonatypeAuth
import io.deepmedia.tools.deployer.model.DeploySpec
import io.deepmedia.tools.deployer.model.Secret
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.targets

plugins {
`kotlin-dsl`
`java-gradle-plugin`
id("io.deepmedia.tools.deployer") version "0.11.0-rc01"
id("io.deepmedia.tools.deployer") version "0.12.0-rc1"
kotlin("plugin.serialization") version "1.9.23"
}

dependencies {
compileOnly("com.android.tools.build:gradle:8.0.2")
compileOnly("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.23")

api("org.jetbrains.dokka:dokka-gradle-plugin:1.8.20")

implementation("io.ktor:ktor-client-core:2.3.11")
implementation("io.ktor:ktor-client-cio:2.3.11")
implementation("io.ktor:ktor-client-content-negotiation:2.3.11")
implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.11")
}

// Gradle 7.X has embedded kotlin version 1.6, but kotlin-dsl plugins are compiled with 1.4 for compatibility with older
Expand Down Expand Up @@ -46,7 +46,7 @@ gradlePlugin {
}

group = "io.deepmedia.tools.deployer"
version = "0.11.0" // on change, update both docs and README
version = "0.12.0-rc1" // on change, update both docs and README

deployer {
verbose = true
Expand Down Expand Up @@ -79,6 +79,7 @@ deployer {
sonatypeSpec {
auth.user = secret("SONATYPE_USER")
auth.password = secret("SONATYPE_PASSWORD")
syncToMavenCentral = true
}

// use "deploySonatypeSnapshot" to deploy to sonatype snapshots repo
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,48 @@
package io.deepmedia.tools.deployer

import io.deepmedia.tools.deployer.model.AbstractDeploySpec
import io.deepmedia.tools.deployer.model.Component
import org.gradle.api.Project
import org.gradle.api.logging.LogLevel
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.publish.maven.internal.publication.MavenPublicationInternal
import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.withType
import org.gradle.plugins.signing.Sign
import org.gradle.plugins.signing.SigningExtension
import org.gradle.plugins.signing.signatory.pgp.PgpSignatory
import org.gradle.security.internal.pgp.BaseInMemoryPgpSignatoryProvider

/**
* Note: with respect to official docs, we do the extra step of fetching the signatory
* (which [SigningExtension] generates after [SigningExtension.useInMemoryPgpKeys]) and pass that again
* to the task using [Sign.setSignatory].
*
* This may be helpful in case different key-password pairs are defined for different publications,
* which our API allows, while the [SigningExtension] is a project-wide item. There's the risk that
* at execution time, all tasks use the last key-value pair which is not what we want.
*/
internal fun Project.configureSigning(
spec: AbstractDeploySpec<*>,
info: Pair<String, String>,
maven: MavenPublication,
log: Logger
): Sign? {
// Configure signing if present
val signInfo = spec.resolveSigning(this)
if (signInfo != null) {
log { "configureSigning: signing MavenPublication ${maven.name}" }
val ext = extensions.getByType(SigningExtension::class)
val (key, password) = signInfo
ext.useInMemoryPgpKeys(key, password)
try {
return ext.sign(maven).single()
} catch (e: Throwable) {
logger.log(
LogLevel.WARN, "Two or more specs share the same MavenPublication under the hood! " +
"Only one of the signatures will be used, and other configuration parameters " +
"might be conflicting as well. Location: ${log.prefix} [${e.message}]")
}
): Sign {
log { "configureSigning: signing MavenPublication ${maven.name}" }

// If this publication is shared between specs, there's a chance that the sign task already exists.
// Note that we have no way of verifying whether that spec used the same key-password pair, so we warn.
val previous = tasks.withType<Sign>().findByName("sign${maven.name.capitalized()}")
if (previous != null) {
logger.log(
LogLevel.WARN, "Two or more specs share the same MavenPublication under the hood! " +
"Only one of the signatures will be used, and other configuration parameters " +
"might be conflicting too. Location: ${log.prefix}")
return previous
}

val ext = extensions.getByType(SigningExtension::class)
ext.useInMemoryPgpKeys(info.first, info.second)
val signatory = ext.signatory
return ext.sign(maven).single().apply {
setSignatory(signatory)
}
return null
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
package io.deepmedia.tools.deployer

import io.deepmedia.tools.deployer.impl.*
import io.deepmedia.tools.deployer.model.*
import io.deepmedia.tools.deployer.specs.*
import org.gradle.api.Action
import org.gradle.api.PolymorphicDomainObjectContainer
import org.gradle.api.model.ObjectFactory
import org.gradle.kotlin.dsl.newInstance
import org.gradle.kotlin.dsl.polymorphicDomainObjectContainer
import org.gradle.kotlin.dsl.property
import javax.inject.Inject

open class DeployerExtension @Inject constructor(target: org.gradle.api.Project) : SecretScope, DeploySpec by DefaultDeploySpec(target) {
open class DeployerExtension @Inject constructor(private val objects: ObjectFactory) : SecretScope, DeploySpec by DefaultDeploySpec(objects) {

val verbose = target.objects.property<Boolean>().convention(false)
val verbose = objects.property<Boolean>().convention(false)

private val objects = target.objects
// TODO: make this public. The problem is that OssrhService is a shared service and so it doesn't make sense to
// configure values in a single gradle subproject (the first one would win)
internal val mavenCentralSync = objects.newInstance<SonatypeMavenCentralSync>()
internal fun mavenCentralSync(action: Action<SonatypeMavenCentralSync>) { action.execute(mavenCentralSync) }

@Deprecated("DeployerExtension now *is* the default spec. Simply use `this`.")
val defaultSpec get() = this
Expand All @@ -22,12 +27,6 @@ open class DeployerExtension @Inject constructor(target: org.gradle.api.Project)
action.execute(defaultSpec)
}

init {
target.whenEvaluated {
resolve(target)
}
}

fun auth(action: Action<Auth>) { action.execute(auth) }
fun content(action: Action<Content>) { action.execute(content) }
fun projectInfo(action: Action<ProjectInfo>) { action.execute(projectInfo) }
Expand All @@ -41,7 +40,7 @@ open class DeployerExtension @Inject constructor(target: org.gradle.api.Project)
}

private fun specName(current: String, default: String): String {
return if (current.startsWith(default)) current else "$default${current.capitalize()}"
return if (current.startsWith(default)) current else "$default${current.capitalized()}"
}

fun localSpec(name: String = "local", configure: Action<LocalDeploySpec> = Action { }) {
Expand Down
Loading

0 comments on commit f7fb8f3

Please sign in to comment.