Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solves #345 : optional signing #346

Merged
merged 2 commits into from
May 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions scalalib/src/mill/scalalib/PublishModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package scalalib

import ammonite.ops._
import mill.define.{ExternalModule, Task}
import mill.eval.{PathRef, Result}
import mill.eval.PathRef
import mill.scalalib.publish.{Artifact, SonatypePublisher}
import mill.util.Loose.Agg

/**
* Configuration necessary for publishing a Scala module to Maven Central or similar
*/
Expand All @@ -17,11 +17,11 @@ trait PublishModule extends JavaModule { outer =>
def pomSettings: T[PomSettings]
def publishVersion: T[String]

def publishSelfDependency = T{
Artifact(pomSettings().organization, artifactId(), publishVersion()),
def publishSelfDependency = T {
Artifact(pomSettings().organization, artifactId(), publishVersion())
}

def publishXmlDeps = T.task{
def publishXmlDeps = T.task {
val ivyPomDeps = ivyDeps().map(resolvePublishDependency().apply(_))
val modulePomDeps = Task.sequence(moduleDeps.map(_.publishSelfDependency))()
ivyPomDeps ++ modulePomDeps.map(Dependency(_, Scope.Compile))
Expand Down Expand Up @@ -59,7 +59,7 @@ trait PublishModule extends JavaModule { outer =>

def sonatypeSnapshotUri: String = "https://oss.sonatype.org/content/repositories/snapshots"

def publishArtifacts = T{
def publishArtifacts = T {
val baseName = s"${artifactId()}-${publishVersion()}"
PublishModule.PublishData(
artifactMetadata(),
Expand All @@ -73,32 +73,35 @@ trait PublishModule extends JavaModule { outer =>
}

def publish(sonatypeCreds: String,
gpgPassphrase: String,
gpgPassphrase: String = null,
signed: Boolean = true,
release: Boolean): define.Command[Unit] = T.command {
val PublishModule.PublishData(artifactInfo, artifacts) = publishArtifacts()
new SonatypePublisher(
sonatypeUri,
sonatypeSnapshotUri,
sonatypeCreds,
gpgPassphrase,
Option(gpgPassphrase),
signed,
T.ctx().log
).publish(artifacts.map{case (a, b) => (a.path, b)}, artifactInfo, release)
}
}

object PublishModule extends ExternalModule{
object PublishModule extends ExternalModule {
case class PublishData(meta: Artifact, payload: Seq[(PathRef, String)])

object PublishData{
implicit def jsonify: upickle.default.ReadWriter[PublishData] = upickle.default.macroRW
}

def publishAll(sonatypeCreds: String,
gpgPassphrase: String,
gpgPassphrase: String = null,
signed: Boolean = true,
publishArtifacts: mill.main.Tasks[PublishModule.PublishData],
release: Boolean = false,
sonatypeUri: String = "https://oss.sonatype.org/service/local",
sonatypeSnapshotUri: String = "https://oss.sonatype.org/content/repositories/snapshots") = T.command{
sonatypeSnapshotUri: String = "https://oss.sonatype.org/content/repositories/snapshots") = T.command {

val x: Seq[(Seq[(Path, String)], Artifact)] = Task.sequence(publishArtifacts.value)().map{
case PublishModule.PublishData(a, s) => (s.map{case (p, f) => (p.path, f)}, a)
Expand All @@ -107,7 +110,8 @@ object PublishModule extends ExternalModule{
sonatypeUri,
sonatypeSnapshotUri,
sonatypeCreds,
gpgPassphrase,
Option(gpgPassphrase),
signed,
T.ctx().log
).publishAll(
release,
Expand Down
18 changes: 12 additions & 6 deletions scalalib/src/mill/scalalib/publish/SonatypePublisher.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import scalaj.http.HttpResponse
class SonatypePublisher(uri: String,
snapshotUri: String,
credentials: String,
gpgPassphrase: String,
gpgPassphrase: Option[String],
signed: Boolean,
log: Logger) {

private val api = new SonatypeHttpApi(uri, credentials)
Expand All @@ -29,11 +30,11 @@ class SonatypePublisher(uri: String,
).mkString("/")
val fileMapping = fileMapping0.map{ case (file, name) => (file, publishPath+"/"+name) }

val signedArtifacts = fileMapping ++ fileMapping.map {
val signedArtifacts = if (signed) fileMapping.map {
case (file, name) => poorMansSign(file, gpgPassphrase) -> s"$name.asc"
}
} else Seq()

artifact -> signedArtifacts.flatMap {
artifact -> (fileMapping ++ signedArtifacts).flatMap {
case (file, name) =>
val content = read.bytes(file)

Expand Down Expand Up @@ -135,10 +136,15 @@ class SonatypePublisher(uri: String,
}

// http://central.sonatype.org/pages/working-with-pgp-signatures.html#signing-a-file
private def poorMansSign(file: Path, passphrase: String): Path = {
private def poorMansSign(file: Path, maybePassphrase: Option[String]): Path = {
val fileName = file.toString
import ammonite.ops.ImplicitWd._
%("gpg", "--passphrase", passphrase, "--batch", "--yes", "-a", "-b", fileName)
maybePassphrase match {
case Some(passphrase) =>
%("gpg", "--passphrase", passphrase, "--batch", "--yes", "-a", "-b", fileName)
case None =>
%("gpg", "--batch", "--yes", "-a", "-b", fileName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it useful to sign artifacts without gpgPassphrase ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I honestly don't know if it's useful, but I'm following Haoyi's comment :

#345 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I didn't notice that. All good then

}
Path(fileName + ".asc")
}

Expand Down