Skip to content

Repository files navigation

xemantic-conventions

Gradle plugin setting up standard conventions for Xemantic's projects

Maven Central Version GitHub Release Date license

GitHub Actions Workflow Status GitHub branch check runs GitHub commits since latest release GitHub last commit

GitHub contributors GitHub commit activity GitHub code size in bytes GitHub Created At kotlin version discord users online Bluesky

Why?

Setting up a gradle project for a Kotlin multiplatform library can be hassle. There are so many repetitive pieces of configuration which are easy to mismanage and omit. There are also special workarounds required to publish such libraries to maven central. This plugin is attempting to centralize all of that.

Features

  • JAR Manifest Configuration: Populates the Implementation-Title, Implementation-Version, Implementation-Vendor and Implementation-Vendor-Id manifest attributes from the project metadata, and bundles the project's LICENSE file into META-INF
  • AI-Friendly Test Logging: Test failures are logged in a structured, machine-readable format optimized for processing by coding AI agents (like Claude Code). Only failures and skipped tests are logged, each failure with its message, captured standard output and full stack trace, which reduces noise and makes CI/CD output easily digestible by both humans and AI tools.
  • Version Management: The updateVersionsAfterRelease task rewrites the released version in README.md and sets the version in gradle.properties to the next snapshot
  • JReleaser Integration: Announces releases on Discord, LinkedIn and Bluesky - the release itself is published by the maven-publish plugin, JReleaser is used for announcements only

Usage

To you lib.versions.toml (located in the gradle dir) add:

[versions]

# your other versions ...
xemanticConventionsPlugin = "0.7.0"

[libraries]
# your libraries ...

[plugins]
# your other plugins ...
xemantic-conventions = { id = "com.xemantic.gradle.xemantic-conventions", version.ref = "xemanticConventionsPlugin" }

Then, in your build.gradle.kts, you can specify:

plugins {
    alias(libs.plugins.kotlin.multiplatform) // or jvm
    alias(libs.plugins.kotlin.plugin.power.assert) // optional
    alias(libs.plugins.kotlinx.binary.compatibility.validator) // optional
    alias(libs.plugins.dokka)
    alias(libs.plugins.version.catalog.update) // optional
    alias(libs.plugins.maven.publish) // com.vanniktech.maven.publish, provides the publishToMavenCentral task
    alias(libs.plugins.jreleaser)
    alias(libs.plugins.xemantic.conventions)
}

xemantic {
    description = "What this project is about"
    inceptionYear = "2025"
    applyAllConventions()
}

In a multimodule build apply the plugin to the root project only. The conventions reach the subprojects on their own, and jreleaserAnnounce waits for the publishToMavenCentral task of every module that has one, so no aggregate task has to be declared by hand.

Dependency versions are not this plugin's concern - the version-catalog-update plugin already provides pin, keep and versionSelector idioms, so configure it directly in the project which needs it.

Test configuration

The current test reporting is configured for AI-friendly output, in particular when used together with xemantic-kotlin-test library, so that an autonomous AI agent can perform TDD in a feedback loop, with maximal information and minimal noise, preventing context rot.

Example error report when running gradle build in JVM:

> Task :jvmTest FAILED
<test-failure test="com.xemantic.kotlin.test.ProjectDocumentationTest.foo equals bar()" platform="jvm">
<message>
assert("foo" == "bar")
             |
             false
</message>
<stacktrace>
  at app//org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:38)
  at app//org.junit.jupiter.api.Assertions.fail(Assertions.java:138)
  at app//kotlin.test.junit5.JUnit5Asserter.fail(JUnitSupport.kt:56)
  at app//kotlin.test.Asserter.assertTrue(Assertions.kt:694)
  at app//kotlin.test.junit5.JUnit5Asserter.assertTrue(JUnitSupport.kt:30)
  at app//kotlin.test.Asserter.assertTrue(Assertions.kt:704)
  at app//kotlin.test.junit5.JUnit5Asserter.assertTrue(JUnitSupport.kt:30)
  at app//com.xemantic.kotlin.test.AssertionsKt.assert(Assertions.kt:32)
  at app//com.xemantic.kotlin.test.ProjectDocumentationTest.foo equals bar(ProjectDocumentationTest.kt:25)
  at java.base@24.0.2/java.lang.reflect.Method.invoke(Method.java:565)
  at java.base@24.0.2/java.util.ArrayList.forEach(ArrayList.java:1604)
  at java.base@24.0.2/java.util.ArrayList.forEach(ArrayList.java:1604)
</stacktrace>
</test-failure>
ProjectDocumentationTest[jvm] > foo equals bar()[jvm] FAILED

About

Gradle plugin setting up standard conventions for Xemantic's projects

Resources

Code of conduct

Contributing

Stars

3 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages