diff options
Diffstat (limited to 'scalalib')
-rw-r--r-- | scalalib/src/mill/scalalib/PublishModule.scala | 40 | ||||
-rw-r--r-- | scalalib/src/mill/scalalib/publish/SonatypePublisher.scala | 90 |
2 files changed, 79 insertions, 51 deletions
diff --git a/scalalib/src/mill/scalalib/PublishModule.scala b/scalalib/src/mill/scalalib/PublishModule.scala index 8dfa0663..5c8b35e6 100644 --- a/scalalib/src/mill/scalalib/PublishModule.scala +++ b/scalalib/src/mill/scalalib/PublishModule.scala @@ -2,8 +2,9 @@ package mill package scalalib import ammonite.ops._ -import mill.define.Task +import mill.define.{ExternalModule, Task} import mill.eval.{PathRef, Result} +import mill.scalalib.publish.SonatypePublisher import mill.util.Loose.Agg /** * Configuration necessary for publishing a Scala module to Maven Central or similar @@ -60,20 +61,43 @@ trait PublishModule extends ScalaModule { outer => def sonatypeSnapshotUri: String = "https://oss.sonatype.org/content/repositories/snapshots" - def publish(sonatypeCreds: String, gpgPassphrase: String): define.Command[Unit] = T.command { + def publishArtifacts = T{ val baseName = s"${artifactId()}-${publishVersion()}" - val artifacts = Seq( - jar().path -> s"${baseName}.jar", - sourcesJar().path -> s"${baseName}-sources.jar", - docsJar().path -> s"${baseName}-javadoc.jar", - pom().path -> s"${baseName}.pom" + Seq( + jar().path -> s"$baseName.jar", + sourcesJar().path -> s"$baseName-sources.jar", + docsJar().path -> s"$baseName-javadoc.jar", + pom().path -> s"$baseName.pom" ) + } + + def publish(sonatypeCreds: String, gpgPassphrase: String): define.Command[Unit] = T.command { new SonatypePublisher( sonatypeUri, sonatypeSnapshotUri, sonatypeCreds, gpgPassphrase, T.ctx().log - ).publish(artifacts, artifact()) + ).publish(publishArtifacts(), artifact()) } } +object PublishModule extends ExternalModule{ + def publishAll(sonatypeCreds: String, + gpgPassphrase: String, + modules: Seq[PublishModule], + sonatypeUri: String = "https://oss.sonatype.org/service/local", + sonatypeSnapshotUri: String = "https://oss.sonatype.org/content/repositories/snapshots") = T.task{ + new SonatypePublisher( + sonatypeUri, + sonatypeSnapshotUri, + sonatypeCreds, + gpgPassphrase, + T.ctx().log + ).publishAll( + Task.traverse(modules)( + m => T.task{(m.publishArtifacts(), m.artifact())} + )():_* + ) + } + def millDiscover = mill.define.Discover[this.type] +}
\ No newline at end of file diff --git a/scalalib/src/mill/scalalib/publish/SonatypePublisher.scala b/scalalib/src/mill/scalalib/publish/SonatypePublisher.scala index 52271a48..1f00074c 100644 --- a/scalalib/src/mill/scalalib/publish/SonatypePublisher.scala +++ b/scalalib/src/mill/scalalib/publish/SonatypePublisher.scala @@ -16,64 +16,68 @@ class SonatypePublisher(uri: String, private val api = new SonatypeHttpApi(uri, credentials) - def publish(artifacts: Seq[(Path, String)], artifact: Artifact): Unit = { - val signedArtifacts = artifacts ++ artifacts.map { - case (file, name) => - poorMansSign(file, gpgPassphrase) -> s"${name}.asc" - } + def publish(fileMapping: Seq[(Path, String)], artifact: Artifact): Unit = { + publishAll(fileMapping -> artifact) + } + def publishAll(artifacts: (Seq[(Path, String)], Artifact)*): Unit = { - val signedArtifactsWithDigest = signedArtifacts.flatMap { - case (file, name) => - val content = read.bytes(file) + val mappings = for ((fileMapping, artifact) <- artifacts) yield { + val publishPath = Seq( + artifact.group.replace(".", "/"), + artifact.id, + artifact.version + ).mkString("/") - Seq( - name -> content, - (name + ".md5") -> md5hex(content), - (name + ".sha1") -> sha1hex(content) - ) - } + val signedArtifacts = fileMapping ++ fileMapping.map { + case (file, name) => poorMansSign(file, gpgPassphrase) -> s"$name.asc" + } + + artifact -> signedArtifacts.flatMap { + case (file, name) => + val content = read.bytes(file) - val publishPath = Seq( - artifact.group.replace(".", "/"), - artifact.id, - artifact.version - ).mkString("/") + Seq( + name -> content, + (name + ".md5") -> md5hex(content), + (name + ".sha1") -> sha1hex(content) + ) + } + } - if (artifact.isSnapshot) - publishSnapshot(publishPath, signedArtifactsWithDigest, artifact) - else - publishRelease(publishPath, signedArtifactsWithDigest, artifact) + val (snapshots, nonSnapshots) = mappings.partition(_._1.isSnapshot) + if(snapshots.nonEmpty) { + publishSnapshot(snapshots.flatMap(_._2), snapshots.map(_._1)) + } + if(nonSnapshots.nonEmpty) { + publishRelease(nonSnapshots.flatMap(_._2), nonSnapshots.map(_._1)) + } } - private def publishSnapshot(publishPath: String, - payloads: Seq[(String, Array[Byte])], - artifact: Artifact): Unit = { - val baseUri: String = snapshotUri + "/" + publishPath + private def publishSnapshot(payloads: Seq[(String, Array[Byte])], + artifacts: Seq[Artifact]): Unit = { val publishResults = payloads.map { case (fileName, data) => - log.info(s"Uploading ${fileName}") - val resp = api.upload(s"${baseUri}/${fileName}", data) + log.info(s"Uploading $fileName") + val resp = api.upload(s"$snapshotUri/$fileName", data) resp } - reportPublishResults(publishResults, artifact) + reportPublishResults(publishResults, artifacts) } - private def publishRelease(publishPath: String, - payloads: Seq[(String, Array[Byte])], - artifact: Artifact): Unit = { - val profileUri = api.getStagingProfileUri(artifact.group) + private def publishRelease(payloads: Seq[(String, Array[Byte])], + artifacts: Seq[Artifact]): Unit = { + val profileUri = api.getStagingProfileUri(artifacts.map(_.group).mkString("-")) val stagingRepoId = - api.createStagingRepo(profileUri, artifact.group) - val baseUri = - s"${uri}/staging/deployByRepositoryId/${stagingRepoId}/${publishPath}" + api.createStagingRepo(profileUri, artifacts.map(_.group).mkString("-")) + val baseUri = s"$uri/staging/deployByRepositoryId/$stagingRepoId/" val publishResults = payloads.map { case (fileName, data) => log.info(s"Uploading ${fileName}") - api.upload(s"${baseUri}/${fileName}", data) + api.upload(s"$baseUri/$fileName", data) } - reportPublishResults(publishResults, artifact) + reportPublishResults(publishResults, artifacts) log.info("Closing staging repository") api.closeStagingRepo(profileUri, stagingRepoId) @@ -90,19 +94,19 @@ class SonatypePublisher(uri: String, log.info("Dropping staging repository") api.dropStagingRepo(profileUri, stagingRepoId) - log.info(s"Published ${artifact.id} successfully") + log.info(s"Published ${artifacts.map(_.id).mkString(", ")} successfully") } private def reportPublishResults(publishResults: Seq[HttpResponse[String]], - artifact: Artifact) = { + artifacts: Seq[Artifact]) = { if (publishResults.forall(_.is2xx)) { - log.info(s"Published ${artifact.id} to Sonatype") + log.info(s"Published v${artifacts.map(_.id).mkString(", ")} to Sonatype") } else { val errors = publishResults.filterNot(_.is2xx).map { response => s"Code: ${response.code}, message: ${response.body}" } throw new RuntimeException( - s"Failed to publish ${artifact.id} to Sonatype. Errors: \n${errors.mkString("\n")}" + s"Failed to publish ${artifacts.map(_.id).mkString(", ")} to Sonatype. Errors: \n${errors.mkString("\n")}" ) } } |