The Gradle Enterprise sbt plugin improves your development workflow and your productivity, when developing and maintaining sbt builds. The plugin enables Build Scan insights and supports publishing to scans.gradle.com.
Gradle Enterprise 2023.2 or later is required.
sbt Build Scan functionality is not enabled by default with Gradle Enterprise. If you wish to use sbt with Gradle Enterprise, please contact your customer success representative. |
Getting set up
The latest version of the Gradle Enterprise sbt plugin is 0.10 and is compatible with all sbt versions above 1.6.0.
The instructions in this section describe applying and configuring the plugin for a single sbt project.
Applying the plugin
You apply the Gradle Enterprise sbt plugin to your build by adding the following configuration block to a new or existing project/plugins.sbt
file in your sbt project. The sbt plugin will be downloaded automatically from Maven Central once you load your build.
addSbtPlugin("com.gradle" % "sbt-gradle-enterprise" % "0.10")
Connecting to Gradle Enterprise
All Gradle Enterprise settings are grouped under one configuration object that needs to be set in the Global
scope. Unless you intend to publish build scans to scans.gradle.com, the minimum configuration required is that of the Gradle Enterprise server URL.
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
server = Server(
url = Some(url("https://gradle-enterprise.mycompany.com"))))
Other configuration options will be described as we introduce each feature, but you can find all configuration options in the configuration reference.
Allowing untrusted SSL communication
If your Gradle Enterprise server uses an SSL certificate that is not trusted by your build’s Java runtime, you will not be able to publish build scans without explicitly allowing untrusted servers.
To do this, set the allowUntrusted
option to true
:
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
server = Server(
url = Some(url("https://gradle-enterprise.mycompany.com")),
allowUntrusted = true))
Use of this configuration is a security risk as it makes it easier for a third party to intercept your build scan data. It should only be used as a short term workaround until the server can be configured with a trusted certificate.
Authenticating
Gradle Enterprise installations may be configured to require build scan publishing to be authenticated. Additionally, installations may be configured to only allow certain users to publish build scans. If your instance doesn’t require authentication, you can skip to Using build scans
Gradle Enterprise access keys should be treated with the same secrecy as passwords. They are used to authorize access to Gradle Enterprise from a build. |
Automated access key provisioning
The easiest way to configure a build environment to authenticate with Gradle Enterprise is to use the gradleEnterpriseProvisionAccessKey
task.
$ sbt gradleEnterpriseProvisionAccessKey
When executed, it opens your web browser and asks to confirm provisioning of a new access key. You will be asked to sign in to Gradle Enterprise in your browser first if you are not already signed in.
When confirmed, a new access key will be generated and stored in the keys.properties
file within the Gradle Enterprise storage directory (~/.sbt/.gradle-enterprise
by default).
Any existing access key for the same server will be replaced in the file, but will not be revoked at the server for use elsewhere. To revoke old access keys, sign in to Gradle Enterprise and access “My settings” via the user menu at the top right of the page.
If your browser cannot be opened automatically at the correct page, you will be asked to manually open a link provided in the build console. |
For all other options of authentication, see Authenticating with Gradle Enterprise
Connecting to scans.gradle.com
A free version of Gradle Enterprise is available at scans.gradle.com, but before you can publish a build scan you need to agree to the terms of service, which can be found at https://gradle.com/terms-of-service.
You can agree to the terms of service by adding the following configuration to the build:
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
buildScan = BuildScan(
termsOfService = Some(url("https://gradle.com/terms-of-service") -> true)))
Once you have accepted the terms of service, you can start publishing build scans to scans.gradle.com.
Be careful not to commit agreement to the terms of service into a project that may be built by others. |
Using build scans
Build Scan® is a shareable record of what happened during a build, captured and visualized by Gradle Enterprise.
What is part of a single build scan?
Unlike other build tools, sbt is often used by typing commands in its own interactive shell. In this mode, sbt will publish a build scan for each top-level task that it runs.
Interactive mode
For example, when invoking a single command in the shell:
sbt:test-project> compile
[info] compiling 1 Scala source to test-project/core/target/scala-2.13/classes ...
[info] compiling 1 Scala source to test-project/backend/target/scala-2.13/classes ..
[info] Publishing build scan...
[info] https://ge.mycompany.com/s/ohd4cybh6yc4g
Sbt allows one to chain several commands separated by semicolons, as in compile; test
. In this case, a build scan is published for each one of them:
sbt:test-project> compile; test
[info] compiling 1 Scala source to test-project/core/target/scala-2.13/classes ...
[info] compiling 1 Scala source to test-project/backend/target/scala-2.13/classes ...
[success] Total time: 1 s, completed 23 Jun 2023, 15:16:51
[info] Publishing build scan...
[info] https://ge.mycompany.com/s/lmzvnpyy66vbw
[info] compiling 2 Scala sources to test-project/core/target/scala-2.13/test-classes ...
...
[info] Publishing build scan...
[info] https://ge.mycompany.com/s/pg37gbjxr4sxo
Batch mode
When sbt is invoked with several tasks on the command line, as it’s often the case on CI, sbt will publish a single build scan for the whole sbt process.
$ sbt compile test
[info] welcome to sbt 1.9.0 (BellSoft Java 17.0.4)
[info] loading global plugins from /../.sbt/1.0/plugins
...
[info] Publishing build scan...
[info] https://ge.mycompany.com/s/5563ccpas77ua
Controlling when build scans are published
Once you’ve gone through the initial setup of the previous section, you are ready to start publishing build scans. But when should you publish them? Every time you run a build? Only when the build fails? It’s up to you. The Gradle Enterprise sbt plugin has several options that allow you to use whatever approach works best.
Publishing every build run
This is the default. There are many advantages to publishing build scans regularly, such as being able to track the behavior and performance of a build over time. It makes no sense relying on ad-hoc publishing of scans in such a situation as it’s easy to forget on the command line. Should you decide to explicitly enforce this default option, you can do this as follows
This approach means that you get a build scan for every successful and failed build that runs, including from your continuous integration infrastructure and your developers.
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
buildScan = BuildScan(
publishConfig = PublishConfig.Always))
If you want to deactivate build scans for a particular build, you can pass the |
Publishing on demand
We imagine that when you first start experimenting with build scans, you won’t want to publish them all the time until you become familiar with the implications. Even then, you may have good reason not to go all-in and automate the process. That’s where one-off build scans come in.
If you only want to publish build scans when explicitly requested, use the following publish configuration:
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
buildScan = BuildScan(
publishConfig = PublishConfig.OnDemand))
When publishing on-demand, you can pass the scan
system property to control publishing:
$ sbt -Dscan
This system property overrides the configured value, so it can also be used to disable publishing, regardless of the build setting by setting it to false
.
Publishing based on criteria
Many of you will want a bit more control over exactly when build scans are published without resorting to using -Dscan
each time. Perhaps you only want to publish build scans when the build fails, or if the build is running on your continuous integration infrastructure. Such scenarios are covered by the options in the following code snippets.
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
buildScan = BuildScan(
publishConfig = PublishConfig.OnFailure))
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
buildScan = BuildScan(
publishConfig = if (sys.env.contains("CI")) PublishConfig.Always else PublishConfig.OnDemand))
Configuring background uploading
By default, build scans are uploaded in the background after the build has finished. This allows the build to finish sooner, but can be problematic in build environments (e.g. ephemeral CI agents) that terminate as soon as the build is finished, as the upload may be terminated before it completes. Background uploading should be disabled for such environments.
Disabling programmatically
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
buildScan = BuildScan(
backgroundUpload = false
)
)
It may be desirable to conditionally set the value based on the environment.
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
buildScan = BuildScan(
backgroundUpload = sys.env.get("CI").exists(_.toBoolean)
)
)
Disabling via system property
Background uploading can be disabled by setting the gradle.scan.uploadInBackground
system property to false
. The system property setting always takes precedence over the programmatic setting.
$ sbt -Dgradle.scan.uploadInBackground=false compile test publish
Configuring project identifier
Detailed information regarding project-level access control can be found here.
Configuring programmatically
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
projectId = ProjectId("myProject")
)
Configuring via system property
Project identifier can be specified by setting the gradle.enterprise.projectId
. The system property setting always takes precedence over the programmatic setting.
$ sbt -Dgradle.enterprise.projectId=myProject compile test publish
Authenticating with Gradle Enterprise
The easiest way to configure a build environment to authenticate with Gradle Enterprise is to automatically provision an access key as covered in Automated access key provisioning. Depending on your needs, next are alternative options to manually configure an access key.
Manual access key configuration
Access keys can be configured manually for an environment, when automated provisioning is not suitable.
Creating access keys
To create a new access key, sign in to Gradle Enterprise and access “My settings” via the user menu at the top right of the page. From there, use the “Access keys” section to generate an access key.
The access key value should then be copied and configured in your build environment via file, environment variable or the settings file.
Via file
Gradle Enterprise access keys are stored inside the Gradle Enterprise storage directory user home directory (~/.sbt/.gradle-enterprise
by default), at keys.properties
, in a Java properties file. The property name refers to the host name of the server, and the value is the access key.
gradle-enterprise.mycompany.com=7w5kbqqjea4vonghohvuyra5bnvszop4asbqee3m3sm6dbjdudtq
The file may contain multiple entries. The first entry for a given host value will be used.
Via environment variable
The access key may also be specified via the GRADLE_ENTERPRISE_ACCESS_KEY
environment variable. This is typically more suitable for CI build environments.
The environment variable value format is «server host name»=«access key»
.
$ export GRADLE_ENTERPRISE_ACCESS_KEY=gradle-enterprise.mycompany.com=7w5kbqqjea4vonghohvuyra5bnvszop4asbqee3m3sm6dbjdudtq && \
sbt compile
The server host name is specified in order to prevent the access key being transmitted to a different server than intended. In the rare case that you require access keys for multiple servers, you can specify multiple entries separated by semicolons.
$ export GRADLE_ENTERPRISE_ACCESS_KEY=ge1.mycompany.com=7w5kbqqjea4vonghohvuyra5bnvszop4asbqee3m3sm6dbjdudtq;ge2.mycompany.com=9y4agfiubqqjea4vonghohvuyra5bnvszop4asbqee3m3sm67w5k && \
sbt compile
Via configuration
You can also specify the access key in your build file:
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
server = Server(
url = Some(url("https://gradle-enterprise.mycompany.com")),
accessKey = Some("7w5kbqqjea4vonghohvuyra5bnvszop4asbqee3m3sm6dbjdudtq")))
Extending build scans
You can easily include extra custom information in your build scans in the form of tags, links and values. This is a very powerful mechanism for capturing and sharing information that is important to your build and development process.
This information can be anything you like. You can tag all builds run by your continuous integration tool with a CI
tag. You can capture the name of the environment that the build published to as a value. You can link to the source revision for the build in an online tool such as GitHub. The possibilities are endless.
You can see how the custom data appears in figures 1 and 2:


