Adding a New Module
Optional integration modules follow a consistent pattern established by fun-jackson and fun-assertj.
This page is a checklist for maintainers adding a new module.
When to create a module
Create a new module when the integration requires an optional peer dependency that users may or may not
have on their classpath. The core lib module must never depend on it.
Examples of appropriate modules: fun-spring, fun-micronaut, fun-quarkus, fun-reactor.
Checklist
1. Create the Gradle subproject
Create the directory and build.gradle:
plugins { id 'dmx-fun.java-module'}
dependencies { api project(':lib') compileOnly libs.spring.context // optional peer dependency testImplementation libs.spring.context // or property-driven version}
mavenPublishing { coordinates("codes.domix", "fun-spring", "${project.version}")
pom { name = 'dmx-fun Spring integration' description = 'Optional Spring module for dmx-fun: ...' }}Key rules:
- Always apply
dmx-fun.java-module— this pulls in the convention plugin, the Maven publishing configuration, the signing setup, and the JSpecify dependency. - Declare the peer dependency as
compileOnlyso users bring their own version. - Drive the test dependency version via a Gradle property (e.g.
-PspringVersion=6.1.0) to enable CI matrix testing, falling back to the version catalog entry.
2. Register in settings.gradle
include('fun-spring')3. Add to the root build.gradle aggregation
The root build.gradle aggregates test reports and Javadoc. Add the new module to both:
dependencies { testReportAggregation project(':fun-spring') jacocoAggregation project(':fun-spring')}And add its source directory to the aggregateJavadoc task’s --module-source-path arguments.
4. Expand CI path triggers
Four workflow files reference module paths — update all of them:
| Workflow | Where to add |
|---|---|
.github/workflows/gradle.yml | paths: block (push) and dorny/paths-filter filters |
.github/workflows/publish.yml | paths: block |
.github/workflows/publish-snapshot.yml | paths: block |
5. Add a compatibility matrix workflow
If the module has an optional peer dependency, create .github/workflows/{module}-compatibility.yaml
following the pattern of jackson-compatibility.yaml:
- Trigger: PR touching
{module}/**or the workflow file - Matrix: one entry per supported version of the peer dependency
- Run:
./gradlew :{module}:test -P{module}Version={version}
6. Write a README.md in the module root
Cover: what the module does, Maven/Gradle coordinates, usage snippet, version compatibility table.
See jackson/README.md or assertj/README.md for the expected format.
7. Add a guide page
Create site/src/data/guide/{module-name}.mdx following the established guide style:
ordershould be the next available integer after the last module guide- Externalize all code snippets into
site/src/data/code/guide/{module-name}/ - Include a version compatibility table matching the CI matrix
8. Register in the guide index
Add a card to the modules array in site/src/pages/guide/index.astro:
{ name: 'Spring integration', href: `${base}guide/fun-spring`, summary: 'Spring-aware adapters for dmx-fun types.', whenToUse: 'You are using Spring and want native dmx-fun support.', avoidWhen: 'You are not using Spring — the module is optional.', tag: 'Spring',},Naming conventions
| Artifact | Pattern | Example |
|---|---|---|
| Directory | {integration-name} | fun-spring |
artifactId | fun-{integration-name} | fun-spring |
POM name | dmx-fun {Integration} integration | dmx-fun Spring integration |
| Java module name | dmx.fun.{integration} | dmx.fun.spring |
| Base package | dmx.fun.{integration} | dmx.fun.spring |
| Guide slug | {integration-name} | /guide/fun-spring |