diff --git a/.travis.yml b/.travis.yml index 5652b04..6b8b848 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,44 +4,33 @@ scala: - 2.13.0 env: - global: - # PGP_PASSPHRASE - - secure: "NAYlvLQD1OiF+B8NvN+l1Lh0a2xa9FYFfA7LVHt1FXkri6wM/44oVuLF2H7BQTHczFN4754lAR5nrXrBccX1pa4BFmdNLu/nzZIjzjMxz5rFJRcK3nsycJPPUSY6mh5jBP5mR+hyW1zngQPGqCMmwAPP6pANaAztKh34DMSCcdRWb9Gfz6+IL0whCUywYk6LcXBfpD+H0u2ahGUM5ZTWWqqyTDiYmGIhfkXShUZ7oRYNgxffK3BbC5c3UztOTefHMiSCVgqnqNxmFCaGijtm6P1lxW4ebXrklVdb8/Z2AOrJxjV2+Itytb/8w7ukQvYUaPwBoyJYbN0glicMXoYwXKaJ0Rs7VxLFShUQGzDuQFzn5mcjn6r46Gs7aPYC0WTRW6Tx8aaaie7kV+w1zwIx1FrK4OpGaCKGQc73sEUng9EPcVZCbBNS5MNuF/yCfyYN+tSrC7Ms7KzQUwk1aoabEctEqL/Nax8LwayuBBFGrOQnOI9Rt6IxFAze6tJShkcNrZeOp6P/2eCanipHqH18lV3gNr7mKmJL1kTiBdMHo41S/DumNblOz1n5pVOBBLIOjD2Q55uDHAWUPXLbRa+BMtGrmbY2IHIUQPZNKTvnZ5PzoOezP2nSKANUC0V4pN7gVGOmZ/2iPJ7/itdU1tqlQFGRPJvTAzRtsXbPhynEqqw=" - # SONA_USER - - secure: "Uc+tOT5E5FEQwLx4ZXZO1Oum1HAhMbvCWpKpkReqdsyb+xBdMbJkt43o8jvM/2WNVMcijEku87o5yWWa/fRDfqBg4GCuwnjUYu/3S0Lyxso8Mgmlcn6khmi09inOvAMVpCdBjvr+krJG1kXgxO62qA3IM0FU9z06Kcngz8F4YhnSGBv2HkOI/+9UHjQeex7tSUSFZi8itnEIN+gK4oWLVItyo0MbH4539BeJyoq/+e70xNxolLFHpVhruBQssg8MS60C5rajo7FXo1BODv+SIR+d1UZ6z8sl2iFU2psijej39nYHzmbxuM9P5Twozs38Rq7g4CM5aFLebna8VZoO6zZtM4PIAyiExkWWILQknrZEhHSded6l73GDeX+eoIigvYNxxAgXMh+MJll1i+XEySLjku8NvarQJ8c09x4S/Rjz1CBEfvlAhM+f117PqVsB87JBnsfE7CABfusJ2wqBpFf9pq9DA3E62XSEniWTIzow37YSR7opRv6wvHzuGrO6OeadIN1P2hb/FDiXDBnqG4xtGUFx81FM0dl9jV97kYiXoaqTwjT0j3d1MBGiN7IzeHxLbczMWA9mvvXtIeOxa73mph3grKKXiRqf/U+455oEIbCObEudjI7zXbjhXGeoVb+OqU7t5Beo+0Lg3H0hyntCsewops/h52lTmgsg5Hw=" - # SONA_PASS - - secure: "ggXFZBlzV5ek/rBaE9lrEZlAIfUrv4XDJ4OrP8daMrJxmwkXtoSbcB3z4VgqqWKzAzW89CcU1IiojzDbe/het3xEX4qxdz5Wt05/E+WOgbek528kelwMxq12XRe6xaCVfG+y8OISPgq1q3vKoO/xYGVbK3D6hSD+cjojEXyPpjAfrVSUof06aNPFPQeLX9exgu9zrxkJJm01PbTh19vQk4Ojc++oEmpF7HLD1CF1m7AlW0U2Rba+syivpj9Ray3Z9vu0TnFL06r4TiwZruwcXTLrWUqumFI0r5mhaY6SNH7bqttu+3RPIOdkUGxIeGlkDi3xopt7r2aEkhOKvjRXapW0e/CWmUo1J+NnlIumxrldi4n0iiJGVEvY4Krx/HGZe0wCVTh4vDNOllTGdFmkkxN6WoaHALgj3QNM3XLjvvUu3VcT+QNtsVIvgUDesrtos8zCKczzdhL/d4BMiIg7SFfA33S3vx8BeczLBqddrx+yLSPzfheKrHW7g76EAEyN26vE2/2/GRlMOlG8Lmu8rXBfIPsK9T/ztfE1CxaTW5EsMSrxO2+O/bvAa6DY0R79KkHf7LDI+azzP2NwYx8anM9WlMTp4EbawI/KGZRilWYtJ3Q3y5EQERsrP71W35dKqiBFMPdspS+lTS9hGtso08n7cR2MwTbRjoXVRcWfJ/I=" - matrix: - # The empty SCALAJS_VERSION will only compile for the JVM - - SCALAJS_VERSION= ADOPTOPENJDK=8 MODULE=scala-collection-contrib - - SCALAJS_VERSION=0.6.28 ADOPTOPENJDK=8 MODULE=scala-collection-contribJS - - SCALAJS_VERSION=1.0.0-M8 ADOPTOPENJDK=8 MODULE=scala-collection-contribJS - - SCALAJS_VERSION= ADOPTOPENJDK=11 MODULE=scala-collection-contrib + - SCALAJS_VERSION= ADOPTOPENJDK=8 + - SCALAJS_VERSION=0.6.29 ADOPTOPENJDK=8 + - SCALAJS_VERSION=1.0.0-M8 ADOPTOPENJDK=8 + - SCALAJS_VERSION= ADOPTOPENJDK=11 before_install: # adding $HOME/.sdkman to cache would create an empty directory, which interferes with the initial installation - "[[ -d $HOME/.sdkman/bin ]] || rm -rf $HOME/.sdkman/" - curl -sL https://get.sdkman.io | bash - - echo sdkman_auto_answer=true > "$HOME/.sdkman/etc/config" + - echo sdkman_auto_answer=true > $HOME/.sdkman/etc/config - source "$HOME/.sdkman/bin/sdkman-init.sh" install: - sdk install java $(sdk list java | grep -o "$ADOPTOPENJDK\.[0-9\.]*hs-adpt" | head -1) - unset JAVA_HOME - java -Xmx32m -version - - javac -J-Xmx32m -version + - git fetch --tags # get all tags for sbt-dynver -script: - - admin/build.sh +script: ./build.sh before_cache: - - find $HOME/.sbt -name "*.lock" | xargs rm - - find $HOME/.ivy2/cache -name "ivydata-*.properties" | xargs rm + - rm -f $HOME/.ivy2/.sbt.ivy.lock + - find $HOME/.ivy2/cache -name "ivydata-*.properties" | xargs rm + - find $HOME/.sbt -name "*.lock" | xargs rm cache: directories: - - $HOME/.ivy2/cache - - $HOME/.coursier - - $HOME/.sbt/1.0 - - $HOME/.sbt/boot - - $HOME/.sbt/launchers - - $HOME/.sdkman + - $HOME/.ivy2/cache + - $HOME/.sbt + - $HOME/.cache/coursier + - $HOME/.sdkman diff --git a/admin/README.md b/admin/README.md deleted file mode 100644 index 2659187..0000000 --- a/admin/README.md +++ /dev/null @@ -1,68 +0,0 @@ -## Tag Driven Releasing - -### Initial setup for the repository - -To configure tag driven releases from Travis CI. - - 1. Generate a key pair for this repository with `./admin/genKeyPair.sh`. - Edit `.travis.yml` and `admin/build.sh` as prompted. - 1. Publish the public key to https://pgp.mit.edu - 1. Store other secrets as encrypted environment variables with `./admin/encryptEnvVars.sh`. - Edit `.travis.yml` as prompted. - 1. Edit `.travis.yml` to use `./admin/build.sh` as the build script, - and edit that script to use the tasks required for this project. - Ensure that `RELEASE_COMBO` is `true` for build matrix combinations - that should be released to sonatype (when building a tag). - -It is important to add comments in `.travis.yml` to identify the name -of each environment variable encoded in a `secure` section. - -After these steps, your `.travis.yml` should contain config of the form: - -``` -language: scala - -jdk: - - openjdk8 - -scala: - - 2.11.12 - - 2.12.6 - -env: - global: - # PGP_PASSPHRASE - - secure: "XXXXXX" - # SONA_USER - - secure: "XXXXXX" - # SONA_PASS - - secure: "XXXXXX" - -script: admin/build.sh - -notifications: - email: - - a@b.com -``` - -If Sonatype credentials change in the future, step 3 can be repeated -without generating a new key. - -### Testing - - 1. Follow the release process below to create a dummy release (e.g., `v0.1.0-TEST1`). - Confirm that the release was staged to Sonatype but do not release it to Maven - central. Instead, drop the staging repository. - -### Performing a release - - 1. Create a GitHub "Release" with a corresponding tag (e.g., `v0.1.1`) via the GitHub - web interface. - 1. The release will be published using the Scala and JVM version combinations specified - in the travis build matrix where `[ "$RELEASE_COMBO" = "true" ]`. - - If you need to release against a different Scala version, create a new commit that modifies - `.travis.yml` and push a new tag, e.g., `v1.2.3#2.13.0-M5`. The suffix after `#` is ignored. - 1. Travis CI will schedule a build for this release. Review the build logs. - 1. Log into https://oss.sonatype.org/ and identify the staging repository. - 1. Sanity check its contents. - 1. Release staging repository to Maven and send out release announcement. diff --git a/admin/build.sh b/admin/build.sh deleted file mode 100755 index fd26f14..0000000 --- a/admin/build.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash - -set -e - -# Builds of tagged revisions are published to sonatype staging. - -# Travis runs a build on revisions, including on new tags. -# Builds for a tag have TRAVIS_TAG defined, which we use for identifying tagged builds. -# Checking the local git clone would not work because git on travis does not fetch tags. - -# The version number to be published is extracted from the tag, e.g., v1.2.3 publishes -# version 1.2.3 on all combinations of the travis matrix where `[ "$RELEASE_COMBO" = "true" ]`. - -# In order to build a previously released version against a new (binary incompatible) Scala release, -# a new commit that modifies (and prunes) the Scala versions in .travis.yml needs to be added on top -# of the existing tag. Then a new tag can be created for that commit, e.g., `v1.2.3#2.13.0-M5`. -# Everything after the `#` in the tag name is ignored. - -if [[ "$ADOPTOPENJDK" == "8" ]]; then - RELEASE_COMBO=true; -fi - -verPat="[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9-]+)?" -tagPat="^v$verPat(#.*)?$" - -if [[ "$TRAVIS_TAG" =~ $tagPat ]]; then - tagVer=${TRAVIS_TAG} - tagVer=${tagVer#v} # Remove `v` at beginning. - tagVer=${tagVer%%#*} # Remove anything after `#`. - publishVersion='set every version := "'$tagVer'"' - - if [ "$RELEASE_COMBO" = "true" ]; then - currentJvmVer=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}' | sed 's/^1\.//' | sed 's/[^0-9].*//') - echo "Releasing $tagVer with Scala $TRAVIS_SCALA_VERSION on Java version $currentJvmVer." - - publishTask="$MODULE/publishSigned" - - cat admin/gpg.sbt >> project/plugins.sbt - cp admin/publish-settings.sbt . - - # Copied from the output of genKeyPair.sh - K=$encrypted_19496a14fffe_key - IV=$encrypted_19496a14fffe_iv - openssl aes-256-cbc -K $K -iv $IV -in admin/secring.asc.enc -out admin/secring.asc -d - fi -fi - -sbt "++$TRAVIS_SCALA_VERSION" "$publishVersion" "$MODULE/clean" "$MODULE/test" "$publishTask" diff --git a/admin/encryptEnvVars.sh b/admin/encryptEnvVars.sh deleted file mode 100755 index b625667..0000000 --- a/admin/encryptEnvVars.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -# -# Encrypt sonatype credentials so that they can be -# decrypted in trusted builds on Travis CI. -# -set -e - -read -s -p 'SONA_USER: ' SONA_USER -travis encrypt SONA_USER="$SONA_USER" -read -s -p 'SONA_PASS: ' SONA_PASS -travis encrypt SONA_PASS="$SONA_PASS" diff --git a/admin/genKeyPair.sh b/admin/genKeyPair.sh deleted file mode 100755 index 17db3f3..0000000 --- a/admin/genKeyPair.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash -# -# Generates a key pair for this repository to sign artifacts. -# Encrypt the private key and its passphrase in trusted builds -# on Travis CI. -# -set -e - -# Based on https://gist.github.com/kzap/5819745: -function promptDelete() { - if [[ -f "$1" ]]; then - echo About to delete $1, Enter for okay / CTRL-C to cancel - read - rm "$1" - fi -} -for f in admin/secring.asc.enc admin/secring.asc admin/pubring.asc; do promptDelete "$f"; done - -echo Generating key pair. Please enter 1. repo name 2. scala-internals@googlegroups.com, 3. a new passphrase -echo Be careful when using special characters in the passphrase, see http://docs.travis-ci.com/user/encryption-keys/#Note-on-escaping-certain-symbols -cp admin/gpg.sbt project -sbt 'set pgpReadOnly := false' \ - 'set pgpPublicRing := file("admin/pubring.asc")' \ - 'set pgpSecretRing := file("admin/secring.asc")' \ - 'pgp-cmd gen-key' -rm project/gpg.sbt - -echo ============================================================================================ -echo Encrypting admin/secring.asc. Update K and IV variables in admin/build.sh accordingly. -echo ============================================================================================ -travis encrypt-file admin/secring.asc -rm admin/secring.asc -mv secring.asc.enc admin - -echo ============================================================================================ -echo Encrypting environment variables. Add each to a line in .travis.yml. Include a comment -echo with the name of the corresponding variable -echo ============================================================================================ -read -s -p 'PGP_PASSPHRASE: ' PGP_PASSPHRASE -travis encrypt PGP_PASSPHRASE="$PGP_PASSPHRASE" - diff --git a/admin/gpg.sbt b/admin/gpg.sbt deleted file mode 100644 index 3b55e21..0000000 --- a/admin/gpg.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.2-1") // only added when publishing, see build.sh diff --git a/admin/publish-settings.sbt b/admin/publish-settings.sbt deleted file mode 100644 index 026c6ee..0000000 --- a/admin/publish-settings.sbt +++ /dev/null @@ -1,8 +0,0 @@ -def env(key: String) = Option(System.getenv(key)).getOrElse("") - -inThisBuild(Seq( - pgpPassphrase := Some(env("PGP_PASSPHRASE").toArray), - pgpPublicRing := file("admin/pubring.asc"), - pgpSecretRing := file("admin/secring.asc"), - credentials += Credentials("Sonatype Nexus Repository Manager", "oss.sonatype.org", env("SONA_USER"), env("SONA_PASS")) -)) diff --git a/admin/pubring.asc b/admin/pubring.asc deleted file mode 100644 index ac1349c..0000000 --- a/admin/pubring.asc +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: BCPG v1.51 - -mQENBF0w4ZMBCACLX2RqR9L5J9wti2G8Hgi0XktuUtaHighmKT31tQgQf4RleHsR -kd+cVKaop623+LTf+8HHBquB2ZbIGg0gnyFUluPJEIanSYAJbM373snvwkUzU28x -g0KTHWg3HaX+2Yg2TemL2EW6TQYdOpHk7jkxUMxOAIAd+YalEZpGCgEEiKqTTNIt -24sqZHyS8n6rT+RD+PcyQBqRG6eoPRQdjUzNaFcD+SEilpqVlG3I3qAdsdPMI7bi -O2jWVKE38NMemiPweGdAgZrya4a7srg9x5lujlqN3LtzBhwZLolymGYLEQfE2v1v -4Mr4fO2roFpSVkZQSdeqVqfjDHMaz0mY6tUFABEBAAG0O3NjYWxhLWNvbGxlY3Rp -b24tY29udHJpYiA8c2NhbGEtaW50ZXJuYWxzQGdvb2dsZWdyb3Vwcy5jb20+iQEc -BBMBAgAGBQJdMOGTAAoJEJUcb0POSwjJw+sH/AvkB05NR3ojI8880WIceWeFPPHF -ISK9l5KNchBB0+3OwB9w6X2J75MV7F/stNfgYe+meQlxveHNi/z4ULKxhFVMj7JK -ldr2H5rvtxNyLgSL8ljBGPAcHml81SML8J0qNoRPXPkmbnXPdZZ7NPqMGUIbZtCX -40HD5LAjv+q2Q4OERtQpjN9qK0c2pWi2W3JzfUh55adPAoPXSVBIfxImLSdPGKBc -Dj8ugFAqxivUvCQhwa91RkFLL+PefRDvSalPofRXY6P0Vn+gQZm4wgGerp05uEnk -v5ZEO2WrXxffwMsZog6CCFuNgmjJrMkhaAF4/JO/7mlrmpkf6tpXxF+MabA= -=tc/r ------END PGP PUBLIC KEY BLOCK----- diff --git a/admin/secring.asc.enc b/admin/secring.asc.enc deleted file mode 100644 index 6e29807..0000000 Binary files a/admin/secring.asc.enc and /dev/null differ diff --git a/build.sbt b/build.sbt index 35187c0..60685fb 100644 --- a/build.sbt +++ b/build.sbt @@ -1,48 +1,35 @@ -import sbtcrossproject.CrossPlugin.autoImport.{ crossProject, CrossType } -import ScalaModulePlugin._ +import sbtcrossproject.CrossPlugin.autoImport.{CrossType, crossProject} -lazy val root = project.in(file(".")) - .aggregate(`scala-collection-contribJS`, `scala-collection-contribJVM`) - .settings( - disablePublishing, - // HACK If we don’t add this dependency the tests compilation of the aggregated projects fails - libraryDependencies += "junit" % "junit" % "4.12" % Test - ) +// With CrossType.Pure, the root project also picks up the sources in `src` +Compile/sources := Nil +Test/sources := Nil -lazy val `scala-collection-contrib` = crossProject(JVMPlatform, JSPlatform) +lazy val collectionContrib = crossProject(JVMPlatform, JSPlatform) + .withoutSuffixFor(JVMPlatform) .crossType(CrossType.Pure) - .withoutSuffixFor(JVMPlatform).in(file(".")) - .settings(scalaModuleSettings) - .jvmSettings(scalaModuleSettingsJVM) + .in(file(".")) + .settings(ScalaModulePlugin.scalaModuleSettings) + .jvmSettings(ScalaModulePlugin.scalaModuleSettingsJVM) .settings( name := "scala-collection-contrib", - version := "0.2.1-SNAPSHOT", - - crossScalaVersions in ThisBuild := Seq("2.13.0"), - scalacOptions ++= Seq("-opt-warnings", "-language:higherKinds", "-deprecation", "-feature", "-Xfatal-warnings"), scalacOptions in (Compile, doc) ++= Seq("-implicits", "-groups"), - testOptions += Tests.Argument(TestFrameworks.JUnit, "-q", "-v", "-s", "-a"), parallelExecution in Test := false, // why? - - mimaPreviousVersion := Some("0.1.0"), - - homepage := Some(url("https://github.com/scala/scala-collection-contrib")), - licenses := Seq("Apache-2.0" -> url("https://www.apache.org/licenses/LICENSE-2.0")), - libraryDependencies ++= Seq( "junit" % "junit" % "4.12" % Test, "com.novocode" % "junit-interface" % "0.11" % Test, "org.openjdk.jol" % "jol-core" % "0.9" % Test ) ) + .jvmSettings( + scalaModuleMimaPreviousVersion := Some("0.1.0"), // why only in jvmSettings? + // TODO: osgi settings; not trivial because of split packages. + // See https://github.com/scala/scala-collection-compat/pull/226 + // OsgiKeys.exportPackage := Seq(s"scala.collection.*;version=${version.value}"), + ) .jsConfigure(_.enablePlugins(ScalaJSJUnitPlugin)) .jsSettings( - mimaPreviousVersion := None, // Scala.js cannot run forked tests fork in Test := false ) - -lazy val `scala-collection-contribJVM` = `scala-collection-contrib`.jvm -lazy val `scala-collection-contribJS` = `scala-collection-contrib`.js diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..a3a387f --- /dev/null +++ b/build.sh @@ -0,0 +1,73 @@ +#!/bin/bash + +set -e + +# Builds of tagged revisions are published to sonatype staging. + +# Travis runs a build on new revisions and on new tags, so a tagged revision is built twice. +# Builds for a tag have TRAVIS_TAG defined, which we use for identifying tagged builds. + +# sbt-dynver sets the version number from the tag +# sbt-travisci sets the Scala version from the travis job matrix + +# When a new binary incompatible Scala version becomes available, a previously released version +# can be released using that new Scala version by creating a new tag containing the Scala version +# after a hash, e.g., v1.2.3#2.13.0-M3. In this situation, the first job of the travis job +# matrix builds the release. All other jobs are stopped. Make sure that the first job uses +# the desired JVM version. + +# For normal tags that are cross-built, we release on JDK 8 for Scala 2.x +isReleaseJob() { + if [[ "$ADOPTOPENJDK" == "8" ]]; then + true + else + false + fi +} + +# For tags that define a Scala version, we pick the jobs of one Scala version (2.13.x) to do the releases +isTagScalaReleaseJob() { + if [[ "$ADOPTOPENJDK" == "8" && "$TRAVIS_SCALA_VERSION" =~ ^2\.13\.[0-9]+$ ]]; then + true + else + false + fi +} + +if [[ "$SCALAJS_VERSION" != "" ]]; then + projectPrefix="collectionContribJS" +else + projectPrefix="collectionContrib" +fi + +verPat="[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9-]+)?" +tagPat="^v$verPat(#$verPat)?$" + +if [[ "$TRAVIS_TAG" =~ $tagPat ]]; then + releaseTask="ci-release" + tagScalaVer=$(echo $TRAVIS_TAG | sed s/[^#]*// | sed s/^#//) + if [[ "$tagScalaVer" == "" ]]; then + if ! isReleaseJob; then + echo "Not releasing on Java $ADOPTOPENJDK with Scala $TRAVIS_SCALA_VERSION" + exit 0 + fi + else + if isTagScalaReleaseJob; then + setTagScalaVersion='set every scalaVersion := "'$tagScalaVer'"' + else + echo "The releases for Scala $tagScalaVer are built by other jobs in the travis job matrix" + exit 0 + fi + fi +fi + +# default is +publishSigned; we cross-build with travis jobs, not sbt's crossScalaVersions +export CI_RELEASE="$projectPrefix/publishSigned" +export CI_SNAPSHOT_RELEASE="$projectPrefix/publish" + +# default is sonatypeBundleRelease, which closes and releases the staging repo +# see https://github.com/xerial/sbt-sonatype#commands +# for now, until we're confident in the new release scripts, just close the staging repo. +export CI_SONATYPE_RELEASE="; sonatypePrepare; sonatypeBundleUpload; sonatypeClose" + +sbt "$setTagScalaVersion" clean $projectPrefix/test $projectPrefix/publishLocal $releaseTask diff --git a/project/build.properties b/project/build.properties index c0bab04..abfd235 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1,2 @@ +# Not 1.3.0 due to https://github.com/sbt/sbt/issues/5043 sbt.version=1.2.8 diff --git a/project/plugins.sbt b/project/plugins.sbt index 0459ceb..649ce0f 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,7 +1,7 @@ -scalacOptions ++= Seq("-deprecation", "-feature", "-Xfatal-warnings") +val scalaJSVersion = + Option(System.getenv("SCALAJS_VERSION")).filter(_.nonEmpty).getOrElse("0.6.29") -val scalajsVersion = Option(System.getenv("SCALAJS_VERSION")).filter(_.nonEmpty).getOrElse("0.6.28") +addSbtPlugin("org.scala-lang.modules" % "sbt-scala-module" % "2.1.2") -addSbtPlugin("org.scala-lang.modules" % "sbt-scala-module" % "2.0.0") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % scalajsVersion) addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "0.6.1") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % scalaJSVersion)