Is there a way to define property to be used in both settings.gradle.kts and projects/subprojects build.gradle.kts with gradle 6.0?

See ticket #11090 "Definitions from buildSrc/ not found in settings.gradle.kts using gradle 6.0-rc-1".

As you already noticed this changed recently:

This has changed in 6.0, and was deprecated in 5.6. Please see: https://docs.gradle.org/current/userguide/upgrading_version_5.html#buildsrc_usage_in_gradle_settings

-- https://github.com/gradle/gradle/issues/11090#issuecomment-544473179

One of the maintainers describes the reasons behind the decision:

Unfortunately, there are pros and cons to both arrangements (settings-then-buildSrc and buildSrc-then-settings), and we opted for the former after considering.

(...)

The pros that compelled us to make the change:

  1. Settings plugins can influence buildSrc and main build (i.e. apply a build plugin to both)
  2. Build cache configuration is applied to buildSrc
  3. buildSrc behaves more like a regular included build

-- https://github.com/gradle/gradle/issues/11090#issuecomment-545697268

And finally some bad news:

We won't be changing the behaviour back to the pre Gradle 6 arrangement. Please let us know if you would like more detail on how to use one of the alternative mechanisms for using complex logic in a settings script.

-- https://github.com/gradle/gradle/issues/11090#issuecomment-545697268

Workarounds

In the aforementioned post the author proposes some workarounds:

The con of this is exactly what you have hit. It's now less convenient to use complex logic in your settings script. Now, you have to either:

  1. Inline the logic into the settings file
  2. Move the logic to a shared script that can be used where it needs to
  3. Move the logic to a pre-built binary that you load in the settings file (i.e. a settings plugin)

-- https://github.com/gradle/gradle/issues/11090#issuecomment-545697268

#1 is pretty straightforward, but I can only assume what #2 and #3 mean. I come from the Groovy world and only recently started making friends with Kotlin DSL. Having said that let's give it a try.

In #3 the author might be talking about developing an external plugin and applying it in both scripts. I'm not really sure if this is something that would make sense to implement (it gives you strong typing though).

"#2 Move the logic to a shared script that can be used where it needs to"

I think it's about having a common script plugin and including it in both settings.gradle and build.gradle files. The plugin would put the static information in the ExtraPropertiesExtension of the ExtensionAware in scope (Settings in case of a settings.gradle script plugin and Project in case of build.gradle). This is described in this answer to "Include scripts with Gradle Kotlin DSL":

How can I put all common constants (such as dependency versions) to the separate file to include them just by using something like springBootVersion or Constants.springBootVersion with compile-time checks?

There is no good way to do it currently. You can use extra properties, but it won't guarantee compile time checks. Something like that:

// $rootDir/dependencies.gradle.kts

// this will try to take configuration from existing ones
val compile by configurations
val api by configurations
dependencies {
  compile("commons-io:commons-io:1.2.3")
  api("some.dep")
}

// This will put your version into extra extension
extra["springBootVersion"] = "1.2.3"

And you can use it like this:

// $rootDir/build.gradle.kts
subprojects {
  apply {
    plugin<JavaLibraryPlugin>()
    from("$rootDir/dependencies.gradle.kts")
  }

And in your module:

// $rootDir/module/build.gradle.kts
// This will take existing dependency from extra
val springBootVersion: String by extra
dependencies {
  compile("org.spring:boot:$springBootVersion")
}

-- Include scripts with Gradle Kotlin DSL