sbt plugin to aggregate tasks across subprojects and their crossScalaVersions
Switch branches/tags
Clone or download
eed3si9n Merge pull request #19 from sbt/merged
Note this is merged into sbt 1
Latest commit 29eaa11 Nov 1, 2017
Failed to load latest commit information.
notes 0.1.5 Mar 3, 2015
project invert the loop Jul 21, 2014
src Merge pull request #6 from jroper/concurrent-execution Feb 27, 2015
.gitignore Added optional plugin that allows overriding the builtin cross buildi… Feb 26, 2015
.travis.yml Travis Feb 27, 2015 reword Oct 31, 2017
build.sbt 0.1.5 Mar 3, 2015
sbt-doge.png wow Jul 21, 2014
scripted.sbt invert the loop Jul 21, 2014


‼️ This plugin is retired. sbt-doge has been merged in sbt 1. See #18. ‼️

sbt-doge is a sbt plugin to aggregate across crossScalaVersions for multi-project builds, which I call partial cross building.


Current implementation of + cross building operator does not take in account for the crossScalaVersions of the sub projects. Until that's fixed, here's an alternative implementation of it.


This is an auto plugin, so you need sbt 0.13.5+. Put this in project/doge.sbt:

addSbtPlugin("com.eed3si9n" % "sbt-doge" % "0.1.5")


First, define a multi-project build with a root project aggregating some child projects:

def commonSettings: Seq[Def.Setting[_]] = Seq(
  organization := "com.example.doge",
  version := "0.1-SNAPSHOT"

lazy val rootProj = (project in file(".")).
  aggregate(libProj, fooPlugin).
  settings(commonSettings: _*)

lazy val libProj = (project in file("lib")).
  settings(commonSettings: _*).
    name := "foo-lib",
    scalaVersion := "2.11.1",
    crossScalaVersions := Seq("2.11.1", "2.10.4")

lazy val fooPlugin =(project in file("sbt-foo")).
  settings(commonSettings: _*).
    name := "sbt-foo",
    sbtPlugin := true,
    scalaVersion := "2.10.4",
    crossScalaVersions := Seq("2.10.4")

Next run this from the root project:

> ;so clean; such test; very publishLocal

sbt-doge will break the above into the following commands and executes them:

> wow 2.11.1
> libProj/clean
> wow 2.10.4
> libProj/clean
> fooPlugin/clean
> wow 2.10.4
> wow 2.11.1
> libProj/test
> wow 2.10.4
> libProj/test
> fooPlugin/test
> wow 2.10.4
> wow 2.11.1
> libProj/publishLocal
> wow 2.10.4
> libProj/publishLocal
> fooPlugin/publishLocal
> wow 2.10.4

It is looking into aggregate of the current project, and for each aggregated project, running a loop for each crossScalaVersions and executing the passed in command. The currently supported prefixes are: much, so, such, and very.

wow is a better implementation of ++ that only affects the aggregated projects.


CrossPerProjectPlugin overrides sbt's + and ++ commands and uses doge's implementation that aggregates command respecting crossScalaVersions at each subproject. It is not a triggered plugin and so must be enabled using enablePlugins(CrossPerProjectPlugin).

can now be written as

> ;+ clean; + test; + publishLocal

strict aggregation

sbt-doge adds strict aggregation command plz. plz 2.11.5 compile will aggregate only the subproject that contains 2.11.5 in crossScalaVersions. The alias for plz command is +++ for CrossPerProjectPlugin.

Usage from sbt-release

sbt-doge can be used with the sbt-release plugin for the purposes of cross publishing as of sbt-release 1.0.4 onward. To use it you will want to ensure that releaseCrossBuild is set to false, and that your release steps incorporate certain + commands (see note below). Here is an example that substitues the regular test and publish steps with their cross build equivalents:

NOTE: the + command here assumes CrossPerProjectPlugin is enabled - if it is not either enable it or change the + to so or equivalent.

  releaseCrossBuild := false
  releaseProcess := Seq[ReleaseStep](

You will also need to ensure that any sub project that is used as a classpath dependency of another sub project i.e. referenced in a dependsOn, is also aggregated.

The ConductR Library project incorporates the above settings in order to deliver a complex build for Scala 2.11 and Scala 2.12. Certain sub projects are excluded from Scala 2.12 concerns as there will not be any support for them e.g. when considering Play 2.3 and Play 2.4. The resultant artifacts are signed and published to Maven Central.