Skip to content
Open
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
9 changes: 8 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,20 @@ jobs:
# pluginManagement version and none of its configuration applies —
# wrong tag name, no autoVersionSubmodules, and release:perform would
# deploy unsigned artifacts that Central rejects.
#
# -Dskip.npm=false is forced for the same reason the profiles are explicit. The MCP
# dashboard assets are build output and are no longer tracked in git, so a release
# that skipped the frontend would publish a jar without the dashboard. release:perform
# builds in its own target/checkout, where a workflow-level path check cannot gate the
# deploy, so pin the property here and let the enforcer rule in
# springdoc-openapi-starter-common-mcp fail the build if the assets are still missing.
- name: Release
run: |
mvn $MAVEN_ARGS -Pci,gpg release:prepare release:perform \
-DreleaseVersion='${{ inputs.releaseVersion }}' \
-DdevelopmentVersion='${{ inputs.developmentVersion }}' \
-DdryRun=${{ inputs.dryRun }} \
-Darguments="-DskipTests"
-Darguments="-DskipTests -Dskip.npm=false"
env:
MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_TOKEN }}
Expand Down
29 changes: 26 additions & 3 deletions CONTRIBUTING.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ If you don't have an IDE preference we would recommend that you use IntellIJ.

=== Importing into IntelliJ IDEA

If you have performed a checkout of this repository already, use "`File`" -> "`Open`" and then select the root `build.gradle` file to import the code.
If you have performed a checkout of this repository already, use "`File`" -> "`Open`" and then select the root `pom.xml` file to import the code.

Alternatively, you can let IntellIJ IDEA checkout the code for you.
Use "`File`" ->
Expand Down Expand Up @@ -118,15 +118,38 @@ Projects can be imported without the plugins, your code changes just won't be au

=== Building from Source

springdoc-openapi source can be built from the command line using https://maven.apache.org/[Maven] on JDK 1.8 or above.
springdoc-openapi source can be built from the command line using https://maven.apache.org/[Maven] on JDK 21 or above.

The project can be built from the root directory using the standard maven command:

[indent=0]
----
$ ./mvn install
$ mvn install
----

==== The MCP dashboard frontend

`springdoc-openapi-starter-common-mcp` ships a React dashboard. The build runs `npm install` and
`vite build` for it through the
https://github.com/eirslett/frontend-maven-plugin[frontend-maven-plugin], which downloads the Node
version pinned by the `node.version` property in the root `pom.xml`. No local Node installation is
required.

The dashboard is build output: it is generated straight into the module's output directory
(`springdoc-openapi-starter-common-mcp/target/classes/mcp-ui`), it is not tracked by git, and
`mvn clean` removes it. The module excludes `mcp-ui/**` from `src/main/resources`, so a copy left
there by a standalone `npm run build` is never packaged.

Passing `-Dskip.npm=true` skips the frontend step and leaves the build directory alone. That means
whatever is already in `target/classes/mcp-ui` — possibly from an earlier build, and possibly older
than the current frontend sources — is packaged as-is, and a `mvn clean` build packages no dashboard
at all. In the latter case, with `springdoc.ai.mcp.dashboard-enabled=true`, the dashboard path serves
HTTP 404 for the UI, while `/api/mcp-admin/**` is unaffected.

The release and snapshot builds always build the frontend (`-Pci`, and `-Dskip.npm=false` forced by
the release workflow), so published artifacts always carry a dashboard built from the sources they
were tagged from.

== Cloning the git repository on Windows

Some files in the git repository may exceed the Windows maximum file path (260 characters), depending on where you clone the repository.
Expand Down
3 changes: 2 additions & 1 deletion springdoc-openapi-starter-common-mcp/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,5 @@ Desktop.ini
######################
# MCP Dashboard
######################
src/main/frontend/node_modules/
src/main/frontend/node_modules/
src/main/resources/mcp-ui/
57 changes: 57 additions & 0 deletions springdoc-openapi-starter-common-mcp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,34 @@
<fileset>
<directory>src/main/frontend/node_modules</directory>
</fileset>
<!-- Build output that older revisions of this module wrote into the source
tree. Nothing generates it any more, but a stale copy left in a working
copy should not survive a clean. -->
<fileset>
<directory>src/main/resources/mcp-ui</directory>
</fileset>
</filesets>
</configuration>
</plugin>
<!-- The dashboard assets are written by the frontend build straight into
${project.build.outputDirectory}/mcp-ui, which mvn clean removes. Exclude any
copy sitting in the source tree, so a leftover from an earlier build (or from a
standalone npm run build) can never be packaged in place of freshly built
assets. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>default-resources</id>
<configuration>
<excludes>
<exclude>mcp-ui/**</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
Expand Down Expand Up @@ -88,6 +113,38 @@
</goals>
<configuration>
<arguments>run build</arguments>
<environmentVariables>
<MCP_UI_OUT_DIR>${project.build.outputDirectory}/mcp-ui</MCP_UI_OUT_DIR>
</environmentVariables>
</configuration>
</execution>
</executions>
</plugin>
<!-- The dashboard assets are generated by the frontend plugin above and are not
tracked by git, so a build that skips the frontend step would silently package
a jar without the UI. Fail such a build instead of shipping it. This runs from
the project itself, so it also covers release:perform, which builds in its own
target/checkout where a workflow-level path check would not apply. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>require-mcp-dashboard-assets</id>
<phase>process-classes</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<skip>${skip.npm}</skip>
<rules>
<requireFilesExist>
<message>The MCP dashboard assets are missing from ${project.build.outputDirectory}/mcp-ui, so the packaged jar would ship without the UI. They are generated by frontend-maven-plugin; build without -Dskip.npm=true.</message>
<files>
<file>${project.build.outputDirectory}/mcp-ui/index.html</file>
</files>
</requireFilesExist>
</rules>
</configuration>
</execution>
</executions>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ export default defineConfig({
},
},
build: {
outDir: '../resources/mcp-ui',
// The Maven build points this at the module output directory (target/classes/mcp-ui) so
// that the generated dashboard lives under target/, where mvn clean removes it. A
// standalone build keeps writing next to the sources; those copies are not tracked, and
// the module excludes them from the jar, which only ever packages what Maven produced.
outDir: process.env.MCP_UI_OUT_DIR ?? '../resources/mcp-ui',
emptyOutDir: true,
},
server: {
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Loading