From 72ce3053367bca5712944191ad2c66abd2b59832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Wed, 11 Mar 2026 21:07:03 +0100 Subject: [PATCH 1/9] feat: add CD pipeline for Maven Central Portal publishing Configure vanniktech maven-publish plugin with Central Portal, GPG signing, and GitHub Actions workflow triggered on version tags. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/cd.yml | 32 ++++++++++++++++++++++++++++++++ build.gradle.kts | 5 +++-- core/build.gradle.kts | 36 ++++++++++++++++++++++++++++++------ 3 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/cd.yml diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 00000000..1d7f63b5 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,32 @@ +name: CD + +on: + push: + tags: + - 'v*' + +permissions: + contents: read + +jobs: + publish: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 21 + + - uses: gradle/actions/setup-gradle@v4 + + - name: Publish to Maven Central + env: + RELEASE_VERSION: ${{ github.ref_name }} + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.GPG_SIGNING_KEY }} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.GPG_SIGNING_PASSWORD }} + run: ./gradlew publishAndReleaseToMavenCentral diff --git a/build.gradle.kts b/build.gradle.kts index a55997f7..3d32fc28 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,11 +1,12 @@ plugins { kotlin("jvm") version "2.3.0" apply false id("org.jlleitschuh.gradle.ktlint") version "12.1.2" apply false + id("com.vanniktech.maven.publish") version "0.30.0" apply false } allprojects { - group = "com.avsystem" - version = "0.0.1" + group = "com.avsystem.justworks" + version = System.getenv("RELEASE_VERSION")?.removePrefix("v") ?: "0.0.1-SNAPSHOT" repositories { mavenCentral() diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 1dbfccca..834fd957 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -2,7 +2,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("jvm") - `maven-publish` + id("com.vanniktech.maven.publish") id("org.jetbrains.kotlinx.kover") version "0.9.1" } @@ -15,7 +15,6 @@ ktlint { version.set("1.8.0") } - dependencies { implementation("io.swagger.parser.v3:swagger-parser:2.1.39") implementation("com.squareup:kotlinpoet:2.2.0") @@ -28,10 +27,35 @@ tasks.test { useJUnitPlatform() } -publishing { - publications { - create("maven") { - from(components["java"]) +mavenPublishing { + publishToMavenCentral(com.vanniktech.maven.publish.SonatypeHost.CENTRAL_PORTAL) + signAllPublications() + + pom { + name.set("justworks-core") + description.set("Kotlin OpenAPI 3.0 client code generator with Ktor and kotlinx.serialization") + url.set("https://github.com/AVSystem/justworks") + + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + + developers { + developer { + id.set("avsystem") + name.set("AVSystem") + organization.set("AVSystem") + organizationUrl.set("https://www.avsystem.com") + } + } + + scm { + connection.set("scm:git:git://github.com/AVSystem/justworks.git") + developerConnection.set("scm:git:ssh://github.com/AVSystem/justworks.git") + url.set("https://github.com/AVSystem/justworks") } } } From 9b507708f2dce9d6838aff484386334e496a2d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Thu, 19 Mar 2026 13:42:09 +0100 Subject: [PATCH 2/9] refactor: streamline Gradle build script and update developer metadata - Replaced redundant property setters with assignment syntax. - Updated Maven Central configuration and developer information in `pom`. - Simplified ktlint version and compiler arguments setup. --- core/build.gradle.kts | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 834fd957..83edecff 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,3 +1,4 @@ +import com.vanniktech.maven.publish.SonatypeHost.Companion.CENTRAL_PORTAL import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -12,7 +13,7 @@ kotlin { // todo: remove when https://github.com/JLLeitschuh/ktlint-gradle/issues/912 resolved ktlint { - version.set("1.8.0") + version = ("1.8.0") } dependencies { @@ -28,34 +29,35 @@ tasks.test { } mavenPublishing { - publishToMavenCentral(com.vanniktech.maven.publish.SonatypeHost.CENTRAL_PORTAL) + publishToMavenCentral(CENTRAL_PORTAL) signAllPublications() pom { - name.set("justworks-core") - description.set("Kotlin OpenAPI 3.0 client code generator with Ktor and kotlinx.serialization") - url.set("https://github.com/AVSystem/justworks") + name = "justworks-core" + description = "Kotlin OpenAPI 3.0 client code generator with Ktor and kotlinx.serialization" + url = "https://github.com/AVSystem/justworks" licenses { license { - name.set("The Apache License, Version 2.0") - url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" } } developers { developer { - id.set("avsystem") - name.set("AVSystem") - organization.set("AVSystem") - organizationUrl.set("https://www.avsystem.com") + id = "halotukozak" + name = "Bartłomiej Kozak" + email = "bartlomiejkozak@proton.me" + organization = "AVSystem" + organizationUrl = "https://www.avsystem.com" } } scm { - connection.set("scm:git:git://github.com/AVSystem/justworks.git") - developerConnection.set("scm:git:ssh://github.com/AVSystem/justworks.git") - url.set("https://github.com/AVSystem/justworks") + connection = "scm:git:git://github.com/AVSystem/justworks.git" + developerConnection = "scm:git:ssh://github.com/AVSystem/justworks.git" + url = "https://github.com/AVSystem/justworks" } } } From 73575abbab723bc8b9127b7e1df586dcad839b2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Thu, 19 Mar 2026 13:54:21 +0100 Subject: [PATCH 3/9] update developer email in pom configuration --- core/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 83edecff..e323dcc2 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -48,7 +48,7 @@ mavenPublishing { developer { id = "halotukozak" name = "Bartłomiej Kozak" - email = "bartlomiejkozak@proton.me" + email = "b.kozak@avsystem.com" organization = "AVSystem" organizationUrl = "https://www.avsystem.com" } From e28de9e8d0d6f4d6bd88aa52d743f7be7b0035d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Thu, 19 Mar 2026 13:59:29 +0100 Subject: [PATCH 4/9] feat: integrate vanniktech maven-publish plugin and configure centralized Maven publishing - Added Maven publish configuration for all subprojects with shared metadata. - Simplified and unified POM setup, including URLs, licenses, SCM info, and developer details. - Removed individual Maven configurations from subprojects. --- build.gradle.kts | 46 +++++++++++++++++++++++++++++++++++++++++ core/build.gradle.kts | 29 +------------------------- plugin/build.gradle.kts | 14 ++++++++++++- 3 files changed, 60 insertions(+), 29 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3d32fc28..2f212820 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,6 @@ +import com.vanniktech.maven.publish.MavenPublishBaseExtension +import com.vanniktech.maven.publish.SonatypeHost.Companion.CENTRAL_PORTAL + plugins { kotlin("jvm") version "2.3.0" apply false id("org.jlleitschuh.gradle.ktlint") version "12.1.2" apply false @@ -14,3 +17,46 @@ allprojects { apply(plugin = "org.jlleitschuh.gradle.ktlint") } + +subprojects { + pluginManager.withPlugin("com.vanniktech.maven.publish") { + extensions.configure { + publishToMavenCentral(CENTRAL_PORTAL) + signAllPublications() + + pom { + url = "https://github.com/AVSystem/justworks" + + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + + developers { + developer { + id = "halotukozak" + name = "Bartłomiej Kozak" + email = "b.kozak@avsystem.com" + organization = "AVSystem" + organizationUrl = "https://www.avsystem.com" + } + developer { + id = "mzielu" + name = "Marcin Zieliński" + email = "m.zielinski@avsystem.com" + organization = "AVSystem" + organizationUrl = "https://www.avsystem.com" + } + } + + scm { + connection = "scm:git:git://github.com/AVSystem/justworks.git" + developerConnection = "scm:git:ssh://github.com/AVSystem/justworks.git" + url = "https://github.com/AVSystem/justworks" + } + } + } + } +} diff --git a/core/build.gradle.kts b/core/build.gradle.kts index e323dcc2..a51847d9 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,4 +1,3 @@ -import com.vanniktech.maven.publish.SonatypeHost.Companion.CENTRAL_PORTAL import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -29,38 +28,12 @@ tasks.test { } mavenPublishing { - publishToMavenCentral(CENTRAL_PORTAL) - signAllPublications() - pom { name = "justworks-core" description = "Kotlin OpenAPI 3.0 client code generator with Ktor and kotlinx.serialization" - url = "https://github.com/AVSystem/justworks" - - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - - developers { - developer { - id = "halotukozak" - name = "Bartłomiej Kozak" - email = "b.kozak@avsystem.com" - organization = "AVSystem" - organizationUrl = "https://www.avsystem.com" - } - } - - scm { - connection = "scm:git:git://github.com/AVSystem/justworks.git" - developerConnection = "scm:git:ssh://github.com/AVSystem/justworks.git" - url = "https://github.com/AVSystem/justworks" - } } } + tasks.withType().configureEach { compilerOptions { freeCompilerArgs.add("-Xcontext-parameters") diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index 4826a9a4..6d87a40a 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -1,7 +1,10 @@ +import com.vanniktech.maven.publish.GradlePlugin +import com.vanniktech.maven.publish.JavadocJar + plugins { kotlin("jvm") `java-gradle-plugin` - `maven-publish` + id("com.vanniktech.maven.publish") id("org.jetbrains.kotlinx.kover") version "0.9.1" } @@ -23,6 +26,15 @@ gradlePlugin { } } +mavenPublishing { + configure(GradlePlugin(javadocJar = JavadocJar.Empty())) + + pom { + name = "justworks-plugin" + description = "Gradle plugin for generating Kotlin Ktor client code from OpenAPI 3.0 specifications" + } +} + // Functional test source set val functionalTest by sourceSets.creating { compileClasspath += sourceSets["main"].output From 37b97ac47f076e0b4244e10e814cc97319b6c114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Thu, 19 Mar 2026 14:20:11 +0100 Subject: [PATCH 5/9] refactor: move Maven publishing config to plugin module only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Core module no longer publishes to Maven Central — only the Gradle plugin is distributed. All POM metadata now lives in plugin/build.gradle.kts. Co-Authored-By: Claude Opus 4.6 (1M context) --- build.gradle.kts | 46 ----------------------------------------- core/build.gradle.kts | 7 ------- plugin/build.gradle.kts | 34 ++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 53 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 2f212820..3d32fc28 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,3 @@ -import com.vanniktech.maven.publish.MavenPublishBaseExtension -import com.vanniktech.maven.publish.SonatypeHost.Companion.CENTRAL_PORTAL - plugins { kotlin("jvm") version "2.3.0" apply false id("org.jlleitschuh.gradle.ktlint") version "12.1.2" apply false @@ -17,46 +14,3 @@ allprojects { apply(plugin = "org.jlleitschuh.gradle.ktlint") } - -subprojects { - pluginManager.withPlugin("com.vanniktech.maven.publish") { - extensions.configure { - publishToMavenCentral(CENTRAL_PORTAL) - signAllPublications() - - pom { - url = "https://github.com/AVSystem/justworks" - - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - - developers { - developer { - id = "halotukozak" - name = "Bartłomiej Kozak" - email = "b.kozak@avsystem.com" - organization = "AVSystem" - organizationUrl = "https://www.avsystem.com" - } - developer { - id = "mzielu" - name = "Marcin Zieliński" - email = "m.zielinski@avsystem.com" - organization = "AVSystem" - organizationUrl = "https://www.avsystem.com" - } - } - - scm { - connection = "scm:git:git://github.com/AVSystem/justworks.git" - developerConnection = "scm:git:ssh://github.com/AVSystem/justworks.git" - url = "https://github.com/AVSystem/justworks" - } - } - } - } -} diff --git a/core/build.gradle.kts b/core/build.gradle.kts index a51847d9..f66ac142 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -2,7 +2,6 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("jvm") - id("com.vanniktech.maven.publish") id("org.jetbrains.kotlinx.kover") version "0.9.1" } @@ -27,12 +26,6 @@ tasks.test { useJUnitPlatform() } -mavenPublishing { - pom { - name = "justworks-core" - description = "Kotlin OpenAPI 3.0 client code generator with Ktor and kotlinx.serialization" - } -} tasks.withType().configureEach { compilerOptions { diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index 6d87a40a..7b2aa8ff 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -1,5 +1,6 @@ import com.vanniktech.maven.publish.GradlePlugin import com.vanniktech.maven.publish.JavadocJar +import com.vanniktech.maven.publish.SonatypeHost.Companion.CENTRAL_PORTAL plugins { kotlin("jvm") @@ -28,10 +29,43 @@ gradlePlugin { mavenPublishing { configure(GradlePlugin(javadocJar = JavadocJar.Empty())) + publishToMavenCentral(CENTRAL_PORTAL) + signAllPublications() pom { name = "justworks-plugin" description = "Gradle plugin for generating Kotlin Ktor client code from OpenAPI 3.0 specifications" + url = "https://github.com/AVSystem/justworks" + + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + + developers { + developer { + id = "halotukozak" + name = "Bartłomiej Kozak" + email = "b.kozak@avsystem.com" + organization = "AVSystem" + organizationUrl = "https://www.avsystem.com" + } + developer { + id = "mzielu" + name = "Marcin Zieliński" + email = "m.zielinski@avsystem.com" + organization = "AVSystem" + organizationUrl = "https://www.avsystem.com" + } + } + + scm { + connection = "scm:git:git://github.com/AVSystem/justworks.git" + developerConnection = "scm:git:ssh://github.com/AVSystem/justworks.git" + url = "https://github.com/AVSystem/justworks" + } } } From f654f05105b01d1315cb8205ea48f00f7dcea00c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Thu, 19 Mar 2026 14:45:17 +0100 Subject: [PATCH 6/9] chore: centralize Maven publishing configuration in root project - Applied shared Maven publishing setup to all subprojects. - Consolidated POM metadata including licenses, SCM details, and developer info in the root `build.gradle.kts`. - Removed duplicated Maven configurations across subprojects. --- build.gradle.kts | 46 +++++++++++++++++++++++++++++++++++++++++ core/build.gradle.kts | 10 ++++++++- plugin/build.gradle.kts | 34 ------------------------------ 3 files changed, 55 insertions(+), 35 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3d32fc28..9e726005 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,6 @@ +import com.vanniktech.maven.publish.MavenPublishBaseExtension +import com.vanniktech.maven.publish.SonatypeHost + plugins { kotlin("jvm") version "2.3.0" apply false id("org.jlleitschuh.gradle.ktlint") version "12.1.2" apply false @@ -14,3 +17,46 @@ allprojects { apply(plugin = "org.jlleitschuh.gradle.ktlint") } + +subprojects { + pluginManager.withPlugin("com.vanniktech.maven.publish") { + extensions.configure { + publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) + signAllPublications() + + pom { + url = "https://github.com/AVSystem/justworks" + + licenses { + license { + name = "The Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + + developers { + developer { + id = "halotukozak" + name = "Bartłomiej Kozak" + email = "b.kozak@avsystem.com" + organization = "AVSystem" + organizationUrl = "https://www.avsystem.com" + } + developer { + id = "mzielu" + name = "Marcin Zieliński" + email = "m.zielinski@avsystem.com" + organization = "AVSystem" + organizationUrl = "https://www.avsystem.com" + } + } + + scm { + connection = "scm:git:git://github.com/AVSystem/justworks.git" + developerConnection = "scm:git:ssh://github.com/AVSystem/justworks.git" + url = "https://github.com/AVSystem/justworks" + } + } + } + } +} diff --git a/core/build.gradle.kts b/core/build.gradle.kts index f66ac142..0e8a691d 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -3,6 +3,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("jvm") id("org.jetbrains.kotlinx.kover") version "0.9.1" + id("com.vanniktech.maven.publish") } kotlin { @@ -11,7 +12,14 @@ kotlin { // todo: remove when https://github.com/JLLeitschuh/ktlint-gradle/issues/912 resolved ktlint { - version = ("1.8.0") + version = "1.8.0" +} + +mavenPublishing { + pom { + name = "justworks-core" + description = "OpenAPI 3.0 parser and Kotlin Ktor client code generator" + } } dependencies { diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index 7b2aa8ff..6d87a40a 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -1,6 +1,5 @@ import com.vanniktech.maven.publish.GradlePlugin import com.vanniktech.maven.publish.JavadocJar -import com.vanniktech.maven.publish.SonatypeHost.Companion.CENTRAL_PORTAL plugins { kotlin("jvm") @@ -29,43 +28,10 @@ gradlePlugin { mavenPublishing { configure(GradlePlugin(javadocJar = JavadocJar.Empty())) - publishToMavenCentral(CENTRAL_PORTAL) - signAllPublications() pom { name = "justworks-plugin" description = "Gradle plugin for generating Kotlin Ktor client code from OpenAPI 3.0 specifications" - url = "https://github.com/AVSystem/justworks" - - licenses { - license { - name = "The Apache License, Version 2.0" - url = "https://www.apache.org/licenses/LICENSE-2.0.txt" - } - } - - developers { - developer { - id = "halotukozak" - name = "Bartłomiej Kozak" - email = "b.kozak@avsystem.com" - organization = "AVSystem" - organizationUrl = "https://www.avsystem.com" - } - developer { - id = "mzielu" - name = "Marcin Zieliński" - email = "m.zielinski@avsystem.com" - organization = "AVSystem" - organizationUrl = "https://www.avsystem.com" - } - } - - scm { - connection = "scm:git:git://github.com/AVSystem/justworks.git" - developerConnection = "scm:git:ssh://github.com/AVSystem/justworks.git" - url = "https://github.com/AVSystem/justworks" - } } } From d8c8da22faa2ff3581ba65ddef15a836df630eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Fri, 20 Mar 2026 12:38:32 +0100 Subject: [PATCH 7/9] fix: address PR review feedback from ddworak - Add CI dependency to CD workflow to prevent publishing broken artifacts - Add --no-configuration-cache to publish command - Validate release tag with semver regex instead of naive v-prefix strip - Centralize kover plugin version in root build.gradle.kts for consistency Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/cd.yml | 9 ++++++++- build.gradle.kts | 6 +++++- core/build.gradle.kts | 2 +- plugin/build.gradle.kts | 2 +- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 1d7f63b5..711209d0 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -9,7 +9,14 @@ permissions: contents: read jobs: + ci: + uses: ./.github/workflows/ci.yml + permissions: + contents: read + pull-requests: write + publish: + needs: ci runs-on: ubuntu-latest steps: @@ -29,4 +36,4 @@ jobs: ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.GPG_SIGNING_KEY }} ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.GPG_SIGNING_PASSWORD }} - run: ./gradlew publishAndReleaseToMavenCentral + run: ./gradlew publishAndReleaseToMavenCentral --no-configuration-cache diff --git a/build.gradle.kts b/build.gradle.kts index 9e726005..2e9bcb6e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,12 +4,16 @@ import com.vanniktech.maven.publish.SonatypeHost plugins { kotlin("jvm") version "2.3.0" apply false id("org.jlleitschuh.gradle.ktlint") version "12.1.2" apply false + id("org.jetbrains.kotlinx.kover") version "0.9.1" apply false id("com.vanniktech.maven.publish") version "0.30.0" apply false } allprojects { group = "com.avsystem.justworks" - version = System.getenv("RELEASE_VERSION")?.removePrefix("v") ?: "0.0.1-SNAPSHOT" + version = System + .getenv("RELEASE_VERSION") + ?.let { Regex("""^v(\d+\.\d+\.\d+.*)$""").matchEntire(it)?.groupValues?.get(1) } + ?: "0.0.1-SNAPSHOT" repositories { mavenCentral() diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 0e8a691d..1990a3bc 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -2,7 +2,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("jvm") - id("org.jetbrains.kotlinx.kover") version "0.9.1" + id("org.jetbrains.kotlinx.kover") id("com.vanniktech.maven.publish") } diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index 6d87a40a..6119aac0 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -5,7 +5,7 @@ plugins { kotlin("jvm") `java-gradle-plugin` id("com.vanniktech.maven.publish") - id("org.jetbrains.kotlinx.kover") version "0.9.1" + id("org.jetbrains.kotlinx.kover") } kotlin { From 17d8c3c309447ebff4f31580266f3720c9b5a856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Fri, 20 Mar 2026 13:20:47 +0100 Subject: [PATCH 8/9] docs: add comprehensive README for Gradle plugin usage --- README.md | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/README.md b/README.md index 3a764e6c..bf3e9446 100644 --- a/README.md +++ b/README.md @@ -1 +1,92 @@ # justworks + +A Gradle plugin that generates type-safe Kotlin [Ktor](https://ktor.io/) client code from OpenAPI 3.0 specifications. + +## Installation + +Add the plugin to your `build.gradle.kts`: + +```kotlin +plugins { + id("com.avsystem.justworks") version "" +} +``` + +The plugin and core library are published to Maven Central: + +- `com.avsystem.justworks:plugin` -- Gradle plugin +- `com.avsystem.justworks:core` -- OpenAPI parser and code generator + +## Usage + +Configure one or more OpenAPI specs in the `justworks` extension: + +```kotlin +justworks { + specs { + register("petstore") { + specFile = file("api/petstore.yaml") + packageName = "com.example.petstore" + } + register("payments") { + specFile = file("api/payments.yaml") + packageName = "com.example.payments" + // Optional: override default sub-packages + apiPackage = "com.example.payments.client" + modelPackage = "com.example.payments.dto" + } + } +} +``` + +Each spec gets its own Gradle task (`justworksGenerate`) and output directory. Run all generators at once with: + +```bash +./gradlew justworksGenerateAll +``` + +Generated sources are automatically wired into Kotlin source sets, so `compileKotlin` depends on code generation -- no extra configuration needed. + +### Configuration options + +| Property | Required | Default | Description | +|----------------|----------|--------------------------|--------------------------------------| +| `specFile` | Yes | -- | Path to the OpenAPI spec (.yaml/.json) | +| `packageName` | Yes | -- | Base package for generated code | +| `apiPackage` | No | `$packageName.api` | Package for API client classes | +| `modelPackage` | No | `$packageName.model` | Package for model/data classes | + +## Publishing + +Releases are published to [Maven Central](https://central.sonatype.com/) automatically when a version tag (`v*`) is pushed. The CD pipeline runs CI checks first, then publishes signed artifacts via the [vanniktech maven-publish](https://github.com/vanniktech/gradle-maven-publish-plugin) plugin. + +To trigger a release: + +```bash +git tag v1.0.0 +git push origin v1.0.0 +``` + +The version is derived from the tag (stripping the `v` prefix). Without a tag, the version defaults to `0.0.1-SNAPSHOT`. + +## Development + +Requires **JDK 21+**. + +```bash +# Run tests and linting +./gradlew check + +# Run only unit tests +./gradlew test + +# Run functional tests (plugin module) +./gradlew plugin:functionalTest + +# Lint check +./gradlew ktlintCheck +``` + +## License + +Apache License 2.0 From 6035a194a70a0189a85cabac4be210a69e408e61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kozak?= Date: Fri, 20 Mar 2026 15:26:02 +0100 Subject: [PATCH 9/9] fix: add tag validation and CI gate to CD workflow - Add validate-tag job that fails fast on non-semver tags - Make publish depend on both CI and tag validation - Add workflow_call trigger to ci.yml for reusable workflow support Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/cd.yml | 13 ++++++++++++- .github/workflows/ci.yml | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 711209d0..9dec65f6 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -15,8 +15,19 @@ jobs: contents: read pull-requests: write + validate-tag: + runs-on: ubuntu-latest + steps: + - name: Validate semver tag + run: | + TAG="${GITHUB_REF_NAME}" + if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(.*)$ ]]; then + echo "::error::Tag '$TAG' does not match semver format (expected v..)" + exit 1 + fi + publish: - needs: ci + needs: [ ci, validate-tag ] runs-on: ubuntu-latest steps: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 01895a10..68bcbe61 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,7 @@ on: branches: [ master ] pull_request: branches: [ master ] + workflow_call: permissions: contents: read