summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sc23
-rw-r--r--scalalib/src/mill/scalalib/PublishModule.scala40
-rw-r--r--scalalib/src/mill/scalalib/publish/SonatypePublisher.scala90
3 files changed, 94 insertions, 59 deletions
diff --git a/build.sc b/build.sc
index c77a9eda..ea016d96 100755
--- a/build.sc
+++ b/build.sc
@@ -227,7 +227,7 @@ def publishVersion = T.input{
}
def uploadToGithub(assembly: Path, authKey: String, release: String, label: String) = {
- if (release == "unstable"){
+ if (release != "unstable"){
scalaj.http.Http("https://api.github.com/repos/lihaoyi/mill/releases")
.postData(
upickle.json.write(
@@ -261,13 +261,20 @@ def releaseCI(githubAuthKey: String,
def releaseManual(githubAuthKey: String,
sonatypeCreds: String,
gpgPassphrase: String) = T.command{
- moduledefs.publish(sonatypeCreds, gpgPassphrase)()
- core.publish(sonatypeCreds, gpgPassphrase)()
- scalalib.publish(sonatypeCreds, gpgPassphrase)()
- scalajslib.publish(sonatypeCreds, gpgPassphrase)()
- scalaworker.publish(sonatypeCreds, gpgPassphrase)()
- scalajslib.jsbridges("0.6").publish(sonatypeCreds, gpgPassphrase)()
- scalajslib.jsbridges("1.0").publish(sonatypeCreds, gpgPassphrase)()
+ mill.scalalib.PublishModule.publishAll(
+ sonatypeCreds = sonatypeCreds,
+ gpgPassphrase = gpgPassphrase,
+ modules = Seq(
+ moduledefs,
+ core,
+ scalalib,
+ scalajslib,
+ scalaworker,
+ scalajslib.jsbridges("0.6"),
+ scalajslib.jsbridges("1.0")
+ )
+ )
+
val (release, label) = publishVersion()
uploadToGithub(releaseAssembly().path, githubAuthKey, release, label)
()
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")}"
)
}
}