From 5d631ebba2829fa10b66149a8405534cd2143a0d Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Sun, 4 Dec 2016 00:30:11 -0800 Subject: Refactor project to use .sbt build definitions and add continuous deployment script --- .ci/build | 38 +++++++++++ .ci/sec.gpg.enc | Bin 0 -> 4176 bytes .travis.yml | 27 ++++++-- build.sbt | 69 +++++++++++++++++--- flow-core/build.sbt | 8 +-- flow-native/build.sbt | 10 ++- flow-samples/terminal-stream/build.sbt | 3 - flow-samples/terminal/build.sbt | 3 - flow-samples/watcher/build.sbt | 3 - flow-stream/build.sbt | 6 +- project/Dependencies.scala | 4 +- project/FlowBuild.scala | 64 ------------------- project/Release.scala | 111 --------------------------------- project/plugins.sbt | 9 +-- version.sbt | 1 - 15 files changed, 134 insertions(+), 222 deletions(-) create mode 100755 .ci/build create mode 100644 .ci/sec.gpg.enc delete mode 100644 flow-samples/terminal-stream/build.sbt delete mode 100644 flow-samples/terminal/build.sbt delete mode 100644 flow-samples/watcher/build.sbt delete mode 100644 project/FlowBuild.scala delete mode 100644 project/Release.scala delete mode 100644 version.sbt diff --git a/.ci/build b/.ci/build new file mode 100755 index 0000000..1d668d8 --- /dev/null +++ b/.ci/build @@ -0,0 +1,38 @@ +#!/bin/bash +set -ev + +sbt +test +sbt \ + samplesTerminal/test \ + samplesTerminalStream/test \ + samplesWatcher/test + +# Automatic publishing for tags that start with `v` +if [[ "$TRAVIS_PULL_REQUEST" == "false" && "$TRAVIS_TAG" =~ ^v[0-9].* ]]; then + # Setup gpg keys + gpg --keyserver keyserver.ubuntu.com --recv-keys "DC6A9A5E884B2D680E080467E107A4A6CF561C67" + openssl aes-256-cbc -K $encrypted_e5a450dd395a_key -iv $encrypted_e5a450dd395a_iv -in .ci/sec.gpg.enc -out sec.gpg -d + gpg --import sec.gpg + + # Setup sbt-pgp plugin + cat < gpg.sbt + pgpSigningKey in Global := Some(0xE107A4A6CF561C67l) + useGpgAgent in Global := true + useGpg in Global := true +EOF + + # Setup publishing + cat < sonatype.sbt + credentials += Credentials( + "Sonatype Nexus Repository Manager", + "oss.sonatype.org", + "8VNUX6+2", + "$SONATYPE_PASS" + ) +EOF + + # Build and publish + sbt clean + sbt -Drelease=true +test + sbt -Drelease=true +publishSigned +fi diff --git a/.ci/sec.gpg.enc b/.ci/sec.gpg.enc new file mode 100644 index 0000000..95bd3c4 Binary files /dev/null and b/.ci/sec.gpg.enc differ diff --git a/.travis.yml b/.travis.yml index ffbd92e..a8d4609 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,25 @@ language: scala -scala: - - 2.11.8 - - 2.12.0-RC1 + jdk: - oraclejdk8 # this should be changed to openjdk as soon as it becomes available on Travis CI -compiler: - - gcc-4.8 + +addons: + apt: + packages: + - cmake + - socat + +env: + - secure: "cb7gVK66QE5dMvyDnUNxjzaXC1dDpGip8hS38Ffv/c6LEGkyUQBJYtIpfh2cXqgTFeapmWLBLnNI2e3IrK/0DwlbJjf3B61pvgUI1GafG/B4ma+RIrIvxwWD1gY3w7VmWxlu2ZfFHLrjsUNyFOom0qWFKuxDdwDoW9WNzrX8cOY=" + +script: .ci/build + +cache: + directories: + - "$HOME/.ivy2/cache" + - "$HOME/.sbt/boot/" + +before_cache: + - find $HOME/.ivy2/cache/ch.jodersky -depth -name "flow*" -exec rm -r {} \; + - find $HOME/.ivy2 -name "ivydata-*.properties" -delete + - find $HOME/.sbt -name "*.lock" -delete diff --git a/build.sbt b/build.sbt index 2f895fb..50d9f8a 100644 --- a/build.sbt +++ b/build.sbt @@ -1,17 +1,69 @@ -import flow.{FlowBuild, Release} +// Build settings +version in ThisBuild := ("git describe --always --dirty=-SNAPSHOT --match v[0-9].*" !!).tail.trim +crossScalaVersions in ThisBuild := List("2.11.8", "2.12.0") +scalaVersion in ThisBuild := crossScalaVersions.value.head +scalacOptions in ThisBuild ++= Seq( + "-deprecation", + "-unchecked", + "-feature", + "-target:jvm-1.8" +) +fork in ThisBuild := true + +// Publishing +organization in ThisBuild := "ch.jodersky" +licenses in ThisBuild := Seq(("BSD New", url("http://opensource.org/licenses/BSD-3-Clause"))) +homepage in ThisBuild := Some(url("https://jodersky.github.io/flow")) +publishMavenStyle in ThisBuild := true +publishTo in ThisBuild := { + val nexus = "https://oss.sonatype.org/" + Some("releases" at nexus + "service/local/staging/deploy/maven2") +} +pomExtra in ThisBuild := { + + git@github.com:jodersky/flow.git + scm:git:git@github.com:jodersky/flow.git + + + + jodersky + Jakob Odersky + + +} + +// Project structure +lazy val root = (project in file(".")) + .aggregate(core, native, stream) + +lazy val core = (project in file("flow-core")) + .settings(name := "flow-core") + .dependsOn(native % "test->runtime") + +lazy val native = (project in file("flow-native")) + .settings(name := "flow-native") + +lazy val stream = (project in file("flow-stream")) + .settings(name := "flow-stream") + .dependsOn(core, core % "test->test", native % "test->runtime") + +lazy val samplesTerminal = (project in file("flow-samples") / "terminal") + .dependsOn(core, native % Runtime) -FlowBuild.commonSettings +lazy val samplesTerminalStream = (project in file("flow-samples") / "terminal-stream") + .dependsOn(stream, native % Runtime) -Release.settings +lazy val samplesWatcher = (project in file("flow-samples") / "watcher") + .dependsOn(core, native % Runtime) -/* Settings related to publishing */ +// Root project settings publishArtifact := false publish := () publishLocal := () // make sbt-pgp happy publishTo := Some(Resolver.file("Unused transient repository", target.value / "unusedrepo")) -/* Generate documentation */ +// Generate documentation enablePlugins(PreprocessPlugin) sourceDirectory in Preprocess := (baseDirectory in ThisBuild).value / "Documentation" preprocessVars in Preprocess := Map( @@ -20,7 +72,7 @@ preprocessVars in Preprocess := Map( "native_minor" -> "0" ) -/* Add scaladoc to documentation */ +// Add scaladoc to documentation enablePlugins(SiteScaladocPlugin) unidocSettings scalacOptions in (ScalaUnidoc, doc) ++= Seq( @@ -29,12 +81,11 @@ scalacOptions in (ScalaUnidoc, doc) ++= Seq( "-implicits", // Add methods "inherited" through implicit conversions "-sourcepath", baseDirectory.value.getAbsolutePath ) ++ { - val latestTag: String = "git describe --abbrev=0".!! + val latestTag: String = "git describe --abbrev=0 --match v[0-9].*".!! Opts.doc.sourceUrl( - s"https://github.com/jodersky/flow/blob/$latestTag€{FILE_PATH}.scala" + s"https://github.com/jodersky/flow/blob/$latestTag€{FILE_PATH}.scala" ) } siteMappings ++= (mappings in (ScalaUnidoc, packageDoc)).value.map{ case (file, path) => (file, "api/" + path) } -fork := true diff --git a/flow-core/build.sbt b/flow-core/build.sbt index 40eb978..fdfcbab 100644 --- a/flow-core/build.sbt +++ b/flow-core/build.sbt @@ -1,9 +1,7 @@ -import flow.{FlowBuild, Dependencies} - -FlowBuild.commonSettings +import flow.Dependencies libraryDependencies += Dependencies.akkaActor -libraryDependencies += Dependencies.akkaTestKit -libraryDependencies += Dependencies.scalatest +libraryDependencies += Dependencies.akkaTestKit % "test" +libraryDependencies += Dependencies.scalatest % "test" target in javah := (baseDirectory in ThisBuild).value / "flow-native" / "src" / "include" diff --git a/flow-native/build.sbt b/flow-native/build.sbt index 1f5720e..2c7ffea 100644 --- a/flow-native/build.sbt +++ b/flow-native/build.sbt @@ -1,10 +1,8 @@ -import flow.{FlowBuild} - -FlowBuild.commonSettings - enablePlugins(JniNative) sourceDirectory in nativeCompile := sourceDirectory.value -// uncomment below to use library in lib_native instead -//enableNativeCompilation in Compile := false +// package native libraries from lib_native during releases +val isRelease = sys.props("release") == "true" +enableNativeCompilation in Compile := !isRelease +enableNativeCompilation in Test := !isRelease diff --git a/flow-samples/terminal-stream/build.sbt b/flow-samples/terminal-stream/build.sbt deleted file mode 100644 index 5fbdd89..0000000 --- a/flow-samples/terminal-stream/build.sbt +++ /dev/null @@ -1,3 +0,0 @@ -import flow.{FlowBuild} - -FlowBuild.commonSettings diff --git a/flow-samples/terminal/build.sbt b/flow-samples/terminal/build.sbt deleted file mode 100644 index 5fbdd89..0000000 --- a/flow-samples/terminal/build.sbt +++ /dev/null @@ -1,3 +0,0 @@ -import flow.{FlowBuild} - -FlowBuild.commonSettings diff --git a/flow-samples/watcher/build.sbt b/flow-samples/watcher/build.sbt deleted file mode 100644 index 5fbdd89..0000000 --- a/flow-samples/watcher/build.sbt +++ /dev/null @@ -1,3 +0,0 @@ -import flow.{FlowBuild} - -FlowBuild.commonSettings diff --git a/flow-stream/build.sbt b/flow-stream/build.sbt index f14190f..c9aa7eb 100644 --- a/flow-stream/build.sbt +++ b/flow-stream/build.sbt @@ -1,7 +1,5 @@ -import flow.{FlowBuild, Dependencies} - -FlowBuild.commonSettings +import flow.Dependencies libraryDependencies += Dependencies.akkaActor libraryDependencies += Dependencies.akkaStream -libraryDependencies += Dependencies.scalatest +libraryDependencies += Dependencies.scalatest % "test" diff --git a/project/Dependencies.scala b/project/Dependencies.scala index f02b039..0e7d1ac 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,7 +7,7 @@ object Dependencies { val akkaActor = "com.typesafe.akka" %% "akka-actor" % "2.4.14" val akkaStream ="com.typesafe.akka" %% "akka-stream" % "2.4.14" - val akkaTestKit = "com.typesafe.akka" %% "akka-testkit" % "2.4.14" % "test" - val scalatest = "org.scalatest" %% "scalatest" % "3.0.1" % "test" + val akkaTestKit = "com.typesafe.akka" %% "akka-testkit" % "2.4.14" + val scalatest = "org.scalatest" %% "scalatest" % "3.0.1" } diff --git a/project/FlowBuild.scala b/project/FlowBuild.scala deleted file mode 100644 index 19042b6..0000000 --- a/project/FlowBuild.scala +++ /dev/null @@ -1,64 +0,0 @@ -package flow - -import sbt._ -import Keys._ - -object FlowBuild extends Build { - - val scalaVersions = List("2.11.8", "2.12.0") - - lazy val commonSettings: Seq[Setting[_]] = Seq( - resolvers += Resolver.jcenterRepo, - scalaVersion := scalaVersions.head, - crossScalaVersions := scalaVersions.reverse, - scalacOptions ++= Seq("-deprecation", "-unchecked", "-feature", "-target:jvm-1.8"), - organization := "ch.jodersky", - licenses := Seq(("BSD New", url("http://opensource.org/licenses/BSD-3-Clause"))), - homepage := Some(url("https://jodersky.github.io/flow")), - publishMavenStyle := true, - publishTo := { - val nexus = "https://oss.sonatype.org/" - if (isSnapshot.value) - Some("snapshots" at nexus + "content/repositories/snapshots") - else - Some("releases" at nexus + "service/local/staging/deploy/maven2") - }, - pomIncludeRepository := { _ => false }, - pomExtra := { - - git@github.com:jodersky/flow.git - scm:git:git@github.com:jodersky/flow.git - - - - jodersky - Jakob Odersky - - - } - ) - - lazy val root = (project in file(".")). - aggregate(core, native, stream) - - lazy val core = (project in file("flow-core")). - settings(name:= "flow-core"). - dependsOn(native % "test->runtime") - - lazy val native = (project in file("flow-native")). - settings(name:= "flow-native") - - lazy val stream = (project in file("flow-stream")). - settings(name:= "flow-stream"). - dependsOn(core, core % "test->test", native % "test->runtime") - - lazy val samplesTerminal = (project in file("flow-samples") / "terminal"). - dependsOn(core, native % Runtime) - - lazy val samplesTerminalStream = (project in file("flow-samples") / "terminal-stream"). - dependsOn(stream, native % Runtime) - - lazy val samplesWatcher = (project in file("flow-samples") / "watcher"). - dependsOn(core, native % Runtime) - -} diff --git a/project/Release.scala b/project/Release.scala deleted file mode 100644 index a203262..0000000 --- a/project/Release.scala +++ /dev/null @@ -1,111 +0,0 @@ -package flow - -import sbt._ -import sbtrelease._ -import sbtrelease.ReleasePlugin.autoImport._ -import sbtrelease.ReleaseStateTransformations._ - -import ch.jodersky.sbt.jni.plugins.JniNative.autoImport._ -import ch.jodersky.sbt.jni.plugins.JniPackage.autoImport._ - -import com.typesafe.sbt.pgp.PgpKeys._ - -object Release { - - - def settings: Seq[Setting[_]] = Seq( - - //sign git tags - releaseVcs := Some(new SignedGit(Keys.baseDirectory.value)), - - //publish signed - releasePublishArtifactsAction := publishSigned.value, - - //build for multiple scala versions, - releaseCrossBuild := true, - - releaseProcess := Seq[ReleaseStep]( - - //Check that there are no snapshot dependencies - checkSnapshotDependencies, - - //During a release, only native libraries in lib_native will be packaged - disableLocalBuild, - - //Check that there are native libraries in lib_native and list all - //libraries that will be packaged - checkNativeLibs, - - //Ask for release version and next development version - inquireVersions, - - //Set version to release version and save - setReleaseVersion, - - //Clean - runClean, - - //Compile and test - runTest, - - //If all tests pass, commit the updated version - commitReleaseVersion, - - //Also create a tag - tagRelease, - - //Publish artifacts, note that they will only be uploaded, not yet be released to the public - publishArtifacts, - - //Bump version to next development - setNextVersion, - - //TODO: update website - - //Commit - commitNextVersion, - - //Push all changes (commits and tags) to GitHub - pushChanges - - ) - ) - - /** Set `enableNativeCompilations` to false. */ - lazy val disableLocalBuild = ReleaseStep(st => { - val st1 = ReleaseStateTransformations.reapply(Seq( - enableNativeCompilation in FlowBuild.native in Compile := false, - enableNativeCompilation in FlowBuild.native in Test := false - ), st) - st1.log.info("Disabled compilation of native libraries during release process.") - st1 - }) - - /** Release step that prints all native libraries that will be packaged - * and awaits approval from user. */ - lazy val checkNativeLibs = ReleaseStep(action = st0 => { - val log = st0.log - val project = FlowBuild.native - - val extracted = Project.extract(st0) - val (st1, libs) = extracted.runTask(unmanagedNativeLibraries in project in Compile, st0) - - log.info("The following native libraries will be packaged:") - log.info("---------------------") - libs.toSeq.sortBy(_._2).foreach{ case (file, path) => - log.info(path) - } - SimpleReader.readLine("Are the all native libraries listed (y/n)? [n] ") match { - case Some("y") => //do nothing - case _ => sys.error("Missing native libaries. Aborting release.") - } - st1 - }) - - /** A Git wrapper that signs tags. */ - class SignedGit(baseDir: File) extends Git(baseDir) { - override def tag(name: String, comment: String, force: Boolean = false) = - cmd("tag", "-s", name, "-m", comment, if(force) "-f" else "") - } - -} diff --git a/project/plugins.sbt b/project/plugins.sbt index 3db4586..2ff38e5 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -14,11 +14,8 @@ addSbtPlugin("com.eed3si9n" % "sbt-unidoc" % "0.3.3") // Generate website content addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "1.0.0") +// Sign published artifacts +addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0") + // Publish to sonatype and sync with maven central addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "1.1") - -// Automate release process -addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.0") - -// Usually a global plugin, made explicit to work with release automation -addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0") diff --git a/version.sbt b/version.sbt deleted file mode 100644 index 2c28183..0000000 --- a/version.sbt +++ /dev/null @@ -1 +0,0 @@ -version in ThisBuild := "3.0.4-SNAPSHOT" -- cgit v1.2.3