build(api): commit the openapi spec as a yaml - #960
Merged
Conversation
Every branch that touches a controller regenerates the spec, and the spec was one line of minified JSON. Two such branches conflicted on that line every time, whatever they had each changed, and resolving it meant regenerating rather than reading a diff. This branch hit it three times. It is `openapi.yaml` now, block style, keys sorted: 22,495 lines where there was one. Two branches adding an endpoint each conflict only where they actually disagree. The old comment in openapi-common.sh said the extension had to stay .json because @hey-api/openapi-ts parses .yaml as YAML "and errors on single-line flow-style documents". That was a consequence of keeping minified content in a .yaml file, not a reason to keep minifying. Block YAML reads fine, which the generated client proves: it is byte-identical to the one the JSON produced. The generator test writes the YAML with snakeyaml, which the api already bundles, so `dumpOpenApiSpec` is a copy and the jq dependency is gone. `normalize_api_spec` has nothing left to normalise and is kept as a presence check so the call sites still read the same for every spec.
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
services/api/openapi.jsonwas one line.jq -S -cminified it, so every branch thattouched a controller regenerated that line, and two such branches conflicted on it every
time — whatever each had actually changed. Git cannot merge a single line two ways.
Resolving it never meant reading a diff either, because there is nothing to read: the fix is
always to take either side and regenerate. #921 hit this three times in one branch.
The comment in
scripts/openapi-common.shsaid the extension had to stay.json:That is a consequence of keeping minified content in a
.yamlfile, not a reason to keepminifying. A flow-style document in a
.yamlfile breaks the parser; a block-style one doesnot.
What this achieves
services/api/openapi.yaml, block style, keys sorted: 22,495 lines where there was one.Two branches that each add an endpoint now conflict only where they genuinely disagree, and
a conflict that does happen is legible.
The generated TypeScript client is byte-identical to the one the JSON produced, which is
the evidence that the parser concern above was about flow style rather than about YAML.
How
The generator test already wrote the spec, so it writes the YAML too — sorted keys, block
style,
widthunbounded so a long description stays on its line and a reworded sentence is aone-line diff. It uses snakeyaml, which
services/apialready bundles.dumpOpenApiSpecis therefore a copy, andjqleaves that code path entirely.normalize_api_spechas nothing left to normalise; it is kept as a presence check so thecall sites still read the same for every spec.
Ten places named the old path and all move:
.gitattributes,.github/diff-stats.yml, thesync assertion in
validate.yml,openapi-ts.blueshell.config.ts, the frontend composemount, both generation scripts, and the Gradle task with its comments.
Worth a reviewer's attention
The diff is 22.5k lines and all but 55 of them are one generated file.
.gitattributesalready marks it
linguist-generated, so GitHub collapses it.The first PR after this that changes an endpoint will show a large spec diff, because it
is the first content diff against a format that has no history. After that they are small,
which is the point.
Sorting is now done in Kotlin rather than by
jq -S.sortKeyssorts every object'skeys and leaves arrays in the order the api gave them — springdoc's ordering is meaningful
for parameters and
required.Verification
:services:api:testyarn typecheck·yarn lintgenerate-openapi-local.shrun twice, then diffedSplit out of #921, which needed it and will rebase onto it.
Diff breakdown —
█added░removed, scaled to the largest row.