Gradle multimodule
Skill SKaiNET-developers/SKaiNET-coding-skills/skainet-contributor-skills/skills/gradle-multimodule
Use ONLY when editing build scripts INSIDE the SKaiNET repository — `SKaiNET/build.gradle.kts`, `SKaiNET/settings.gradle.kts`, `SKaiNET/gradle/libs.versions.toml`, anything under `SKaiNET/build-logic/`, or adding/renaming/removing a `skainet-*` module within SKaiNET. Enforces version-catalog-only references, convention-plugin reuse, BOM registration, binary-compatibility-validator, vanniktech maven-publish, kover. Do NOT fire on a CONSUMER project's build script that just depends on `sk.ainet:skainet-bom` — that's the `skainet-consumer-setup` skill.From its SKILL.md
npx -y skills add SKaiNET-developers/SKaiNET-coding-skills --skill gradle-multimoduleAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
8.1 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it
gradle-multimodule
Rules for editing the SKaiNET multi-module Gradle build. The project is a Gradle composite build: build-logic/ is included via includeBuild and contributes convention plugins; every module under skainet-*/ is included from settings.gradle.kts; all dependency coordinates resolve through gradle/libs.versions.toml.
When to use
- Adding, renaming, or removing a Gradle module.
- Editing any
build.gradle.kts,settings.gradle.kts, or*.gradle.ktsunderbuild-logic/. - Editing
gradle/libs.versions.toml(versions, libraries, plugins, bundles). - Wiring a new dependency into a module.
- Adjusting publication, BOM membership, or coverage configuration.
When NOT to use
- Selecting which Kotlin source-set a file belongs in or which KMP target a module supports — that's
kmp. - Writing the actual production Kotlin code — that's
kotlin. - Test wiring beyond adding the dependency line —
skainet-testingowns assertion APIs and source-set placement for tests.
Hard rules
- Version-catalog-only. Every dependency, plugin, and version reference in any
build.gradle.ktsMUST go throughlibs.versions.<x>,libs.<library>, orlibs.plugins.<plugin>. Hard-coded version strings ("1.10.2",version = "2.3.21") MUST NOT appear in module build scripts. - Plugins via
alias(libs.plugins.<x>). Directid("...") version "..."is reserved for two cases only: (a) thesk.ainet.documentationconvention plugin (no version because it's local), (b) plugins inbuild-logic/build.gradle.ktsitself. - New module = three edits in one change. When adding a
skainet-foomodule: (a) createskainet-foo/build.gradle.kts, (b) addinclude("skainet-foo")(or the nested form) tosettings.gradle.kts, (c) register it inskainet-bom/build.gradle.ktsif it ships as a published artifact. - Dokka comes from the
sk.ainet.dokkaconvention plugin. Modules apply it viaid("sk.ainet.dokka"), not by configuring Dokka directly. Convention plugins live inbuild-logic/convention/src/main/kotlin/. binary-compatibility-validatoris applied on every published module. Don't suppress it locally; if the API dump changes, regenerate via./gradlew :module:apiDumpand commit the diff (seekotlinskill, api-stability reference).- JVM target = 11 across the project. Set via
compilerOptions { jvmTarget.set(JvmTarget.JVM_11) }inside theandroid { }block and inherited elsewhere through KMP defaults. Do not set higher. - No transitive accidents. Use
api(...)only when the dependency's types appear in a module's public Kotlin signatures. Default toimplementation(...). KSP-generated source goes throughadd("kspCommonMainMetadata", project(":skainet-...:...-ksp-processor")).
Workflow — adding a new module
- Decide the area: pick the right top-level group (
skainet-lang,skainet-data,skainet-io,skainet-backends,skainet-compile,skainet-models,skainet-pipeline,skainet-apps,skainet-test). - Create the directory and a minimal
build.gradle.ktsthat mirrors the closest sibling. Apply the same plugin set (kotlinMultiplatform,vanniktech.mavenPublish,binary.compatibility.validator,sk.ainet.dokka, optionallyksp,kotlinx-benchmark). - Add
include("skainet-<group>:<module>")tosettings.gradle.ktsin the matching// ====== <GROUP>section. - Add the catalog entry if the module exposes a new external dependency (rare).
- If the module is published, register it in
skainet-bom/build.gradle.kts. - Run
./gradlew :skainet-<group>:<module>:assembleto validate the wiring. - If a public API was introduced, run
./gradlew :skainet-<group>:<module>:apiDumpand commit the dump.
Canonical examples
Module build.gradle.kts — KMP library with KSP and Dokka:
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidMultiplatformLibrary)
alias(libs.plugins.vanniktech.mavenPublish)
alias(libs.plugins.binary.compatibility.validator)
alias(libs.plugins.ksp)
id("sk.ainet.dokka")
id("org.jetbrains.kotlinx.benchmark")
}
kotlin {
explicitApi()
// ... target list goes here — see kmp skill ...
sourceSets {
commonMain {
kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin")
dependencies {
api(project(":skainet-lang:skainet-lang-ksp-annotations"))
}
}
jvmMain.dependencies {
implementation(libs.kotlinx.benchmark.runtime)
}
commonTest.dependencies {
implementation(libs.kotlin.test)
}
}
}
// from: SKaiNET/skainet-lang/skainet-lang-core/build.gradle.kts:4-69
Catalog entries — every coordinate routed through libs.versions.toml:
[versions]
kotlin = "2.3.21"
ksp = "2.3.6"
dokka = "2.1.0"
kotest = "6.1.11"
kover = "0.9.8"
binaryCompatibilityValidator = "0.18.1"
[libraries]
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotest-runner-junit5 = { module = "io.kotest:kotest-runner-junit5", version.ref = "kotest" }
kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" }
[plugins]
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
skainet-docs = { id = "sk.ainet.documentation" }
// from: SKaiNET/gradle/libs.versions.toml:1-95
settings.gradle.kts — module registration, grouped by area:
includeBuild("build-logic")
// ====== LANG
include("skainet-lang:skainet-lang-core")
include("skainet-lang:skainet-lang-models")
include("skainet-lang:skainet-lang-ksp-annotations")
include("skainet-lang:skainet-lang-ksp-processor")
include("skainet-lang:skainet-lang-dag")
// ====== DATA
include("skainet-data:skainet-data-api")
include("skainet-data:skainet-data-transform")
include("skainet-data:skainet-data-simple")
include("skainet-data:skainet-data-media")
// ====== TEST
include("skainet-test:skainet-test-groundtruth")
include("skainet-test:skainet-test-java")
// from: SKaiNET/settings.gradle.kts:21-73
Related skills
- KMP target list, source-set hierarchy, and
expect/actualplacement — see../kmp/SKILL.md. - Source-code style rules and explicit-API mode — see
../kotlin/SKILL.md. - Adding the Kotest dependency for a test source set — see
../skainet-testing/SKILL.md.
Anti-patterns
// WRONG — hard-coded coordinate / version
implementation("io.kotest:kotest-runner-junit5:6.1.11")
// RIGHT — catalog reference
implementation(libs.kotest.runner.junit5)
// WRONG — applying Dokka by id
plugins { id("org.jetbrains.dokka") version "2.1.0" }
// RIGHT — apply the convention plugin (it configures Dokka)
plugins { id("sk.ainet.dokka") }
// WRONG — adding a new module without registering it
// (skainet-io/skainet-io-newformat/build.gradle.kts created, but settings.gradle.kts unchanged)
// RIGHT — also edit settings.gradle.kts AND skainet-bom in the same change
include("skainet-io:skainet-io-newformat") // in settings.gradle.kts
References
references/catalog-aliases.md— version, library, and plugin aliases pulled fromlibs.versions.toml.references/convention-plugins.md— whatsk.ainet.documentation/sk.ainet.dokkadoes and how to add a new convention plugin.
What ships with it: 3 files
8.9 KB alongside SKILL.md
evals/
- evals.json2.3 KB
references/
- catalog-aliases.md4.0 KB
- convention-plugins.md2.5 KB