Chain task execution on subprojects

Hello guys,

I have a multi-module Gradle project with multiple samples grouped by categories as follows:

./ gradlew projects

Root project 'my-project'
+--- Project ':demos'
\--- Project ':samples'
     +--- Project ':samples:begginer'
     |    +--- Project ':samples:begginer:sampleA'
     |    +--- ...  [many more]
     |    \--- Project ':samples:begginer:sampleB'
     +--- Project ':samples:intermediate'
     |    +--- Project ':samples:intermediate:sampleC'
     |    +--- ...  [many more]
     |    \--- Project ':samples:intermediate:sampleD'
     \--- Project ':samples:advaned'
          +--- Project ':samples:advaned:sampleE'
          +--- ...  [many more]
          \--- Project ':samples:advaned:sampleF'

Because of the high number of those samples and their simplicity (no dependencies between them), the project structure is generated dynamically by the script:

# settings.gradle.kts

File(rootDir, "samples").walk().maxDepth(2)
  .filter {
     it.isDirectory
   }.forEach {
     include(it.path.replace(rootDir.path, "").replace(File.separatorChar, ':'))
   }

With this structure, I would like to build them in the following manner:

  1. Build the whole project ./gradlew build
  2. Build all existing samples ./gradle :samples:build
  3. Build only easy samples ./gradle :samples:easy:build
  4. Build a specific sample./gradle :samples:advance:sampleE:build

Currently, lines (1) and (4) works as expected, but (2) and (3) only executes build task for the category subproject without triggering the actual tasks for their children (samples).

After reading these topics one and two I got the feeling that the category task needs to depend on all its children tasks. If so, could you please suggest if this can be done dynamically and if there are any samples on Groovy/Kotlin DSL?

Any help is highly appreciated!

For the record: so far I came up with the following script

# build.gradle.kts

subprojects {
...
  afterEvaluate {
    childProjects.forEach {
      tasks.forEach { task ->
        task.dependsOn(":${project.path}:${it.value.name}:${task.name}")
      }
    }
  }
}

which actually binds all child project tasks to the current subproject, in my case:

:samples:build dependsOn
  :samples:beginner:build
  :samples:intemediate:build
  :samples:advanced:build

:samples:beginner:build dependsOn
  :samples:beginner:sampleA:build
  ...
  :samples:beginner:sampleB:build

:samples:intemediate:build dependsOn
  :samples:intemediate:sampleC:build
  ...
  :samples:intemediate:sampleD:build

etc.

Please let me know if you find a better way of doing this.