Skip to content

Add springdoc-openapi Gradle + Maven generator plugins - #85

Open
vpelikh wants to merge 2 commits into
mainfrom
feature/openapi-gradle-plugin
Open

Add springdoc-openapi Gradle + Maven generator plugins#85
vpelikh wants to merge 2 commits into
mainfrom
feature/openapi-gradle-plugin

Conversation

@vpelikh

@vpelikh vpelikh commented Aug 26, 2026

Copy link
Copy Markdown
Owner

Summary

Adds two build-time generator plugins that produce an OpenAPI document for a Spring Boot application without leaving a web server running. Both plugins share a single forked-JVM worker (springdoc-openapi-generator-worker) that boots the application context, lets springdoc-openapi build the spec, writes it to disk, and shuts the context down.

  • Gradle pluginio.github.vpelikh.springdoc-openapi-gradle-plugin
    • Gradle TestKit functional tests against a WebFlux app, a WebMvc app, a skip flag, and YAML output (4 tests).
  • Maven pluginspringdoc-openapi-maven-plugin
    • End-to-end maven-invoker-plugin integration tests (generate, generate-webmvc, generate-yaml, generate-skip, generate-jpa).
  • Shared workerspringdoc-openapi-generator-worker
    • Boots a reactive context with a no-op ReactiveWebServerFactory (fully serverless) or a servlet context on an ephemeral port, writes the spec, then exits.

The Gradle plugin is wired into CI (build + tests) and configured for publishing.


Changes

New modules

  • springdoc-openapi-generator-worker/ — shared forked-JVM worker used by both plugins. Detects the target app's stack from its classpath and dispatches to a WebFlux or WebMvc generator.
  • springdoc-openapi-gradle-plugin/ — Gradle plugin (generateOpenApi task).
  • springdoc-openapi-maven-plugin/ — Maven Mojo (springdoc:generate-openapi).

CI / publishing (Gradle plugin)

  • .github/workflows/build.yml — adds Setup Gradle and an extended Build with Maven and Gradle step that builds and tests the Gradle plugin after the Maven install (which populates mavenLocal with the SNAPSHOT artifacts the functional tests resolve).
  • .github/workflows/release.yml — adds Setup Gradle and a Publish Gradle plugin step that runs ./gradlew publishPlugins with GRADLE_PUBLISH_KEY / GRADLE_PUBLISH_SECRET.
  • springdoc-openapi-gradle-plugin/build.gradlejava-gradle-plugin + com.gradle.plugin-publish + maven-publish; plugin id, website/vcsUrl, displayName, description, and tags configured.
  • springdoc-openapi-gradle-plugin/gradle.properties — the plugin version, kept in sync with the Maven release via CI/prepare-release-commit.sh and CI/bump-snapshot.sh.

Version lifecycle

  • CI/prepare-release-commit.sh — also sets springdoc-openapi-gradle-plugin/gradle.properties.
  • CI/bump-snapshot.sh — also bumps the Gradle plugin version after a final release.

Design notes

  • No per-stack config on the plugin side. The worker infers WebFlux vs WebMvc from the target app's classpath, so a single task/java handles both stacks.
  • No fixed port is used. WebFlux never binds a port; WebMvc uses an ephemeral port (0) and shuts down immediately after writing the spec.
  • WebFlux is genuinely serverless (no-op ReactiveWebServerFactory); WebMvc starts a real, short-lived container because the servlet model requires a ServletContext.
  • The plugin intentionally does not force a springdoc stack API onto the fork classpath; the target app's runtime classpath already provides the stack it needs. This keeps the fork classpath identical in shape to the Maven Mojo.

Testing

  • Gradle plugin: ./gradlew :springdoc-openapi-gradle-plugin:build
    • 4 Gradle TestKit functional tests pass (WebFlux, WebMvc, skip, YAML).
  • Maven plugin: ./mvnw install (runs the maven-invoker-plugin ITs).
  • CI: build.yml runs the full Maven build followed by the Gradle plugin build/test on Java 17 and 25.

Notes / follow-ups

  • The Gradle plugin publishes under the fork namespace io.github.vpelikh.springdoc-openapi-gradle-plugin (not the upstream org.springdoc, which is not controlled by this fork).
  • Requires GRADLE_PUBLISH_KEY / GRADLE_PUBLISH_SECRET GitHub secrets to be present for the release-time publishPlugins step to succeed.
  • Version is currently 5.0.6-SNAPSHOT and inherits the existing release/bump workflow.

Checklist

  • Branch builds and functional tests pass
  • Gradle plugin build + 4 TestKit tests pass
  • Maven plugin ITs pass (mvnw install)
  • CI workflows updated and validated (actionlint)
  • Gradle plugin publishing configured
  • Draft PR reviewed before marking ready

Generate the OpenAPI JSON/YAML spec from a Spring Boot app without keeping a web
server running, supporting WebFlux (reactive) and WebMvc (servlet).

- springdoc-openapi-generator-worker: shared thin worker whose entry point
  GeneratorWorkerMain detects the app's web stack from the fork classpath and
  dispatches to GeneratorWorkerWebFlux (REACTIVE, no port bound via a no-op
  ReactiveWebServerFactory) or GeneratorWorkerWebMvc (SERVLET, ephemeral port 0,
  shut down immediately). Writes the JSON/YAML atomically and fails fast on an
  unsupported format.
- springdoc-openapi-gradle-plugin: standalone Gradle plugin exposing
  openApiGenerate { mainClass, outputDir, outputFileName, format, timeoutSeconds,
  systemProperties, skip }. Forks the worker with the Java toolchain's launcher
  and a configurable fork timeout.
- springdoc-openapi-maven-plugin: 'generate' Mojo (springdoc.skip supported)
  that resolves the worker and transitive deps via Aether and forks it against
  the project's runtime classpath.
- systemProperties escape hatch for infra-dependent apps (e.g. JPA/Hibernate)
  via a generation-time profile/overrides.
- The Gradle fork classpath carries only the worker jar (matching the Maven
  Mojo) so a WebMvc app's servlet stack detection is never flipped by a
  webflux-api safety-net; the app's own runtime classpath provides its stack.
- Registered worker and plugin in springdoc-openapi-bom; per-module gitignore.
@vpelikh
vpelikh force-pushed the feature/openapi-gradle-plugin branch from c4543af to 061c7d8 Compare August 26, 2026 17:38
@vpelikh
vpelikh force-pushed the feature/openapi-gradle-plugin branch from a20d3b8 to 9398a40 Compare August 26, 2026 18:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant