An sbt plugin for deploying Heroku Scala applications
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
etc Updated travis setup Jun 9, 2017
project Updated release plugin [skip ci] Aug 28, 2018
src Upgrade to heroku-deploy 2.0.0-RC2 Nov 8, 2017
.gitignore
.travis.yml Update travis config Aug 16, 2017
CHANGELOG.md Updated changelog and readme [skip ci] Aug 20, 2015
LICENSE first commit Aug 29, 2014
README.md Updated readme [skip ci] Aug 28, 2018
build.sbt Upgrade heroku-deploy to 2.0.6 Aug 27, 2018
release.sh Added a new release script [skip ci] Aug 16, 2017
version.sbt Setting version to 2.1.3-SNAPSHOT Aug 28, 2018

README.md

Heroku sbt Plugin Build Status Download

This plugin is used to deploy Scala and Play applications directly to Heroku without pushing to a Git repository. This is can be useful when deploying from a CI server.

Using the Plugin

Add the following to your project/plugins.sbt file:

addSbtPlugin("com.heroku" % "sbt-heroku" % "2.1.2")

If you're not using Play, then you'll also need to add the sbt-native-packager plugin, which creates a stage task. Alternatively, you can deploy a fat JAR using sbt-assembly.

Next, add something like this to your build.sbt if you do not have a Heroku Git repo in your git remotes.

herokuAppName in Compile := "your-heroku-app-name"

Now, if you have the Heroku Toolbelt installed, run:

$ sbt stage deployHeroku

If you do not have the toolbelt installed, then run:

$ HEROKU_API_KEY="xxx-xxx-xxxx" sbt stage deployHeroku

And replace "xxx-xxx-xxxx" with the value of your Heroku API token.

Requirements

  • It is required that you use sbt 0.13.5 or greater.

  • You must use Java 1.7 or higher locally.

  • This plugin has not been tested with Play 2.0 or 2.1.

Configuring the Plugin

You may set the desired JDK version like so:

herokuJdkVersion in Compile := "1.8"

Valid values are 1.6, 1.7, and 1.8. The default is 1.8

You can (but probably should not) set configuration variables like so:

herokuConfigVars in Compile := Map(
  "MY_VAR" -> "some value",
  "JAVA_OPTS" -> "-XX:+UseCompressedOops"
)

If you adhere to the principles of the 12 Factor app, Configuration should be strictly seperated from code. Thus, you do not want to tie your configuration to your codebase. There are a few exceptions to this, such as conf/routes, and some JAVA_OPTS may be universal. But please use herokuConfigVars sparingly.

Any variable defined in herokuConfigVars will override defaults. However, if you remove a variable from this list, it will not automatically be removed from your Heroku app (even on the next deploy).

You may set process types (similar to a Procfile) with herokuProcessTypes:

herokuProcessTypes in Compile := Map(
  "web" -> "target/universal/stage/bin/my-app -Dhttp.port=$PORT",
  "worker" -> "java -jar target/universal/stage/lib/my-worker.jar"
)

You can include additional directories in the slug (they must be relative to the project root):

herokuIncludePaths in Compile := Seq(
  "app", "conf/routes", "public/javascripts"
)

You can run the plugin against all sub-projects (in addition to the root project) by setting the following option:

herokuSkipSubProjects in Compile := false

This defaults to true (and currently it only runs against all sub-projects or none).

You can disable the upload progress in the console by setting the heroku.log.format system property to false, like this:

$ sbt -Dheroku.log.format=false deployHeroku

See the src/sbt-test directory for examples.

Deploying a Fat JAR

If you are packaging your application with sbt-assembly or any other plugin that produces a "fat JAR", you can deploy that file by adding the following configuration to your build.sbt:

herokuFatJar in Compile := Some((assemblyOutputPath in assembly).value)

If not using sbt-assembly, you may replace (assemblyOutputPath in assembly).value with the relative path to your JAR file. Then you can deploy by running:

$ sbt assembly deployHeroku

The sbt-heroku plugin will skip the sbt-native-packager bits and deploy your JAR directly to Heroku.

Running a Remote Console

When using sbt-native-packager version 0.7.6 or greater, sbt-heroku will create a console process type for you. This command can be run like so:

$ heroku run console -a <appname>
Running `console` attached to terminal... up, run.5154
Picked up JAVA_TOOL_OPTIONS: -Xmx384m  -Djava.rmi.server.useCodebaseOnly=true
Failed to created JLineReader: java.lang.NoClassDefFoundError: scala/tools/jline/console/completer/Completer
Falling back to SimpleReader.
Welcome to Scala version 2.10.4 (OpenJDK 64-Bit Server VM, Java 1.8.0_20).
Type in expressions to have them evaluated.
Type :help for more information.

scala>

If you are using Play 2.x, then you will need to upgrade sbt-native-packager manually (because Play uses version 0.7.4 by default). You can do this by adding the following line of code to your project/plugins.sbt:

addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.7.6")

Additionally, the is a bug in Scala 2.11.6 that causes this console task to fail. Upgrading to Scala 2.11.7 fixes the issue.

Deploying to Multiple Environments

To deploy to multiple Heroku app environments, you can use either system properties, environment variables, or any other native sbt/Java configuration method. For example, you might define your appName as a Map and choose a value with the system property as a key.

herokuAppName in Compile := Map(
  "test" -> "your-heroku-app-test",
  "stg"  -> "your-heroku-app-stage",
  "prod" -> "your-heroku-app-prod"
).getOrElse(sys.props("appEnv"), "your-heroku-app-dev")

Then run the sbt command like so:

$ sbt -DappEnv=test stage deployHeroku

Deploying from Git Branches

Another option when using multiple environments is to deploy from a Git branch that corresponds to the environment. This is particularly useful if you are using git-flow or a similar process.

First, add the sbt-git plugin ot your project/plugins.sbt like this:

resolvers += "jgit-repo" at "http://download.eclipse.org/jgit/maven"

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

Then in your build.sbt you can configure the sbt-heroku plugin to deploy to the environment that corresponds to the current Git branch like this:

import com.typesafe.sbt.SbtGit._

// ...

herokuAppName in Compile := Map(
  "testing"    -> "myapp-testing",
  "staging"    -> "myapp-staging",
  "production" -> "myapp"
).getOrElse(git.gitCurrentBranch.value, "myapp-dev")

showCurrentGitBranch

Hacking

In order to run the test suite, you must have the Heroku Toolbelt installed. Then run:

$ sbt scripted

To run an individual test, use a command like this:

$ sbt "scripted settings/config_vars"

The heavy lifting for this plugin is done by the heroku-deploy library. The source code for that project can be found in the heroku-maven-plugin repository. If you need to update that library, do this:

$ git clone https://github.com/heroku/heroku-maven-plugin
$ cd heroku-maven-plugin/heroku-deploy
# make your changes
$ mvn clean install

Then update the heroku-deploy dependency version in the sbt-heroku build.sbt to 0.3.3-SNAPSHOT (or whatever version is specified in the heroku-deploy pom.xml). The next time you run the scripted tests it will pick up the snapshot version from your local Maven repository.