diff --git a/CLAUDE.md b/CLAUDE.md index ec65a09c..c5a61864 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -108,6 +108,12 @@ Layered, from the bottom up: public entry point (e.g. only `OkioIoProvider` is public in `sdk-io-okio3`). - **`sdk-core` has zero non-SLF4J runtime deps** — I/O, Jackson, and concurrency libraries live only in adapter modules. SLF4J is `compileOnly` (added by the root build to every Kotlin module). +- **Published modules apply `id("dexpace.published-module")`** — the convention plugin in the `build-logic` + included build (`build-logic/src/main/kotlin/dexpace.published-module.gradle.kts`) carries the + `maven-publish` + `signing` setup, shared POM, staging repo, and CI-gated signing. Do not re-inline a + `publishing {}`/`signing {}` block in a module; a new publishable module just applies the plugin, and a + module that must not be published simply omits it. Coordinates (`group`/`version`) come from + `gradle.properties` and apply to every project. - **Commit style:** `feat:` / `test:` / `docs:` / `chore:` prefixes; `merge:` for work-unit merge commits. ## Things That Will Bite You diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts new file mode 100644 index 00000000..5512a694 --- /dev/null +++ b/build-logic/build.gradle.kts @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2026 dexpace and Omar Aljarrah + * + * Licensed under the MIT License. See LICENSE in the project root. + * SPDX-License-Identifier: MIT + */ + +// The `kotlin-dsl` plugin lets this build compile precompiled script plugins — every +// `src/main/kotlin/*.gradle.kts` file becomes a plugin whose id is its file name minus the +// `.gradle.kts` suffix (e.g. `dexpace.published-module`). Consumers in the main build apply +// it by that id once `settings.gradle.kts` has `includeBuild("build-logic")` on the plugin +// classpath. +plugins { + `kotlin-dsl` + // Style-gate this included build's own scripts. `build-logic` is a separate build with its + // own settings, so the root build's `subprojects { ktlint }` block does not reach it; without + // this the convention-plugin `.kts` files would escape the repository's Kotlin style checks. + // The version is pinned literally (not via the version catalog) to keep this build catalog-free + // — see the rationale in `settings.gradle.kts`; it must match `ktlint-plugin` in + // `gradle/libs.versions.toml`. + id("org.jlleitschuh.gradle.ktlint") version "12.1.1" +} + +repositories { + mavenCentral() + gradlePluginPortal() +} + +// Pin the toolchain so this included build compiles reproducibly regardless of the JDK running +// the Gradle daemon. This is plugin code for the build JVM, not shipped bytecode, so the version +// only needs to be recent enough for `kotlin-dsl`. +kotlin { + jvmToolchain(21) +} + +ktlint { + ignoreFailures.set(false) +} + +// `kotlin-dsl` adds its plugin wrappers and DSL accessors (under build/generated-sources) to the +// `main` Kotlin source set, so the source-set ktlint tasks would otherwise lint tool-generated +// code. Drop the generated tree from those tasks' inputs; the hand-written convention scripts under +// src/ — and the build script via `runKtlintCheckOverKotlinScripts` — are still checked. +val generatedSourcesDir = layout.buildDirectory.dir("generated-sources").get().asFile +tasks.withType().configureEach { + val handWritten = source.filter { file -> !file.startsWith(generatedSourcesDir) }.files + setSource(handWritten) +} diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts new file mode 100644 index 00000000..a1e6bf7b --- /dev/null +++ b/build-logic/settings.gradle.kts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2026 dexpace and Omar Aljarrah + * + * Licensed under the MIT License. See LICENSE in the project root. + * SPDX-License-Identifier: MIT + */ + +// Standalone settings for the `build-logic` included build. This build compiles the +// repository's convention plugins (precompiled `*.gradle.kts` script plugins) so that the +// production modules can apply them by id instead of duplicating configuration. +// +// `build-logic` deliberately depends on nothing from the version catalog: its sole convention +// plugin wires the core `maven-publish` and `signing` plugins, which ship with Gradle itself +// and therefore need no version. Keeping the included build catalog-free avoids extra +// `dependencyResolutionManagement { versionCatalogs { ... } }` plumbing and the associated +// classpath coupling between the main build and its own build logic. + +rootProject.name = "build-logic" diff --git a/build-logic/src/main/kotlin/dexpace.published-module.gradle.kts b/build-logic/src/main/kotlin/dexpace.published-module.gradle.kts new file mode 100644 index 00000000..20c4af50 --- /dev/null +++ b/build-logic/src/main/kotlin/dexpace.published-module.gradle.kts @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2026 dexpace and Omar Aljarrah + * + * Licensed under the MIT License. See LICENSE in the project root. + * SPDX-License-Identifier: MIT + */ + +// Convention plugin for every module that is published to Maven Central. It carries the +// `maven-publish` + `signing` setup, the shared POM metadata, the staging repository, and the +// CI-gated signing configuration that was previously copied verbatim into all nine module +// build scripts. +// +// A module opts in with `plugins { id("dexpace.published-module") }`. The publication name, +// coordinates, POM, repository, and signing behaviour are then identical across modules; the +// `name`/`description` fields derive from `project.name`, so a module needs no further +// publishing configuration. A module that must NOT be published simply does not apply this +// plugin. + +plugins { + `maven-publish` + signing +} + +// Coordinates (`group`/`version`) are not set here. Gradle applies them from the repository-root +// `gradle.properties` to the root project and every subproject, so each consuming module already +// carries the shared `org.dexpace` coordinates and current version by the time this plugin runs — +// a coordinate bump is a one-line edit in that file. + +// The `library` publication is built from the `java` software component, which only exists once a +// `java`/`java-library`/`kotlin("jvm")` plugin is applied. Every current consumer applies +// `kotlin("jvm")`, but this plugin neither applies nor requires one, so the whole publication + +// signing setup is guarded on the Kotlin JVM plugin. Without the guard, a module that opted in +// without a Java/Kotlin plugin would fail with an opaque "SoftwareComponent with name java not +// found". +pluginManager.withPlugin("org.jetbrains.kotlin.jvm") { + publishing { + publications { + create("library") { + from(components["java"]) + pom { + name.set(project.name) + description.set("Dexpace Java SDK — ${project.name}") + url.set("https://github.com/dexpace/java-sdk") + licenses { + license { + name.set("MIT License") + url.set("https://github.com/dexpace/java-sdk/blob/main/LICENSE") + distribution.set("repo") + } + } + developers { + developer { + id.set("dexpace") + name.set("Dexpace SDK Team") + } + } + scm { + connection.set("scm:git:https://github.com/dexpace/java-sdk.git") + developerConnection.set("scm:git:ssh://github.com/dexpace/java-sdk.git") + url.set("https://github.com/dexpace/java-sdk") + } + } + } + } + repositories { + // Local staging repository. CI must override this to publish to a real remote. + maven { + name = "local" + url = uri(rootProject.layout.buildDirectory.dir("staging-repo")) + } + } + } + + signing { + isRequired = (System.getenv("CI") == "true") + val signingKey = project.findProperty("signing.key") as String? ?: System.getenv("SIGNING_KEY") + val signingPassword = + project.findProperty("signing.password") as String? ?: System.getenv("SIGNING_PASSWORD") + if (!signingKey.isNullOrBlank() && !signingPassword.isNullOrBlank()) { + useInMemoryPgpKeys(signingKey, signingPassword) + } + sign(publishing.publications["library"]) + } +} diff --git a/build.gradle.kts b/build.gradle.kts index 23501757..47875389 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -38,8 +38,8 @@ plugins { alias(libs.plugins.detekt) } -group = "org.dexpace" -version = "0.0.1-alpha.1" +// `group` and `version` are set once in `gradle.properties` and applied by Gradle to the root +// project and every subproject — see that file. // Coverage: aggregate every Kover-enabled subproject through this root project's reports. dependencies { diff --git a/gradle.properties b/gradle.properties index a7df876c..0a58dcd9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,3 +4,11 @@ kotlin.code.style=official # (org.gradle.configuration-cache is intentionally left out and tracked separately.) org.gradle.caching=true org.gradle.parallel=true + +# Project coordinates. Gradle applies `group` and `version` from gradle.properties to every +# project in this build, so the root and all published modules share one source of truth — no +# per-module or per-script literal. A coordinate bump is a one-line edit here. (The `build-logic` +# included build is a separate build with its own scope and does not read these; it needs no +# coordinates of its own.) +group=org.dexpace +version=0.0.1-alpha.1 diff --git a/sdk-async-coroutines/build.gradle.kts b/sdk-async-coroutines/build.gradle.kts index b7c1a41b..c09591f9 100644 --- a/sdk-async-coroutines/build.gradle.kts +++ b/sdk-async-coroutines/build.gradle.kts @@ -8,13 +8,11 @@ plugins { kotlin("jvm") id("org.jetbrains.kotlinx.kover") - `maven-publish` - signing + // Publishing, signing, POM metadata, and coordinates come from this convention plugin + // (build-logic/src/main/kotlin/dexpace.published-module.gradle.kts). + id("dexpace.published-module") } -group = "org.dexpace" -version = "0.0.1-alpha.1" - // Java 8 bytecode is inherited from the root build script — the module ships to JDK 8 consumers // just like `sdk-core` does. @@ -40,50 +38,3 @@ dependencies { tasks.test { useJUnitPlatform() } - -publishing { - publications { - create("library") { - from(components["java"]) - pom { - name.set(project.name) - description.set("Dexpace Java SDK — ${project.name}") - url.set("https://github.com/dexpace/java-sdk") - licenses { - license { - name.set("MIT License") - url.set("https://github.com/dexpace/java-sdk/blob/main/LICENSE") - distribution.set("repo") - } - } - developers { - developer { - id.set("dexpace") - name.set("Dexpace SDK Team") - } - } - scm { - connection.set("scm:git:https://github.com/dexpace/java-sdk.git") - developerConnection.set("scm:git:ssh://github.com/dexpace/java-sdk.git") - url.set("https://github.com/dexpace/java-sdk") - } - } - } - } - repositories { - maven { - name = "local" - url = uri(rootProject.layout.buildDirectory.dir("staging-repo")) - } - } -} - -signing { - isRequired = (System.getenv("CI") == "true") - val signingKey = project.findProperty("signing.key") as String? ?: System.getenv("SIGNING_KEY") - val signingPassword = project.findProperty("signing.password") as String? ?: System.getenv("SIGNING_PASSWORD") - if (!signingKey.isNullOrBlank() && !signingPassword.isNullOrBlank()) { - useInMemoryPgpKeys(signingKey, signingPassword) - } - sign(publishing.publications["library"]) -} diff --git a/sdk-async-netty/build.gradle.kts b/sdk-async-netty/build.gradle.kts index 86e1aa45..9db1ca97 100644 --- a/sdk-async-netty/build.gradle.kts +++ b/sdk-async-netty/build.gradle.kts @@ -8,13 +8,11 @@ plugins { kotlin("jvm") id("org.jetbrains.kotlinx.kover") - `maven-publish` - signing + // Publishing, signing, POM metadata, and coordinates come from this convention plugin + // (build-logic/src/main/kotlin/dexpace.published-module.gradle.kts). + id("dexpace.published-module") } -group = "org.dexpace" -version = "0.0.1-alpha.1" - dependencies { implementation(project(":sdk-core")) // `netty-common` carries `io.netty.util.concurrent.Future`/`Promise`/`EventExecutor` — @@ -30,50 +28,3 @@ dependencies { tasks.test { useJUnitPlatform() } - -publishing { - publications { - create("library") { - from(components["java"]) - pom { - name.set(project.name) - description.set("Dexpace Java SDK — ${project.name}") - url.set("https://github.com/dexpace/java-sdk") - licenses { - license { - name.set("MIT License") - url.set("https://github.com/dexpace/java-sdk/blob/main/LICENSE") - distribution.set("repo") - } - } - developers { - developer { - id.set("dexpace") - name.set("Dexpace SDK Team") - } - } - scm { - connection.set("scm:git:https://github.com/dexpace/java-sdk.git") - developerConnection.set("scm:git:ssh://github.com/dexpace/java-sdk.git") - url.set("https://github.com/dexpace/java-sdk") - } - } - } - } - repositories { - maven { - name = "local" - url = uri(rootProject.layout.buildDirectory.dir("staging-repo")) - } - } -} - -signing { - isRequired = (System.getenv("CI") == "true") - val signingKey = project.findProperty("signing.key") as String? ?: System.getenv("SIGNING_KEY") - val signingPassword = project.findProperty("signing.password") as String? ?: System.getenv("SIGNING_PASSWORD") - if (!signingKey.isNullOrBlank() && !signingPassword.isNullOrBlank()) { - useInMemoryPgpKeys(signingKey, signingPassword) - } - sign(publishing.publications["library"]) -} diff --git a/sdk-async-reactor/build.gradle.kts b/sdk-async-reactor/build.gradle.kts index e5425b83..671019c1 100644 --- a/sdk-async-reactor/build.gradle.kts +++ b/sdk-async-reactor/build.gradle.kts @@ -8,13 +8,11 @@ plugins { kotlin("jvm") id("org.jetbrains.kotlinx.kover") - `maven-publish` - signing + // Publishing, signing, POM metadata, and coordinates come from this convention plugin + // (build-logic/src/main/kotlin/dexpace.published-module.gradle.kts). + id("dexpace.published-module") } -group = "org.dexpace" -version = "0.0.1-alpha.1" - dependencies { implementation(project(":sdk-core")) // Reactor itself is Java 8 compatible and ships with `Mono.fromFuture(...)` / `Mono.toFuture()` @@ -33,50 +31,3 @@ dependencies { tasks.test { useJUnitPlatform() } - -publishing { - publications { - create("library") { - from(components["java"]) - pom { - name.set(project.name) - description.set("Dexpace Java SDK — ${project.name}") - url.set("https://github.com/dexpace/java-sdk") - licenses { - license { - name.set("MIT License") - url.set("https://github.com/dexpace/java-sdk/blob/main/LICENSE") - distribution.set("repo") - } - } - developers { - developer { - id.set("dexpace") - name.set("Dexpace SDK Team") - } - } - scm { - connection.set("scm:git:https://github.com/dexpace/java-sdk.git") - developerConnection.set("scm:git:ssh://github.com/dexpace/java-sdk.git") - url.set("https://github.com/dexpace/java-sdk") - } - } - } - } - repositories { - maven { - name = "local" - url = uri(rootProject.layout.buildDirectory.dir("staging-repo")) - } - } -} - -signing { - isRequired = (System.getenv("CI") == "true") - val signingKey = project.findProperty("signing.key") as String? ?: System.getenv("SIGNING_KEY") - val signingPassword = project.findProperty("signing.password") as String? ?: System.getenv("SIGNING_PASSWORD") - if (!signingKey.isNullOrBlank() && !signingPassword.isNullOrBlank()) { - useInMemoryPgpKeys(signingKey, signingPassword) - } - sign(publishing.publications["library"]) -} diff --git a/sdk-async-virtualthreads/build.gradle.kts b/sdk-async-virtualthreads/build.gradle.kts index 5813c12c..9c0603d4 100644 --- a/sdk-async-virtualthreads/build.gradle.kts +++ b/sdk-async-virtualthreads/build.gradle.kts @@ -11,13 +11,11 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("jvm") id("org.jetbrains.kotlinx.kover") - `maven-publish` - signing + // Publishing, signing, POM metadata, and coordinates come from this convention plugin + // (build-logic/src/main/kotlin/dexpace.published-module.gradle.kts). + id("dexpace.published-module") } -group = "org.dexpace" -version = "0.0.1-alpha.1" - // Virtual threads require JDK 21+. The root build script applies Java 8 to every Kotlin // module; we override here. The output bytecode targets Java 21 — consumers MUST be on // JDK 21 or newer to depend on this module. Both Kotlin and Java compile tasks must agree @@ -63,53 +61,6 @@ tasks.test { useJUnitPlatform() } -publishing { - publications { - create("library") { - from(components["java"]) - pom { - name.set(project.name) - description.set("Dexpace Java SDK — ${project.name}") - url.set("https://github.com/dexpace/java-sdk") - licenses { - license { - name.set("MIT License") - url.set("https://github.com/dexpace/java-sdk/blob/main/LICENSE") - distribution.set("repo") - } - } - developers { - developer { - id.set("dexpace") - name.set("Dexpace SDK Team") - } - } - scm { - connection.set("scm:git:https://github.com/dexpace/java-sdk.git") - developerConnection.set("scm:git:ssh://github.com/dexpace/java-sdk.git") - url.set("https://github.com/dexpace/java-sdk") - } - } - } - } - repositories { - maven { - name = "local" - url = uri(rootProject.layout.buildDirectory.dir("staging-repo")) - } - } -} - -signing { - isRequired = (System.getenv("CI") == "true") - val signingKey = project.findProperty("signing.key") as String? ?: System.getenv("SIGNING_KEY") - val signingPassword = project.findProperty("signing.password") as String? ?: System.getenv("SIGNING_PASSWORD") - if (!signingKey.isNullOrBlank() && !signingPassword.isNullOrBlank()) { - useInMemoryPgpKeys(signingKey, signingPassword) - } - sign(publishing.publications["library"]) -} - // Detekt analysis is disabled on this module because detekt 1.23.x (incl. 1.23.6 and 1.23.8) // embeds a Kotlin compiler whose `org.jetbrains.kotlin.com.intellij.util.lang.JavaVersion.parse` // throws `IllegalArgumentException: 25.0.2` when running on JDK 25+ — the system JDK on this diff --git a/sdk-core/build.gradle.kts b/sdk-core/build.gradle.kts index 8c79e655..e837484c 100644 --- a/sdk-core/build.gradle.kts +++ b/sdk-core/build.gradle.kts @@ -9,13 +9,11 @@ plugins { kotlin("jvm") `java-test-fixtures` id("org.jetbrains.kotlinx.kover") - `maven-publish` - signing + // Publishing, signing, POM metadata, and coordinates come from this convention plugin + // (build-logic/src/main/kotlin/dexpace.published-module.gradle.kts). + id("dexpace.published-module") } -group = "org.dexpace" -version = "0.0.1-alpha.1" - // repositories and shared compileOnly/implementation deps come from the root build.gradle.kts. dependencies { @@ -40,51 +38,3 @@ dependencies { tasks.test { useJUnitPlatform() } - -publishing { - publications { - create("library") { - from(components["java"]) - pom { - name.set(project.name) - description.set("Dexpace Java SDK — ${project.name}") - url.set("https://github.com/dexpace/java-sdk") - licenses { - license { - name.set("MIT License") - url.set("https://github.com/dexpace/java-sdk/blob/main/LICENSE") - distribution.set("repo") - } - } - developers { - developer { - id.set("dexpace") - name.set("Dexpace SDK Team") - } - } - scm { - connection.set("scm:git:https://github.com/dexpace/java-sdk.git") - developerConnection.set("scm:git:ssh://github.com/dexpace/java-sdk.git") - url.set("https://github.com/dexpace/java-sdk") - } - } - } - } - repositories { - // Local staging repository. CI must override this to publish to a real remote. - maven { - name = "local" - url = uri(rootProject.layout.buildDirectory.dir("staging-repo")) - } - } -} - -signing { - isRequired = (System.getenv("CI") == "true") - val signingKey = project.findProperty("signing.key") as String? ?: System.getenv("SIGNING_KEY") - val signingPassword = project.findProperty("signing.password") as String? ?: System.getenv("SIGNING_PASSWORD") - if (!signingKey.isNullOrBlank() && !signingPassword.isNullOrBlank()) { - useInMemoryPgpKeys(signingKey, signingPassword) - } - sign(publishing.publications["library"]) -} diff --git a/sdk-io-okio3/build.gradle.kts b/sdk-io-okio3/build.gradle.kts index 8e33c6b7..957a1ab4 100644 --- a/sdk-io-okio3/build.gradle.kts +++ b/sdk-io-okio3/build.gradle.kts @@ -8,13 +8,11 @@ plugins { kotlin("jvm") id("org.jetbrains.kotlinx.kover") - `maven-publish` - signing + // Publishing, signing, POM metadata, and coordinates come from this convention plugin + // (build-logic/src/main/kotlin/dexpace.published-module.gradle.kts). + id("dexpace.published-module") } -group = "org.dexpace" -version = "0.0.1-alpha.1" - // repositories come from the root build.gradle.kts. // jvmToolchain(8) is inherited from the root via plugins.withId("org.jetbrains.kotlin.jvm"). // We intentionally do NOT override it here: a higher toolchain would let our code reference @@ -32,50 +30,3 @@ dependencies { tasks.test { useJUnitPlatform() } - -publishing { - publications { - create("library") { - from(components["java"]) - pom { - name.set(project.name) - description.set("Dexpace Java SDK — ${project.name}") - url.set("https://github.com/dexpace/java-sdk") - licenses { - license { - name.set("MIT License") - url.set("https://github.com/dexpace/java-sdk/blob/main/LICENSE") - distribution.set("repo") - } - } - developers { - developer { - id.set("dexpace") - name.set("Dexpace SDK Team") - } - } - scm { - connection.set("scm:git:https://github.com/dexpace/java-sdk.git") - developerConnection.set("scm:git:ssh://github.com/dexpace/java-sdk.git") - url.set("https://github.com/dexpace/java-sdk") - } - } - } - } - repositories { - maven { - name = "local" - url = uri(rootProject.layout.buildDirectory.dir("staging-repo")) - } - } -} - -signing { - isRequired = (System.getenv("CI") == "true") - val signingKey = project.findProperty("signing.key") as String? ?: System.getenv("SIGNING_KEY") - val signingPassword = project.findProperty("signing.password") as String? ?: System.getenv("SIGNING_PASSWORD") - if (!signingKey.isNullOrBlank() && !signingPassword.isNullOrBlank()) { - useInMemoryPgpKeys(signingKey, signingPassword) - } - sign(publishing.publications["library"]) -} diff --git a/sdk-serde-jackson/build.gradle.kts b/sdk-serde-jackson/build.gradle.kts index 9d328e27..d805d6de 100644 --- a/sdk-serde-jackson/build.gradle.kts +++ b/sdk-serde-jackson/build.gradle.kts @@ -8,13 +8,11 @@ plugins { kotlin("jvm") id("org.jetbrains.kotlinx.kover") - `maven-publish` - signing + // Publishing, signing, POM metadata, and coordinates come from this convention plugin + // (build-logic/src/main/kotlin/dexpace.published-module.gradle.kts). + id("dexpace.published-module") } -group = "org.dexpace" -version = "0.0.1-alpha.1" - // Java 8 bytecode is inherited from the root build script — jvmToolchain(8) and // jvmTarget=1.8 apply via plugins.withId("org.jetbrains.kotlin.jvm"). Jackson 2.18.x runs // on JDK 8+, so no toolchain override is required. @@ -36,50 +34,3 @@ dependencies { tasks.test { useJUnitPlatform() } - -publishing { - publications { - create("library") { - from(components["java"]) - pom { - name.set(project.name) - description.set("Dexpace Java SDK — ${project.name}") - url.set("https://github.com/dexpace/java-sdk") - licenses { - license { - name.set("MIT License") - url.set("https://github.com/dexpace/java-sdk/blob/main/LICENSE") - distribution.set("repo") - } - } - developers { - developer { - id.set("dexpace") - name.set("Dexpace SDK Team") - } - } - scm { - connection.set("scm:git:https://github.com/dexpace/java-sdk.git") - developerConnection.set("scm:git:ssh://github.com/dexpace/java-sdk.git") - url.set("https://github.com/dexpace/java-sdk") - } - } - } - } - repositories { - maven { - name = "local" - url = uri(rootProject.layout.buildDirectory.dir("staging-repo")) - } - } -} - -signing { - isRequired = (System.getenv("CI") == "true") - val signingKey = project.findProperty("signing.key") as String? ?: System.getenv("SIGNING_KEY") - val signingPassword = project.findProperty("signing.password") as String? ?: System.getenv("SIGNING_PASSWORD") - if (!signingKey.isNullOrBlank() && !signingPassword.isNullOrBlank()) { - useInMemoryPgpKeys(signingKey, signingPassword) - } - sign(publishing.publications["library"]) -} diff --git a/sdk-transport-jdkhttp/build.gradle.kts b/sdk-transport-jdkhttp/build.gradle.kts index f57173e7..f632e693 100644 --- a/sdk-transport-jdkhttp/build.gradle.kts +++ b/sdk-transport-jdkhttp/build.gradle.kts @@ -11,13 +11,11 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("jvm") id("org.jetbrains.kotlinx.kover") - `maven-publish` - signing + // Publishing, signing, POM metadata, and coordinates come from this convention plugin + // (build-logic/src/main/kotlin/dexpace.published-module.gradle.kts). + id("dexpace.published-module") } -group = "org.dexpace" -version = "0.0.1-alpha.1" - // `java.net.http.HttpClient` was finalised in JEP 321 / Java 11. The root build script // applies Java 8 to every Kotlin module; we override here. The output bytecode targets // Java 11 — consumers MUST be on JDK 11 or newer to depend on this module. Both Kotlin @@ -64,53 +62,6 @@ tasks.test { useJUnitPlatform() } -publishing { - publications { - create("library") { - from(components["java"]) - pom { - name.set(project.name) - description.set("Dexpace Java SDK — ${project.name}") - url.set("https://github.com/dexpace/java-sdk") - licenses { - license { - name.set("MIT License") - url.set("https://github.com/dexpace/java-sdk/blob/main/LICENSE") - distribution.set("repo") - } - } - developers { - developer { - id.set("dexpace") - name.set("Dexpace SDK Team") - } - } - scm { - connection.set("scm:git:https://github.com/dexpace/java-sdk.git") - developerConnection.set("scm:git:ssh://github.com/dexpace/java-sdk.git") - url.set("https://github.com/dexpace/java-sdk") - } - } - } - } - repositories { - maven { - name = "local" - url = uri(rootProject.layout.buildDirectory.dir("staging-repo")) - } - } -} - -signing { - isRequired = (System.getenv("CI") == "true") - val signingKey = project.findProperty("signing.key") as String? ?: System.getenv("SIGNING_KEY") - val signingPassword = project.findProperty("signing.password") as String? ?: System.getenv("SIGNING_PASSWORD") - if (!signingKey.isNullOrBlank() && !signingPassword.isNullOrBlank()) { - useInMemoryPgpKeys(signingKey, signingPassword) - } - sign(publishing.publications["library"]) -} - // Detekt analysis is disabled on this module because detekt 1.23.x (incl. 1.23.6 and 1.23.8) // embeds a Kotlin compiler whose `org.jetbrains.kotlin.com.intellij.util.lang.JavaVersion.parse` // throws `IllegalArgumentException: 25.0.2` when running on JDK 25+ — the system JDK on this diff --git a/sdk-transport-okhttp/build.gradle.kts b/sdk-transport-okhttp/build.gradle.kts index a89a4198..9acb3d07 100644 --- a/sdk-transport-okhttp/build.gradle.kts +++ b/sdk-transport-okhttp/build.gradle.kts @@ -8,13 +8,11 @@ plugins { kotlin("jvm") id("org.jetbrains.kotlinx.kover") - `maven-publish` - signing + // Publishing, signing, POM metadata, and coordinates come from this convention plugin + // (build-logic/src/main/kotlin/dexpace.published-module.gradle.kts). + id("dexpace.published-module") } -group = "org.dexpace" -version = "0.0.1-alpha.1" - // Java 8 bytecode is inherited from the root build script — this transport ships to JDK 8 // consumers just like `sdk-core` does. OkHttp 5.x itself supports JDK 8+ at runtime. // @@ -38,53 +36,6 @@ tasks.test { useJUnitPlatform() } -publishing { - publications { - create("library") { - from(components["java"]) - pom { - name.set(project.name) - description.set("Dexpace Java SDK — ${project.name}") - url.set("https://github.com/dexpace/java-sdk") - licenses { - license { - name.set("MIT License") - url.set("https://github.com/dexpace/java-sdk/blob/main/LICENSE") - distribution.set("repo") - } - } - developers { - developer { - id.set("dexpace") - name.set("Dexpace SDK Team") - } - } - scm { - connection.set("scm:git:https://github.com/dexpace/java-sdk.git") - developerConnection.set("scm:git:ssh://github.com/dexpace/java-sdk.git") - url.set("https://github.com/dexpace/java-sdk") - } - } - } - } - repositories { - maven { - name = "local" - url = uri(rootProject.layout.buildDirectory.dir("staging-repo")) - } - } -} - -signing { - isRequired = (System.getenv("CI") == "true") - val signingKey = project.findProperty("signing.key") as String? ?: System.getenv("SIGNING_KEY") - val signingPassword = project.findProperty("signing.password") as String? ?: System.getenv("SIGNING_PASSWORD") - if (!signingKey.isNullOrBlank() && !signingPassword.isNullOrBlank()) { - useInMemoryPgpKeys(signingKey, signingPassword) - } - sign(publishing.publications["library"]) -} - // Detekt runs normally on this module. It uses the JDK-8 toolchain, so it is unaffected by // the detekt 1.23.x `JavaVersion.parse` crash on non-8 toolchains (JDK 25+) that forces the // gate off on `sdk-transport-jdkhttp` (11) and `sdk-async-virtualthreads` (21) — see those diff --git a/settings.gradle.kts b/settings.gradle.kts index 1416c2a6..0aaf6f09 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,6 +5,13 @@ * SPDX-License-Identifier: MIT */ +pluginManagement { + // `build-logic` is an included build that compiles this repository's convention plugins. + // Putting `includeBuild` here (rather than at the top level) lets modules apply those + // plugins by id from their own `plugins {}` block — e.g. `id("dexpace.published-module")`. + includeBuild("build-logic") +} + plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" }