Add a New Gradle Subproject
This skill walks through adding a new subproject to the Gradle multi-project build. It handles registering the project in settings, creating the build script, generating metadata, and creating the source directory structure.
Information to Gather
Before starting, you need these details from the user (ask if not provided):
- Project name - The kebab-case name (e.g.,
build-discovery,language-java) - Target platform and module - Where in
settings.gradle.ktsto register it. The hierarchy is:platform("core")contains modules:core-runtime,core-configuration,core-executionplatform("software")- flat list of subprojects (no nested modules)platform("jvm")- flat list of subprojectsplatform("extensibility")- flat list of subprojectsplatform("native")- flat list of subprojects- Top-level modules (not inside a platform):
documentation,ide,enterprise - Special sections:
packaging,testing
- Whether the project contains public API and what language is used - Determines the plugin:
- Public API/Java →
gradlebuild.distribution.api-java - Public API/Kotlin →
gradlebuild.distribution.api-kotlin - Internal only/Java →
gradlebuild.distribution.implementation-java - Internal only/Kotlin →
gradlebuild.distribution.implementation-kotlin
- Public API/Java →
- A short description of what the project does
Steps
1. Register in settings.gradle.kts
Open settings.gradle.kts at the project root and add a subproject("<project-name>") line in the correct platform/module block. Insert it in alphabetical order among the existing subproject entries.
For example, adding my-new-project to core-runtime:
module("core-runtime") {
subproject("messaging")
subproject("my-new-project") // inserted alphabetically
subproject("native")
}
The physical directory is derived automatically from the platform/module path, e.g.:
- Platform
core, modulecore-runtime→platforms/core-runtime/<project-name>/ - Platform
software(no module) →platforms/software/<project-name>/ - Module
ide(top-level) →platforms/ide/<project-name>/ packaging→packaging/<project-name>/testing→testing/<project-name>/
2. Create the build script
Create build.gradle.kts in the project directory with this structure:
plugins {
id("gradlebuild.distribution.<api-java|api-kotlin|implementation-java|implementation-kotlin>")
}
description = "<description>"
dependencies {
// Group dependencies by configuration, sorted alphabetically within each group:
// api(projects.xxx)
// api(libs.xxx)
//
// implementation(projects.xxx)
// implementation(libs.xxx)
//
// integTestDistributionRuntimeOnly(projects.distributionsCore)
}
gradleModule {
computedRuntimes {
// Auto-generated by `:checkTargetRuntimes --fix`
client = true
daemon = true
worker = true
}
}
errorprone {
nullawayEnabled = true
}
Note: Do NOT include a copyright header - the build script doesn't need one.
If the user has mentioned specific dependencies, add them to the appropriate configuration groups (api, implementation, etc.), sorted alphabetically within each group. Separate groups of different configurations with a blank line.
For brand new projects, nullawayEnabled should be set to true. For projects whose source is being migrated from another project, the new project should inherit the value from the project that source is migrated from.
3. Create source directories
Create these empty directories:
src/main/java/ORsrc/main/kotlin/- Production sourcesrc/test/groovy/- Unit tests (Spock)src/integTest/groovy/- Integration tests (Spock)
Use mkdir -p to create them all at once.
4. Run generateSubprojectsInfo
Run the Gradle task to regenerate .teamcity/subprojects.json:
./gradlew generateSubprojectsInfo
This scans all project directories and updates the TeamCity metadata file with the new project entry. The generated entry will include the project name, path, and flags for whether it has unit tests, integration tests, or cross-version tests based on the presence of the corresponding src/ directories.
5. Run checkTargetRuntimes
Run the Gradle task to automatically determine which Gradle runtimes the project should target based on its dependencies:
./gradlew :checkTargetRuntimes --fix
6. Verify
After all steps complete, confirm to the user:
- The project is registered in
settings.gradle.kts - The build script is created at the correct path
- Source directories exist
subprojects.jsonhas been regenerated./gradlew sanityCheckpasses with no errors