Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ out/
bin/
gen/
target/
/gradle.properties
/secret.gpg
/secring.gpg
/.claude/
206 changes: 72 additions & 134 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,165 +1,103 @@
import com.vanniktech.maven.publish.MavenPublishBaseExtension
import com.vanniktech.maven.publish.SonatypeHost
import helpers.configureMavenCentralMetadata
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import kotlin.io.encoding.Base64
import kotlin.io.encoding.ExperimentalEncodingApi

plugins {
kotlin("jvm") version "1.9.21"
kotlin("plugin.serialization") version "1.9.21"
id("org.jetbrains.dokka") version "1.9.10"
id("com.vanniktech.maven.publish") version "0.29.0"
}

group = "io.github.logtide-dev"
version = "0.4.0"

repositories {
mavenCentral()
}

dependencies {
// Kotlin
implementation(kotlin("stdlib"))

// HTTP Client
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("com.squareup.okhttp3:okhttp-sse:4.12.0")

// JSON Serialization
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")

// Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")

// Logging
compileOnly("org.slf4j:slf4j-api:2.0.9")

// Framework integrations
compileOnly("org.springframework.boot:spring-boot-starter-web:3.2.0")
compileOnly("io.ktor:ktor-server-core:2.3.7")
compileOnly("jakarta.servlet:jakarta.servlet-api:6.0.0")

// Testing
testImplementation(kotlin("test"))
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3")
testImplementation("com.squareup.okhttp3:mockwebserver:4.12.0")
testImplementation("io.mockk:mockk:1.13.8")
val kotlinJvmTarget: String by project
val projectGroup: String by project
val projectVersion: String by project

// Logging for tests (required since slf4j-api is compileOnly)
testImplementation("org.slf4j:slf4j-api:2.0.9")
testImplementation("org.slf4j:slf4j-simple:2.0.9")

// Framework testing dependencies
testImplementation("io.ktor:ktor-server-test-host:2.3.7")
testImplementation("io.ktor:ktor-server-content-negotiation:2.3.7")
testImplementation("io.ktor:ktor-serialization-kotlinx-json:2.3.7")
testImplementation("org.springframework:spring-test:6.1.1")
testImplementation("org.springframework:spring-webmvc:6.1.1")
testImplementation("org.springframework.boot:spring-boot-test:3.2.0")
testImplementation("jakarta.servlet:jakarta.servlet-api:6.0.0")
plugins {
alias(libs.plugins.kotlin.jvm) apply false
alias(libs.plugins.maven.publish) apply false
}

tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "17"
subprojects {
if (projectGroup.isBlank() || projectVersion.isBlank()) {
throw GradleException("Project group and version must be defined in gradle.properties")
}
}

tasks.test {
useJUnitPlatform()
}

java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

mavenPublishing {
publishToMavenCentral(com.vanniktech.maven.publish.SonatypeHost.CENTRAL_PORTAL, automaticRelease = true)
signIfKeyPresent(project)

coordinates("io.github.logtide-dev", "logtide-sdk-kotlin", version.toString())

pom {
name.set("LogTide Kotlin SDK")
description.set("Official Kotlin SDK for LogTide - Self-hosted log management with batching, retry logic, circuit breaker, and query API")
url.set("https://github.com/logtide-dev/logtide-sdk-kotlin")

licenses {
license {
name.set("MIT License")
url.set("https://opensource.org/licenses/MIT")
group = projectGroup
version = projectVersion

apply(plugin = "org.jetbrains.kotlin.jvm")
apply(plugin = "com.vanniktech.maven.publish")
apply(plugin = "signing")

pluginManager.withPlugin("com.vanniktech.maven.publish") {
pluginManager.withPlugin("signing") {
extensions.configure<MavenPublishBaseExtension> {
publishToMavenCentral(
SonatypeHost.CENTRAL_PORTAL,
automaticRelease = true
)
signIfKeyPresent(this@subprojects)

pom {
configureMavenCentralMetadata(this@subprojects)
}
}
}
}

developers {
developer {
id.set("polliog")
name.set("Polliog")
email.set("giuseppe@solture.it")
}
developer {
id.set("emanueleiannuzzi")
name.set("Emanuele Iannuzzi")
email.set("hello@emanueleiannuzzi.me")
plugins.withType<JavaPlugin>().configureEach {
extensions.configure<JavaPluginExtension> {
toolchain {
languageVersion.set(JavaLanguageVersion.of(kotlinJvmTarget))
vendor.set(JvmVendorSpec.AMAZON)
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
}
}

scm {
connection.set("scm:git:git://github.com/logtide-dev/logtide-sdk-kotlin.git")
developerConnection.set("scm:git:ssh://github.com/logtide-dev/logtide-sdk-kotlin.git")
url.set("https://github.com/logtide-dev/logtide-sdk-kotlin")
plugins.withId("org.jetbrains.kotlin.jvm") {
extensions.configure<KotlinJvmProjectExtension> {
jvmToolchain(kotlinJvmTarget.toInt())
}
}
}

tasks.register("printVersion") {
doLast {
println(project.version.toString())
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = kotlinJvmTarget
}
}
}

tasks.register("checkVersionTag") {
doLast {
val tag = System.getenv("GITHUB_REF_NAME")
?.removePrefix("v")
?: return@doLast

val versionString = project.version.toString()

if (versionString != tag) {
throw GradleException(
"Version mismatch: project.version=$versionString, tag=$tag"
)
}
tasks.withType<Test> {
useJUnitPlatform()
}
}

tasks["publishAndReleaseToMavenCentral"].dependsOn("checkVersionTag")

@OptIn(ExperimentalEncodingApi::class)
fun MavenPublishBaseExtension.signIfKeyPresent(project: Project) {
val keyId = System.getenv("KEY_ID").also {
if (it == null) {
println("KEY_ID environment variable not set, assuming binary .gpg key.")
}
}
val keyBytes = System.getenv("SECRING")?.let { Base64.decode(it.toByteArray()).decodeToString() }
private fun MavenPublishBaseExtension.signIfKeyPresent(project: Project) {
val keyId = System.getenv("KEY_ID")
val keyBytes = runCatching {
Base64.decode(System.getenv("SECRING").toByteArray()).decodeToString()
}.getOrNull()
val keyPassword = System.getenv("PASSWORD")

if (keyBytes == null || keyPassword == null) {
println("Signing environment variables not set, skipping signing.")
return
if (keyBytes != null && keyPassword != null) {
println("Signing artifacts with in-memory PGP key (.gpg)")
project.extensions.configure<SigningExtension>("signing") {
// For binary .gpg keys
if (keyId == null) {
useInMemoryPgpKeys(keyBytes, keyPassword)
} else {
useInMemoryPgpKeys(keyId, keyBytes, keyPassword)
}
signAllPublications()
}
} else {
println("Skipping signing of artifacts: PGP key or password not found in environment variables")
}
}

project.extensions.configure<SigningExtension>("signing") {
// For binary .gpg keys
if (keyId == null) {
useInMemoryPgpKeys(keyBytes, keyPassword)
} else {
useInMemoryPgpKeys(keyId, keyBytes, keyPassword)
}
signAllPublications()
tasks.register("printVersion") {
doLast {
println(project.version.toString())
}
}
13 changes: 13 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
plugins {
`kotlin-dsl`
}

repositories {
mavenLocal()
mavenCentral()
maven { url = uri("https://packages.confluent.io/maven/") }
}

dependencies {
gradleApi()
}
13 changes: 13 additions & 0 deletions buildSrc/src/main/kotlin/Libs.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.kotlin.dsl.findByType

@PublishedApi
internal inline val Project.libsVersionCatalog
get() = extensions.findByType<VersionCatalogsExtension>()?.named("libs")
?: error("Version catalog 'libs' not found")

@PublishedApi
internal inline val Project.frameworksVersionCatalog
get() = extensions.findByType<VersionCatalogsExtension>()?.named("frameworks")
?: error("Version catalog 'frameworks' not found")
40 changes: 40 additions & 0 deletions buildSrc/src/main/kotlin/helpers/Publishing.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package helpers

import org.gradle.api.Project
import org.gradle.api.provider.Property
import org.gradle.api.publish.maven.MavenPom

private infix fun <T> Property<T>.by(value: T) = set(value)

@Suppress("Unused")
fun MavenPom.configureMavenCentralMetadata(project: Project) {
name by project.name
description by "Official Kotlin SDK for LogTide - Self-hosted log management with batching, retry logic, circuit breaker, and query API"
url by "https://github.com/logtide-dev/logtide-sdk-kotlin"

licenses {
license {
name.set("MIT License")
url.set("https://opensource.org/licenses/MIT")
}
}

developers {
developer {
id by "polliog"
name by "Polliog"
email by "giuseppe@solture.it"
}
developer {
id by "emanueleiannuzzi"
name by "Emanuele Iannuzzi"
email by "hello@emanueleiannuzzi.me"
}
}

scm {
connection by "scm:git:git://github.com/logtide-dev/logtide-sdk-kotlin.git"
developerConnection by "scm:git:ssh://github.com/logtide-dev/logtide-sdk-kotlin.git"
url by "https://github.com/logtide-dev/logtide-sdk-kotlin"
}
}
23 changes: 23 additions & 0 deletions buildSrc/src/main/kotlin/plugins/LogtideConventionPlugin.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package plugins

import libsVersionCatalog
import org.gradle.api.Plugin
import org.gradle.api.Project

class LogtideConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
val libs = libsVersionCatalog
pluginManager.apply(libs.findPlugin("kotlin-jvm").get().get().pluginId)

dependencies.apply {
add("implementation", libs.findBundle("kotlin").get())
add("compileOnly", libs.findBundle("slf4j").get())

add("testImplementation", libs.findBundle("test-slf4j").get())
add("testImplementation", libs.findBundle("test-kotlin").get())
add("testImplementation", libs.findBundle("test-okhttp").get())
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
implementation-class=plugins.LogtideConventionPlugin
10 changes: 10 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Gradle Properties
org.gradle.parallel=false
org.gradle.jvmargs=-Dfile.encoding=UTF-8
org.gradle.configuration.cache=true
org.gradle.caching=true
# Project Properties
projectGroup=io.github.logtide-dev
projectVersion=0.5.0
# Kotlin
kotlinJvmTarget=17
25 changes: 25 additions & 0 deletions gradle/frameworks.versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[versions]
spring-boot = "3.2.0"
ktor = "2.3.7"
jakarta = "6.0.0"

[plugins]

[libraries]
spring-boot-starter-web = { module = "org.springframework.boot:spring-boot-starter-web", version.ref = "spring-boot" }
ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" }
jakarta-servlet-api = { module = "jakarta.servlet:jakarta.servlet-api", version.ref = "jakarta" }

# Test
ktor-server-test-host = { module = "io.ktor:ktor-server-test-host", version.ref = "ktor" }
ktor-server-content-negotiation = { module = "io.ktor:ktor-server-content-negotiation", version.ref = "ktor" }
ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }

spring-test = { module = "org.springframework:spring-test", version = "6.1.1" }
spring-webmvc = { module = "org.springframework:spring-webmvc", version = "6.1.1" }
spring-boot-test = { module = "org.springframework.boot:spring-boot-test", version.ref = "spring-boot" }

[bundles]
test-ktor = ["ktor-server-test-host", "ktor-server-content-negotiation", "ktor-serialization-kotlinx-json"]
test-spring = ["spring-test", "spring-webmvc", "spring-boot-test"]
test-jakarta = ["jakarta-servlet-api"]
Loading