Gradle Enterprise allows listing and searching across all of the build scans in the system. You can find and filter build scans by tags and custom values, in addition to project name, outcome and other properties. In figure 3, for example, we are filtering for all build scans that have the tag "CI" and a git branch name of "master":

Adding tags
Tags are typically used to indicate the type or class of a build, or a key characteristic. They are prominent in the user interface and quickly inform a user about the nature of a build. A build can have zero or more tags.
They can be added at build time via the buildScan.tags
field:
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
buildScan = BuildScan(
tags = Set(
if (sys.env.contains("CI")) "CI" else "Local",
sys.props("os.name"))))
scan.tag.<tag>
system property to sbt
$ sbt -Dscan.tag.CI -Dscan.tag.$(uname -o)
As demonstrated by the example above, tags are typically applied either as fixed strings within a condition or evaluated at runtime from the environment. But there are no set rules that you need to follow—these are only suggestions.
Note that the order in which you declare the tags doesn’t affect the build scan view. They are displayed in alphabetical order, with any all-caps labels displayed before the rest.
There are limits on captured tags:
|
Adding links
Builds rarely live in isolation. Where does the project source live? Is there online documentation for the project? Where can you find the project’s issue tracker? If these exist and have a URL, you can add them to the build scan.
They can be added at build time via the buildScan.links
field:
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
buildScan = BuildScan(
links = Map(
"VCS" -> url(s"https://github.com/myorg/sample/tree/${sys.props("vcs.branch")}"))))
$ sbt -Dscan.link.VCS=https://github.com/myorg/my-super-project/tree/my-new-feature
The above example demonstrates how you can attach a link to an online VCS repository that points to a specific branch provided as a system property.
Links are Scala pairs, with the first field being the label, and the second one a valid URL. The <label> is simply a string identifier that you choose and that means something to you.
You can see the effect of a custom link in figure 1, which shows how a label Source becomes a hyperlink that anyone viewing the build scan can follow.
There are limits on captured links:
|
Adding custom values
Some information just isn’t useful without context. What does "1G" mean? You might guess that it represents 1 gigabyte, but of what? It’s only when you attach the label "Max heap size for build" that it makes sense. The same applies to git commit IDs, for example, which could be interpreted as some other checksum without a suitable label.
Custom values are designed for these cases that require context. They’re standard key-value pairs, in which the key is a string label of your choosing and the values are also strings, often evaluated from the build environment.
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
buildScan = BuildScan(
values = Map(
"Scala version" -> scalaVersion.value)))
$ sbt "-Dscan.value.Git branch=$(git branch --show-current)"
This examples shows that you can include any sbt setting value. This applies to tags and links as well.
As with tags, you can filter build scans by custom values in Gradle Enterprise.
There are limits on captured custom values:
|
Capturing settings and configuration options
Gradle Enterprise sbt plugin captures the state of selected boolean settings and configuration options. These settings and configuration options can have a significant impact on the behavior of the entire build. Monitoring them provides insights into the overall build configuration. The state of the captured settings and configuration options is available via the Build Scan.
All settings are captured at ThisBuild
scope.
Background build scan publication
Indicates whether the build was configured to upload the Build Scan in the background.
Information about how to configure background uploading for build scans can be found in Configuring background uploading section.
Use Coursier
Indicates whether the build was configured to use Coursier for dependencies resolution.
Coursier is the default dependency resolution library since sbt 1.3.0
Offline
Indicates whether the sbt was configured to work without a network connection where possible.
Turbo
Indicates whether the build was configured to use optional performance optimization features.
Turbo mode is available since sbt 1.3.0.
Parallel execution
Indicates whether the build was configured to use parallel tasks execution.
Information about parallel tasks execution can be found in the reference documentation.
SemanticDB Scalac plugin
Indicates whether the projects in the build were configured to use SemanticDB Scalac plugin.
SemanticDB support is available since sbt 1.3.0.
Interactive mode
Indicates whether the build was run from within the sbt shell, or in batch mode.
Information about the sbt interactive mode can be found in the reference documentation.
Obfuscating identifying data
Build scans capture certain identifying information such as the operating system username, hostname and network addresses. You may choose to obfuscate this data so that it is not decipherable in build scans when viewed, by registering obfuscation functions as part of the sbt plugin configuration.
The following examples show registering obfuscation functions for the different identifying data.
Obfuscating the username:
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
buildScan = BuildScan(
obfuscation = Obfuscation(
username = _.reverse
)
)
)
Obfuscating the hostnames:
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
buildScan = BuildScan(
obfuscation = Obfuscation(
hostname = _.toCharArray.map(_.getNumericValue).mkString("-")
)
)
)
Obfuscating the IP addresses:
Global / gradleEnterpriseConfiguration :=
GradleEnterpriseConfiguration(
buildScan = BuildScan(
obfuscation = Obfuscation(
ipAddresses = _.map(_ => "0.0.0.0")
)
)
)
Troubleshooting
Failed background build scan uploads
When using background build scan uploading (default behaviour, see this section for configuration options) upload failures are not visible in the build logging due to occurring in a background process after the build has finished. Instead, errors are logged to a file located at ~/.sbt/.gradle-enterprise/build-scan-data/upload-failure.log
. If this additional information does not help to resolve the failure, please contact technical support and include the contents of this log file.
If the background upload process fails to start, a warning is shown in the build console and uploading is performed in the build process. If this occurs, please contact technical support with the log files located at ~/.sbt/.gradle-enterprise/build-scan-data/<<plugin-version>>/pending-uploads/*.log
.
Slow resolution of host name
Build scans attempt to determine the host name of the machine. An issue affecting macOS can cause a delay when doing this in some environments.
If you see a warning during your build that resolving the local host name is slow, you can workaround the problem by adding a host name mapping to your /etc/hosts
file.
Add these lines to your /etc/hosts
file, substituting your computer name for 'mbpro' in the below snippet:
127.0.0.1 localhost mbpro.local
::1 localhost mbpro.local
Appendix A: Configuration reference
GradleEnterpriseConfiguration
case class GradleEnterpriseConfiguration(
/** Directory for temporary storage and caches. */
storageDirectory: File = BuildPaths.defaultGlobalBase / GradleEnterpriseConfiguration.DirectoryName,
server: Server = Server(
/** An optional name */
id: Option[String] = None,
/** The url of the server */
url: Option[URL] = None,
/** Whether to allow untrusted SSL connections (if the SSL certification authority is not recognized by the JVM) */
allowUntrusted: Boolean = false,
/** The access key (without any hostname prefix) for authenticating with the Gradle Enterprise server. Environment variable is 'GRADLE_ENTERPRISE_ACCESS_KEY'. */
accessKey: Option[String] = None
),
buildScan: BuildScan = BuildScan(
/** Publishing behavior. Can be overriden with the system property `scan` */
publishConfig: PublishConfig = PublishConfig.Always,
/** Whether to upload scans in a background thread. Can be overridden via the `gradle.scan.uploadInBackground` system property */
backgroundUpload: Boolean = true,
/** Terms of service acceptance (mandatory to publish to scans.gradle.com) */
termsOfService: Option[(URL, Boolean)] = None,
/** List of tags to capture. Additionally, system properties like 'scan.tag.<tag>' can be used to add tags. - */
tags: Set[String] = Set.empty,
/** List of links to capture. Additionally, system properties like 'scan.link.<name>=<url>' can be used to add links. */
links: Map[String, URL] = Map.empty,
/** List of custom values to capture. Additionally, system properties like 'scan.value.<name>=<value>' can be used to add custom values. */
values: Map[String, String] = Map.empty,
obfuscation: Obfuscation = Obfuscation(
/** The function used to obfuscate the captured username. */
username: String => String = identity,
/** The function used to obfuscate the captured local hostname and public hostname */
hostname: String => String = identity,
/** The function used to obfuscate the captured IP addresses. */
ipAddresses: Seq[InetAddress] => Seq[String] = _.map(_.getHostAddress)
)
)
)
Appendix B: Settings and tasks provided by the Gradle Enterprise sbt plugin
The following settings and tasks are exposed by the Gradle Enterprise sbt plugin.
Settings
gradleEnterpriseConfiguration
(sbt plugin 0.9+)
Setting storing the Gradle Enterprise configuration.
Tasks
gradleEnterpriseBuildScanPublishPrevious
(sbt plugin 0.9+)
Publishes the build scan captured by the last build.
gradleEnterpriseProvisionAccessKey
(sbt plugin 0.9+)
Authenticates your build environment with Gradle Enterprise.
Appendix C: Captured information
The Gradle Enterprise sbt plugin captures information while the build is running and transmits it to a server after the build has completed.
Most of the information captured can be considered to be build data. This includes the name of the projects in your build, the tasks, plugins and other things of this nature. Some more general environmental information is also captured. This includes your Java version, operating system, hardware, country, timezone and other things of this nature.
Notably, the actual source code being built and the output artifacts are not captured. However, error messages emitted by compilers or errors in tests may reveal aspects of the source code.
Listing
The list below details the notable information captured by the Gradle Enterprise sbt plugin and transmitted in a build scan.
-
Environment
-
Username (system property
'user.name'
) (Can be obfuscated) -
Local hostname (environment variable
'COMPUTERNAME'
/'HOSTNAME'
) (Can be obfuscated) -
Public hostname (Can be obfuscated)
-
Local IP addresses (Can be obfuscated)
-
-
Build
-
Build invocation options (e.g. requested commands, switches)
-
Build console output
-
Build failure exception messages and stacktraces
-
Background build scan publication
-
Access
Build scans published to a Gradle Enterprise installation are viewable by all users that can reach the server and have the required roles, should Identity Access Management (IAM) be turned on. Gradle Enterprise provides a search interface for discovering and finding individual build scans.
Build scans published to scans.gradle.com are viewable by anyone with the link assigned when publishing the build scan. Links to individual build scans are not discoverable and cannot be guessed, but may be shared.
Appendix D: Release history
0.10
-
[NEW] Add support for project level access control
-
[NEW] Add capturing of logs written to standard output and standard error
Compatible with scans.gradle.com and Gradle Enterprise 2023.3 or later.
0.9
-
[NEW] Initial beta release compatible with Gradle Enterprise 2023.2
Compatible with scans.gradle.com and Gradle Enterprise 2023.2 or later.
Appendix E: Compatibility with sbt and Gradle Enterprise
Compatibility between versions of sbt, Gradle Enterprise, and the Gradle Enterprise sbt plugin can be found here.
Appendix F: Known issues
Configuration
Default storage directory always in the default sbt global directory
(sbt plugin 0.9+)
The default storage directory (.gradle-enterprise
) is always located inside the default sbt global directory (${user.home}/.sbt
), even if a different sbt global directory is set via the sbt BuildPaths.globalBaseDirectory
attribute or the sbt.global.base
system property.
The storage directory can be changed either via the gradle.enterprise.storage.directory
system property or by specifying the desired location via the configuration class in the sbt build file.
Console log
Coursier downloaded dependencies
(sbt plugin 0.9)
Logs of the artifacts downloaded by Coursier are not captured in build scans. This is because they are printed to the standard output, which does not get captured in build scans (a known limitation, see Standard output).
To capture Coursier logs use the Gradle Enterprise sbt plugin 0.10
or later.
Log messages via sLog
(sbt plugin 0.9+)
The Gradle Enterprise sbt plugin does not capture logs generated via the sbt sLog
logger (refer to the sbt documentation log messages in a setting for details).
If sLog
is used inside a task definition, use streams.value.log.info
instead (as suggested by the related sbt documentation) for the log messages to be captured in build scans.
If sLog
is used inside a setting definition, no workaround is available.
MUnit test output
(sbt plugin 0.9)
The Gradle Enterprise sbt plugin 0.9
does not capture logs generated by the MUnit testing library because they are printed to the standard output (a known limitation, see Standard output).
To capture logs generated by MUnit in build scans use the Gradle Enterprise sbt plugin 0.10
or later. Alternatively add the following to your projects' settings:
Test / testOptions += Tests.Argument(TestFrameworks.MUnit, "+l")
Standard output
(sbt plugin 0.9)
The Gradle Enterprise sbt plugin 0.9
does not capture messages printed to the standard output.
To capture messages printed to the standard output use the Gradle Enterprise sbt plugin 0.10
or later. Alternatively use streams.value.log.info
inside a task definition for the log messages to be captured in build scans. Refer to the sbt documentation log messages in a task for details.
Failure
Out of memory errors not captured
(sbt plugin 0.9+)
If an executing task throws a java.lang.OutOfMemoryError (or any other subclass of java.lang.VirtualMachineError), the build scans will not report the failure nor capture the error reported in the log.
IntelliJ IDEA
No build scans with the sbt shell
(sbt plugin 0.9)
Requested task
Incorrect task reported on subprojects
(sbt plugin 0.9+)
In interactive mode, when executing tasks from a specific subproject rather than the root project, the requested task will be wrongly identified as the last command issued to switch project (i.e. project <projectname>
), rather than the actual task executed after having switched project.
The workaround is to execute all commands from the root project using the <projectname>/<task>
notation instead.