Serve OpenAPI 3.0 spec at /openapi.v1.json#37038
Conversation
|
Can you add more comments and document more details in the tool's code? For example: why it needs |
|
I think we should probably also evaluate using OAS3 for swagger-ui. Long-term I would like us to move completely to a OAS3-based solution, ideally OAS 3.1. |
There was a problem hiding this comment.
Pull request overview
Adds an OpenAPI 3.0 (OAS3) JSON spec endpoint generated at build-time by converting the existing Swagger 2.0 template, so API clients that require OAS3 can generate SDKs directly while keeping the existing Swagger v1 spec.
Changes:
- Serve an OAS3 spec at
/openapi.v1.jsonalongside the existing/swagger.v1.json. - Add a generator (
build/generate-openapi.go) to converttemplates/swagger/v1_json.tmpl→templates/swagger/v1_openapi3_json.tmpl. - Wire generation + consistency checks into
make generate-swagger/ backend checks and add required Go module dependencies.
Reviewed changes
Copilot reviewed 7 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| routers/web/web.go | Registers the new /openapi.v1.json route when Swagger is enabled. |
| routers/web/swagger_json.go | Adds the OpenAPI3Json handler to render the OAS3 JSON template. |
| build/generate-openapi.go | Implements Swagger2→OAS3 conversion and post-processing/enrichment steps. |
| build/openapi3-tools.go | Attempts to pin kin-openapi tool deps for generation. |
| templates/swagger/v1_openapi3_json.tmpl | Generated OAS3 JSON template served by the new route. |
| Makefile | Adds OpenAPI3 generation/check targets and hooks into existing checks. |
| go.mod / go.sum | Adds kin-openapi and related transitive deps. |
| .editorconfig | Adds formatting rules for the generated OAS3 template. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
IMO this should be one step. Displaying spec that's converted from generated one does not feel right to me. It's a step too much in the pipeline and I'd prefer to be closer to what we directly control. I'll try to get back to generating API directly from structs after I'll finish dealing with my package related PRs as I'm tied up there a bit. |
|
BTW I would make it just |
|
what about v4 which is supposedly in works? |
|
No idea about that , but I don't think anyone wants to maintain multiple versions of the api existing at the same time in the same repo, that's more like wishful thinking. |
|
But I guess keep the v1 for consistency with swagger and the unlikely event that there will be v2+. |
|
Regarding
|
SDK generators like progenitor (Rust) need named enum types to produce good code. Without them, you get duplicate anonymous string types on every field instead of a shared StateType enum. Deduplicating enums and giving them proper names in #/components/schemas/ is the main motivation for the converter. AST Walker: Walk Go source to find type StateType string declarations and extract the real type names. This would eliminate the map entirely and be correct by construction. But it's a significant scope increase — needs to parse Go source files, resolve which types are actually used in swagger-annotated structs, and handle edge cases. Worth doing eventually but feels like a separate PR. Or maybe better to focus efforts on building a better go annotations to OpenAPI 3 spec. My goal here was the shortest path to being able to use OpenAPI ecosystem tools. |
I understand the concern — a two-stage pipeline (annotations → Swagger 2.0 → OAS3) is more steps than ideal. But I think this PR is a useful incremental step:
That said, direct OAS3 generation would be strictly better long-term. |
e6f384f to
e9cd8cf
Compare
|
@silverwind @TheFox0x7 I made some changes. Could we move forward with this? If we don't want to move forward with this can you give me a path to get an openapi 3.x spec that you do like? |
Have you addressed reviews? |
I had missed some, thank you for the prompt. |
|
Reviewed with Claude Opus 4.7 and opencode; aggregated findings below. HighH1. Missing reserved username entry —
MediumM1.
M2. Walks response/request-body media-types but doesn't recurse into M3. Already discussed — author chose this over an AST walker as the shorter path. Worth documenting that this map must be updated when new enum types are added, otherwise new enums will silently get derived generic names. LowL1. Makefile prereq omits tools file —
L2. All other files in L3. Naming inconsistency — URL L4. When no Posted by Claude Opus 4.7 on behalf of @silverwind. |
|
Regarding Better designs, ranked:
|
Add a build-time conversion step that transforms the existing Swagger 2.0 spec into an OpenAPI 3.0 spec. The OAS3 spec is served alongside the existing Swagger 2.0 spec, enabling API clients that require OAS3 (progenitor, openapi-python-client, etc.) to generate code directly from Gitea's API. New files: - build/generate-openapi.go — converts swagger v1_json.tmpl to OAS3 - build/openapi3-tools.go — tool dependency for kin-openapi - routers/web/swagger_json.go — serves the OAS3 spec - templates/swagger/v1_openapi3_json.tmpl — generated OAS3 spec
- Add build/generate-openapi.go as Makefile prerequisite so changes to the converter trigger spec regeneration - Remove leftover `_ = key` no-op statement - Add top-of-file comment explaining what the converter does and why - Document why knownEnumTypes mapping is needed Co-Authored-By: Claude Opus 4 (claude-opus-4-6)
The enumGroups loop declared key but never used it; use _ instead so the generator compiles. Regenerate v1_openapi3_json.tmpl. Co-Authored-By: Claude (Opus)
Introduces build/openapi3gen as the testable home for OAS3 converter logic. Starts with EnumKey, the canonical value-set hash shared by the enum scanner and the converter. Co-Authored-By: Claude Opus 4.7 (claude-opus-4-7)
ScanSwaggerEnumTypes reads .go files under each directory, finds types documented with // swagger:enum TypeName, and returns a map from canonical value-set key to type name. Happy-path only; failure modes covered in follow-up commits. Co-Authored-By: Claude Opus 4.7 (claude-opus-4-7)
| $(GO) run build/generate-openapi.go | ||
|
|
||
| .PHONY: openapi3-check | ||
| openapi3-check: generate-openapi3 |
There was a problem hiding this comment.
Still think these targets should not have a version, e.g. generate-openapi.
There was a problem hiding this comment.
swagger == openapi 2.0, so something labeled only openapi could be v2 or v3. The version number makes it clear
There was a problem hiding this comment.
I never heard about openapi 2.0, and we don't want to rename this make target once we switch to openapi 3.1, 3.2 or 4.0. there will only ever be one openapi output.
There was a problem hiding this comment.
The project already have a OpenAPI spec: the swagger spec. Swagger became OpenAPI 2.0, then OpenAPI came out with a new version, 3.0. If we rename the OpenAPI 3.0 spec "openapi", then it will be unclear what version this end point is.
There was a problem hiding this comment.
I think generate-openapi3 is a right name
There was a problem hiding this comment.
?
If we're being pedantic it should be generate-openapi2. Swagger has no version, It's the same as openapi2.
Besides I really don't follow here... what integrations? Who's dependent on gitea Makefile or integrating with it? Why would you even promise that makefile is stable, especially for something that's embedded in code and does not need to be generated by any end user or packager?
There was a problem hiding this comment.
If we upgrade to 3.1, should we rename to
generate-openapi31breaking existing integrations?
Why? 3.1 literally belongs to 3, right? 4 doesn't belong to 3 and it breaks from 3, right?
So generate-openapi3 is absolutely the right name
There was a problem hiding this comment.
OAS 3.1 is not strictly backwards-compatible with 3.0, there are subtle breaking changes. I don't get this discussion, we have a "swagger spec" and we have a "openapi spec", versions are irrelevant in both for the generation purpose. I would not recommend to have v3 and v4 specs to co-exist.
There was a problem hiding this comment.
I would not recommend to have v3 and v4 specs to co-exist.
But now v2 (swagger) and and v3 do co-exist.
I do not see anything wrong with the name "openapi3".
If "OAS 3.1 is not strictly backwards-compatible with 3.0", then "openapi3" is just even better.
Why you prefer to mix unclear things together? What's wrong with the number "3" to end users? Who will be hurt or confused?
There was a problem hiding this comment.
OAS 3.1 is not strictly backwards-compatible with 3.0, there are subtle breaking changes
Then why have it as openapi3.v1.json in the router? If in the future we swap it to 3.1 then "the subtle breaking changes" will impact users. Should THAT be more of an issue than makefile?
The target could be named anything and it wouldn't make a difference since no user will ever run it in the first place.
|
it generally looks good and when I plugged it into scalar a bit ago it had no issues. If we're keeping the version in a route, maybe have the entire one? I'm not sure what changed from 3.0 -> 3.1, but it's currently ambiguous which of the two is served which might be confusing to some people if they make wrong assumption. |
|
OAS 3.1 is some keyword alignment and full JSON schema support. A very nice upgrade if you actually work with JSON schema. Likely not relevant for gitea. Long-term I'd like us to switch to a generator that generates OAS 3+ only but I guess this serves as a bridge because that migration will be big. |
TheFox0x7
left a comment
There was a problem hiding this comment.
good to go from my pov. Ran the output spec through vacuum and it doesn't report anything major that's actionable apart from uniqueItems constraint on some string properties. Nothing major though
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Fix missing newline at the end of the file. Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
|
Some TODOs for following up PRs in my mind:
|
* origin/main: Refactor CI workflows (go-gitea#37487) Allow multiple projects per issue and pull requests (go-gitea#36784) [skip ci] Updated translations via Crowdin Refactor compare diff/pull page (1) (go-gitea#37481) Fix review submission from single-commit PR view (go-gitea#37475) Refactor integration tests infrastructure (go-gitea#37462) Fix allow maintainer edit permission check (go-gitea#37479) Serve OpenAPI 3.0 spec at /openapi.v1.json (go-gitea#37038) Batch-load related data in actions run, job, and task API endpoints (go-gitea#37032) Add DEFAULT_TITLE_SOURCE setting for pull request title default behavior (go-gitea#37465) Fix compare dropdown for branches without common history (go-gitea#37470) FIX: URL sanitization to handle schemeless credentials (go-gitea#37440) Refactor pull request view (4) (go-gitea#37451) # Conflicts: # modules/indexer/issues/elasticsearch/elasticsearch.go
The OAS3 conversion landed upstream (go-gitea#37038) after this branch was last regenerated. Run make generate-swagger so the converted templates/swagger/v1_openapi3_json.tmpl reflects the includes query param and blocked_by/blocking schema fields on the three issue endpoints (GetIssue, ListIssues, SearchIssues). Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
Add a build-time conversion step that transforms the existing Swagger 2.0 spec into an OpenAPI 3.0 spec. The OAS3 spec is served alongside the existing Swagger 2.0 spec, enabling API clients that require OAS3 (progenitor, openapi-python-client, etc.) to generate code directly from Gitea's API.
New files:
This is not to be an answer to how gitea handles OAS3 long term, but a way to use what we have to move a step forward.
See https://github.com/myers/gt for how this can be used.
Written with Claude Code using Opus, and human reviewed.