Embed OpenAPI spec and Swagger UI in main Wave container#1043
Merged
Conversation
Previously the OpenAPI spec was shipped as a separate `wave/openapi` nginx image, built and pushed independently on every `[release]` commit via the typespec.yml workflow. Now the spec is compiled at Gradle build time and bundled into the main Wave app container, served at /openapi/ alongside Swagger UI assets from the swagger-ui webjar. The previously unused HTML/CSS/JS bits are externalised so the strict Wave CSP (no `unsafe-inline`) does not break the docs page. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
It was failing the repo's SHA-pinning policy and provides little value.
pditommaso
added a commit
that referenced
this pull request
May 13, 2026
Previously the release steps used `contains(head_commit.message, '[release]')`, which matched the substring anywhere in the message — subject or body. PR #1043 mentioned `[release]` in its body and triggered a full release/publish/ECR push on merge. Add a `detect-release` step that sets `is_release=true` only when the first line of the head commit message contains `[release]` and is not a squash-merge subject (ending with `(#NNN)`) or merge-commit subject (`Merge pull request #NNN`). All 9 release-gated steps now key off that output. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Until now the Wave OpenAPI spec was shipped as a separate
wave/openapinginx image, built and pushed bytypespec.ymlon every[release]commit. That meant two images to deploy, two lifecycles to keep in sync, and a docs endpoint that lived outside the main Wave service.This PR follows the Sched project pattern: the spec is generated as part of the main Gradle build and served directly from the Wave application container at
/openapi/.What changes
Before / after
wave/openapinginx imagewave/appat/openapi/typespec.ymlworkflow on[release]typespec/index.htmlorg.webjars:swagger-ui:5.17.14Files
Added
src/main/resources/swagger-ui-template.html— Swagger UI page, rendered at build time with${PROJECT_VERSION}.src/main/resources/public/openapi/swagger-ui-init.js— Swagger UI bootstrap (externalised for CSP).src/main/resources/public/openapi/swagger-ui-overrides.css— minor Swagger UI styling (externalised for CSP).Modified
build.gradle— addsswagger-uiwebjar dependency and three new Gradle tasks:installTypeSpec→generateOpenApi→generateSwaggerUI, wired intoprocessResources.src/main/resources/application.yml— adds static-resource mappings for/openapi/**and/webjars/**.src/main/groovy/io/seqera/wave/controller/ServiceInfoController.groovy— drops the@Get("/openapi")redirect (it caused a 301 loop because Micronaut resolves/openapiand/openapi/to the same route)..github/workflows/typespec.yml— keeps TypeSpec validation only; drops AWS/ECR config and the docker build/push step.Deleted
typespec/Dockerfiletypespec/index.htmltypespec/tag-and-push-openapi.shHow it hangs together
The generated
openapi.yamlandindex.html, together with the static CSS/JS, end up underbuild/resources/main/public/openapi/and are bundled into the JIB image. Micronaut serves them via the/openapi/**static-resource mapping; Swagger UI's JS/CSS comes from the swagger-ui webjar at/webjars/swagger-ui/5.17.14/....Note on CSP
Wave's response filter sets a strict
default-src 'self'; style-src 'self' https://fonts.googleapis.com; ...— no'unsafe-inline'. The Swagger UI template therefore loads its init script and overrides from same-origin URLs rather than inline<script>/<style>blocks, so no CSP relaxation was needed.Test plan
./gradlew processResourcesproducesbuild/resources/main/public/openapi/{openapi.yaml,index.html,swagger-ui-init.js,swagger-ui-overrides.css}with the correct version interpolated intoindex.html../run.sh, then visithttp://localhost:9090/openapi/— Swagger UI renders, endpoints list loads,/openapi/openapi.yamlreturns the spec./openapi/.ubuntu-latestships with Node, enough fornpm install+npx tsp compile .).typespec.ymlstill validates TypeSpec changes on PRs.🤖 Generated with Claude Code