CI/CD Pipelines
All CI/CD is handled by GitHub Actions. The workflows live in .github/workflows/.
Workflow overview
| Workflow file | Trigger | Purpose |
|---|---|---|
gradle.yml | push / PR to main (code paths) | Full build, tests, coverage, Javadoc, dependency graph submission |
publish.yml | push to main — stable version only | Publish all modules to Maven Central, create git tag and GitHub Release |
publish-snapshot.yml | push to main — SNAPSHOT version only | Publish SNAPSHOT artifacts to Maven Central |
jackson-compatibility.yaml | PR touching jackson/** | Matrix test against Jackson 2.13.x – 2.21.x |
assertj-compatibility.yaml | PR touching assertj/** | Matrix test against AssertJ 3.21.x – 3.27.x |
spring-boot-compatibility.yaml | PR touching spring-boot/** or spring/** | Matrix test of fun-spring-boot against Spring Boot 3.3.x – 4.0.x |
spring-boot-sample-compatibility.yaml | PR touching spring-boot-sample/** or spring/** | Matrix test of the Spring Boot sample app against Boot 3.4.x – 4.0.x |
pages.yml | push to main | Build and deploy the documentation site to GitHub Pages |
gradle.yml — Main CI build
Triggers: push to main on tracked paths, or any PR to main.
Uses dorny/paths-filter on PRs to skip the build entirely when no relevant file changed
(e.g. a documentation-only commit).
What it does:
- Compiles all modules
- Runs all tests and uploads the aggregated JaCoCo coverage report to the PR
- Generates aggregated Javadoc
- Submits the dependency graph to GitHub for Dependabot
Local equivalent:
./gradlew buildSecrets required: none.
publish.yml — Stable release
Triggers: push to main when any of lib/**, jackson/**, assertj/**, gradle/**,
gradle.properties, gradlew, gradlew.bat, or the workflow file itself changes.
Gotcha: the workflow reads version from gradle.properties at runtime.
If the version ends with -SNAPSHOT, all subsequent steps are skipped — the workflow exits early.
Only stable versions (e.g. 0.1.0) proceed.
What it does:
- Reads the version from
gradle.properties - Checks whether the git tag
v{version}already exists — skips if it does (idempotent) - Runs all tests (
./gradlew test) - Publishes all modules to Maven Central (
./gradlew publishToMavenCentral --no-configuration-cache) - Creates and pushes the git tag
v{version} - Creates a GitHub Release with auto-generated release notes
Secrets required:
| Secret | Purpose |
|---|---|
MAVEN_CENTRAL_USERNAME | Maven Central portal username |
MAVEN_CENTRAL_PASSWORD | Maven Central portal password / token |
SIGNING_KEY_ID | GPG key ID (last 8 characters) |
SIGNING_KEY | GPG private key (armored, base64-encoded) |
SIGNING_KEY_PASSWORD | Passphrase for the GPG key |
Local equivalent (dry-run only — do not publish locally):
./gradlew publishToMavenCentral --no-configuration-cache --dry-runpublish-snapshot.yml — SNAPSHOT publish
Triggers: same paths as publish.yml.
Gotcha: mirror of publish.yml — only proceeds when the version ends with -SNAPSHOT.
Stable versions cause all steps to be skipped.
What it does:
- Reads the version; skips if not a SNAPSHOT
- Runs all tests
- Publishes to Maven Central’s snapshot repository via
./gradlew publishToMavenCentral
Secrets required: same five secrets as publish.yml.
jackson-compatibility.yaml — Jackson matrix
Triggers: PR where at least one changed file matches jackson/** or the workflow file itself.
Runs only on pull requests — not on push to main.
What it does: runs :jackson:test for each Jackson version in the matrix:
| Jackson version | Status |
|---|---|
| 2.13.5 | tested |
| 2.14.3 | tested |
| 2.15.4 | tested |
| 2.16.2 | tested |
| 2.17.3 | tested |
| 2.18.2 | tested |
| 2.19.4 | tested |
| 2.20.2 | tested |
| 2.21.2 | tested |
Local equivalent:
./gradlew :jackson:test -PjacksonVersion=2.17.3Secrets required: none.
assertj-compatibility.yaml — AssertJ matrix
Triggers: PR where at least one changed file matches assertj/** or the workflow file itself.
Runs only on pull requests — not on push to main.
What it does: runs :assertj:test for each AssertJ version in the matrix:
| AssertJ version | Status |
|---|---|
| 3.21.0 | tested |
| 3.22.0 | tested |
| 3.23.1 | tested |
| 3.24.2 | tested |
| 3.25.3 | tested |
| 3.26.3 | tested |
| 3.27.7 | tested |
Local equivalent:
./gradlew :assertj:test -PassertjVersion=3.25.3Secrets required: none.
spring-boot-compatibility.yaml — Spring Boot matrix
Triggers: PR where at least one changed file matches spring-boot/**, spring/**,
gradle/libs.versions.toml, or the workflow file itself.
Runs only on pull requests — not on push to main.
fun-spring-boot declares Spring Boot as compileOnly, so users bring their own version.
This matrix catches regressions against different Boot release lines before they reach main.
Boot 4.x aligns with Spring Framework 7.x, which is the baseline this project targets.
What it does: runs :spring-boot:test for each Spring Boot version in the matrix:
| Spring Boot version | Status |
|---|---|
| 3.3.13 | tested |
| 3.4.13 | tested |
| 3.5.13 | tested |
| 4.0.6 | tested |
Local equivalent:
./gradlew :spring-boot:test -PspringBootVersion=4.0.6Secrets required: none.
spring-boot-sample-compatibility.yaml — Spring Boot sample matrix
Triggers: PR where at least one changed file matches spring-boot-sample/**,
spring-boot/**, spring/**, gradle/libs.versions.toml, settings.gradle,
or the workflow file itself.
Runs only on pull requests — not on push to main.
Mirrors the matrix used in spring-boot-compatibility.yaml for the Spring Boot versions,
but scoped to Boot 3.4+ only — the sample requires Spring Boot’s Docker Compose support,
which was introduced in 3.1 and stabilised in 3.4. It tests the full end-to-end stack:
controller → service → database via Testcontainers.
What it does: runs :spring-boot-sample:test for each Spring Boot version in the matrix:
| Spring Boot version | Status |
|---|---|
| 3.4.13 | tested |
| 3.5.13 | tested |
| 4.0.6 | tested |
Local equivalent:
./gradlew :spring-boot-sample:test -PspringBootVersion=3.4.13Secrets required: none.
pages.yml — Documentation site deploy
Triggers: push to main (no path filter — any push rebuilds the site).
What it does:
- Runs
./gradlew aggregateJavadocto generate the API reference - Copies the Javadoc output into
site/public/javadoc/ - Runs
pnpm run buildinsidesite/ - Deploys the
dist/directory to GitHub Pages
Secrets required: none (uses GITHUB_TOKEN with pages: write permission).
Local equivalent:
./gradlew aggregateJavadoccd site && pnpm run build# open dist/ in a local static server