Skip to content

Commit

Permalink
Adding relese script and bintray publishing
Browse files Browse the repository at this point in the history
  • Loading branch information
jsuereth committed Oct 10, 2014
1 parent 10091f7 commit 423c4df
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 34 deletions.
4 changes: 3 additions & 1 deletion pgp-plugin/src/main/scala/com/typesafe/sbt/SbtPgp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ object SbtPgp extends AutoPlugin {

override def trigger = allRequirements

object autoImport {
// Note - workaround for issues in sbt 0.13.5 autoImport
object autoImportImpl {

val PgpKeys = pgp.PgpKeys

Expand All @@ -38,6 +39,7 @@ object SbtPgp extends AutoPlugin {

def signingSettings = PgpSettings.signingSettings
}
val autoImport = autoImportImpl
// TODO - Maybe signing settigns should be a different plugin...
override val projectSettings = PgpSettings.projectSettings
override val buildSettings = PgpSettings.globalSettings
Expand Down
7 changes: 7 additions & 0 deletions pgp-plugin/src/sbt-test/pgp-cmd/gen-key/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pgpSecretRing := baseDirectory.value / "secring.pgp"

pgpPublicRing := baseDirectory.value / "pubring.pgp"

pgpReadOnly := false

pgpPassphrase := Some("test password".toCharArray)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % sys.props("project.version"))
4 changes: 4 additions & 0 deletions pgp-plugin/src/sbt-test/pgp-cmd/gen-key/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
> pgp-cmd gen-key

$ exists secring.pgp
$ exists pubring.pgp
63 changes: 63 additions & 0 deletions project/Release.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import sbt._
import Keys._

import complete.DefaultParsers._
import complete.Parser

object Release {

This comment has been minimized.

Copy link
@eed3si9n

eed3si9n Oct 10, 2014

Member

Should this whole thing be a plugin on it's own?

This comment has been minimized.

Copy link
@jsuereth

jsuereth Oct 10, 2014

Author Member

maybe, or I can learn the release plugin.


val versionNumberParser: Parser[String] = {
val classifier: Parser[String] = ("-" ~ ID) map {
case (dash, id) => dash + id
}
val version: Parser[String] = (Digit ~ chars(".0123456789").* ~ classifier) map {
case ((first, rest), rest2) => ((first +: rest).mkString + rest2)
}
val complete = (chars("v") ~ token(version, "<version number>")) map {
case (v, num) => v + num
}
complete
}

def releaseParser(state: State): Parser[String] =
Space ~> versionNumberParser


val releaseHelp = Help("release",
"release <git tag>" -> "Runs the release script for a given version number",
"""|release <git tag>
|
|Runs our release script. This will:
|1. Run all the tests (unit + scripted) for the current OS.
|2. Tag the git repo with the given tag (v<version>).
|3. Reload the build with the new version number from the git tag.
|4. publish all the artifacts to bintray.""".stripMargin
)

def scriptedForPlatform: String = {
// TODO - Implement. Instead of only running tests we can, we should
// probably ping some service to see if all platform tests have
// succeeded.
"scripted universal/* debian/* rpm/*"
}

def releaseAction(state: State, tag: String): State = {
// TODO - Ensure we're releasing on JDK 6, so we're binary compatible.
// First check to ensure we have a sane publishing environment...
"bintrayCheckCredentials" ::
"all test scripted" ::
// TODO - Signed tags, possibly using pgp keys?
("git tag " + tag) ::
"reload" ::
"all library/publishSigned plugin/publishSigned" ::
"bintrayPublishAllStaged" ::
("git push origin " + tag) ::
state
}

val releaseCommand =
Command("release", releaseHelp)(releaseParser)(releaseAction)

def settings: Seq[Setting[_]]=
Seq(commands += releaseCommand)
}
54 changes: 54 additions & 0 deletions project/bintray.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import sbt._
import sbt.Keys._

object Bintray {
val bintrayPublishAllStaged = taskKey[Unit]("Publish all staged artifacts on bintray.")
val checkBintrayCredentials = taskKey[Unit]("Checks to see if bintray credentials are configured.")
val bintrayRepoId = settingKey[String]("The project id in bintray.")
val bintrayUserId = settingKey[String]("The user we have in bintray.")
val bintrayPublishToUrl = settingKey[String]("The url we'll publish to.")
val bintrayLayout = settingKey[String]("pattern we use when publishing to bintray.")
// val bintrayPluginUrl = "https://api.bintray.com/content/sbt/sbt-plugin-releases/"
//val bintrayPluginLayout = "[module]/[revision]/"+ Resolver.localBasePattern

def bintrayCreds(creds: Seq[sbt.Credentials]): (String, String) = {
val matching =
for {
c <- creds
if c.isInstanceOf[sbt.DirectCredentials]
val cred = c.asInstanceOf[sbt.DirectCredentials]
if cred.host == "api.bintray.com"
} yield cred.userName -> cred.passwd

matching.headOption getOrElse sys.error("Unable to find bintray credentials (api.bintray.com)")
}

def publishContent(pkg: String, subject: String, repo: String, version: String, creds: Seq[sbt.Credentials]): Unit = {
val uri = s"https://bintray.com/api/v1/content/$subject/$repo/$pkg/$version/publish"
val (u,p) = bintrayCreds(creds)
import dispatch.classic._
// TODO - Log the output
Http(url(uri).POST.as(u,p).>|)
}

def settings: Seq[Setting[_]] =
Seq(
bintrayRepoId := "sbt-plugin-releases",
bintrayUserId := "sbt",
bintrayLayout := s"${normalizedName.value}/[revision]/${Resolver.localBasePattern}",
bintrayPublishToUrl := s"https://api.bintray.com/content/${bintrayUserId.value}/${bintrayRepoId.value}/",
publishTo := {
val resolver = Resolver.url("bintray-"+bintrayRepoId.value, new URL(bintrayPublishToUrl.value))(Patterns(false, bintrayLayout.value))
Some(resolver)
},
checkBintrayCredentials := {
val creds = credentials.value
val (user, _) = bintrayCreds(creds)
streams.value.log.info(s"Using $user for bintray login.")
},
bintrayPublishAllStaged := {
val creds = credentials.value
publishContent(projectID.value.name, bintrayUserId.value, bintrayRepoId.value, version.value, creds)
}
)
}
45 changes: 12 additions & 33 deletions project/build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,6 @@ object SbtPgpBuild extends Build {
override val settings: Seq[Setting[_]] =
super.settings ++ versionWithGit

// Sonatype Publishing gunk
def sonatypePublishSettings: Seq[Setting[_]] = Seq(
// If we want on maven central, we need to be in maven style.
publishMavenStyle := true,
publishArtifact in Test := false,
// The Nexus repo we're publishing to.
publishTo <<= version { (v: String) =>
val nexus = "https://oss.sonatype.org/"
if (v.trim.endsWith("SNAPSHOT")) Some("snapshots" at nexus + "content/repositories/snapshots")
else Some("releases" at nexus + "service/local/staging/deploy/maven2")
},
// Maven central cannot allow other repos. We're ok here because the artifacts we
// we use externally are *optional* dependencies.
pomIncludeRepository := { x => false },
licenses += ("BSD" -> url("http://www.opensource.org/licenses/bsd-license.php")),
homepage := Some(url("http://scala-sbt.org/sbt-pgp/")),
scmInfo := Some(ScmInfo(url("http://github.com/sbt/sbt-pgp/"),"git://github.com/sbt/sbt-pgp.git")),
// Maven central wants some extra metadata to keep things 'clean'.
pomExtra := (
<developers>
<developer>
<id>jsuereth</id>
<name>Josh Suereth</name>
</developer>
</developers>)
)

// Website publishing settings.
def websiteSettings: Seq[Setting[_]] = (
site.settings ++
Expand All @@ -62,7 +35,7 @@ object SbtPgpBuild extends Build {
else ("sbt-plugin-releases", scalasbt+"sbt-plugin-releases")
Some(Resolver.url(name, url(u))(Resolver.ivyStylePatterns))
}
)
) ++ Bintray.settings

// Dependencies
val dispatchDependency = "net.databinder" %% "dispatch-http" % "0.8.10"
Expand All @@ -76,24 +49,30 @@ object SbtPgpBuild extends Build {
Project("sbt-pgp", file("."))
aggregate(plugin, library)
settings(websiteSettings:_*)
// Until this plugin is fixed for 0.13.5, we can't do this
// disablePlugins(plugins.IvyPlugin)
settings(
publishLocal := (),
publish := ()
publish := (),
publishLocal := ()
)
settings(Release.settings:_*)
)

import sbt.ScriptedPlugin._

// The sbt plugin.
lazy val plugin = Project("plugin", file("pgp-plugin")) dependsOn(library) settings(commonSettings:_*) settings(
sbtPlugin := true,
organization := "com.typesafe.sbt",
name := "sbt-pgp",
libraryDependencies += dispatchDependency
) settings(websiteSettings:_*)
) settings(websiteSettings:_*) settings(scriptedSettings:_*) settings(
scriptedLaunchOpts += s"-Dproject.version=${version.value}"
)

// The library of PGP functions.
// Note: We're going to just publish this to the sbt repo now.
lazy val library = Project("library", file("gpg-library")) settings(commonSettings:_*) settings(
name := "gpg-library",
name := "pgp-library",
libraryDependencies ++= Seq(bouncyCastlePgp, dispatchDependency, specs2 % "test", sbtIo % "test")
)
}
2 changes: 2 additions & 0 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.5.1")

addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.6.2")

libraryDependencies += "org.scala-sbt" % "scripted-plugin" % sbtVersion.value


0 comments on commit 423c4df

Please sign in to comment.