Skip to content

Commit

Permalink
Ability to pass GPG arguments to publish
Browse files Browse the repository at this point in the history
  • Loading branch information
joan38 committed May 5, 2020
1 parent 306454d commit 99d4f18
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 30 deletions.
46 changes: 26 additions & 20 deletions scalalib/src/PublishModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -114,23 +114,26 @@ trait PublishModule extends JavaModule { outer =>
)
}

/**
* Publish all given artifacts to Sonatype.
* @param gpgArgs GPG arguments. Defaults to `--batch --yes -a -b`.
* Specifying this will override/remove the defaults. Add the default args to your args to keep them.
*/
def publish(sonatypeCreds: String,
gpgPassphrase: String = null,
gpgKeyName: String = null,
signed: Boolean = true,
gpgArgs: Seq[String] = PublishModule.defaultGpgArgs,
release: Boolean,
readTimeout: Int = 60000,
connectTimeout: Int = 5000,
release: Boolean,
awaitTimeout: Int = 120 * 1000,
stagingRelease: Boolean = true): define.Command[Unit] = T.command {
val PublishModule.PublishData(artifactInfo, artifacts) = publishArtifacts()
new SonatypePublisher(
sonatypeUri,
sonatypeSnapshotUri,
sonatypeCreds,
Option(gpgPassphrase),
Option(gpgKeyName),
signed,
gpgArgs,
readTimeout,
connectTimeout,
T.log,
Expand All @@ -141,47 +144,50 @@ trait PublishModule extends JavaModule { outer =>
}

object PublishModule extends ExternalModule {
val defaultGpgArgs = Seq("--batch", "--yes", "-a", "-b")

case class PublishData(meta: Artifact, payload: Seq[(PathRef, String)])
object PublishData{
implicit def jsonify: upickle.default.ReadWriter[PublishData] = upickle.default.macroRW
}

/** An extra resource artifact to publish.
/**
* An extra resource artifact to publish.
* @param file The artifact file
* @param ivyCategory The ivy catogory (e.g. "jars", "zips")
* @param The file suffix including the file extension (e.g. "-with-deps.jar", "-dist.zip").
* It will be appended to the artifact id to construct the full file name.
* @param suffix The file suffix including the file extension (e.g. "-with-deps.jar", "-dist.zip").
* It will be appended to the artifact id to construct the full file name.
*/
case class ExtraPublish(file: PathRef, ivyCategory: String, suffix: String)
object ExtraPublish {
implicit def jsonify: upickle.default.ReadWriter[ExtraPublish] = upickle.default.macroRW
}


def publishAll(sonatypeCreds: String,
gpgPassphrase: String = null,
publishArtifacts: mill.main.Tasks[PublishModule.PublishData],
readTimeout: Int = 60000,
connectTimeout: Int = 5000,
/**
* Publish all given artifacts to Sonatype.
* @param gpgArgs GPG arguments. Defaults to `--batch --yes -a -b`.
* Specifying this will override/remove the defaults. Add the default args to your args to keep them.
*/
def publishAll(publishArtifacts: mill.main.Tasks[PublishModule.PublishData],
sonatypeCreds: String,
signed: Boolean = true,
gpgArgs: Seq[String] = defaultGpgArgs,
release: Boolean = false,
gpgKeyName: String = null,
sonatypeUri: String = "https://oss.sonatype.org/service/local",
sonatypeSnapshotUri: String = "https://oss.sonatype.org/content/repositories/snapshots",
signed: Boolean = true,
readTimeout: Int = 60000,
connectTimeout: Int = 5000,
awaitTimeout: Int = 120 * 1000,
stagingRelease: Boolean = true) = T.command {

stagingRelease: Boolean = true): Command[Unit] = T.command {
val x: Seq[(Seq[(os.Path, String)], Artifact)] = T.sequence(publishArtifacts.value)().map{
case PublishModule.PublishData(a, s) => (s.map{case (p, f) => (p.path, f)}, a)
}
new SonatypePublisher(
sonatypeUri,
sonatypeSnapshotUri,
sonatypeCreds,
Option(gpgPassphrase),
Option(gpgKeyName),
signed,
gpgArgs,
readTimeout,
connectTimeout,
T.log,
Expand Down
15 changes: 5 additions & 10 deletions scalalib/src/publish/SonatypePublisher.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ import os.Shellable
class SonatypePublisher(uri: String,
snapshotUri: String,
credentials: String,
gpgPassphrase: Option[String],
gpgKeyName: Option[String],
signed: Boolean,
gpgArgs: Seq[String],
readTimeout: Int,
connectTimeout: Int,
log: Logger,
Expand All @@ -25,7 +24,6 @@ class SonatypePublisher(uri: String,
}

def publishAll(release: Boolean, artifacts: (Seq[(os.Path, String)], Artifact)*): Unit = {

val mappings = for ((fileMapping0, artifact) <- artifacts) yield {
val publishPath = Seq(
artifact.group.replace(".", "/"),
Expand All @@ -35,7 +33,7 @@ class SonatypePublisher(uri: String,
val fileMapping = fileMapping0.map { case (file, name) => (file, publishPath + "/" + name) }

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

artifact -> (fileMapping ++ signedArtifacts).flatMap {
Expand Down Expand Up @@ -122,7 +120,7 @@ class SonatypePublisher(uri: String,
}

private def reportPublishResults(publishResults: Seq[requests.Response],
artifacts: Seq[Artifact]) = {
artifacts: Seq[Artifact]): Unit = {
if (publishResults.forall(_.is2xx)) {
log.info(s"Published ${artifacts.map(_.id).mkString(", ")} to Sonatype")
} else {
Expand Down Expand Up @@ -154,12 +152,9 @@ class SonatypePublisher(uri: String,
}

// http://central.sonatype.org/pages/working-with-pgp-signatures.html#signing-a-file
private def poorMansSign(file: os.Path, maybePassphrase: Option[String], maybeKeyName: Option[String]): os.Path = {
private def gpgSigned(file: os.Path, args: Seq[String]): os.Path = {
val fileName = file.toString
val optionFlag = (flag: String, ov: Option[String]) => ov.map(flag :: _ :: Nil).getOrElse(Nil)
val command = "gpg" ::
optionFlag("--passphrase", maybePassphrase) ++ optionFlag("-u", maybeKeyName) ++
Seq("--batch", "--yes", "-a", "-b", fileName)
val command = "gpg" +: args :+ fileName

os.proc(command.map(v => v: Shellable))
.call(stdin = os.Inherit, stdout = os.Inherit, stderr = os.Inherit)
Expand Down

0 comments on commit 99d4f18

Please sign in to comment.