Skip to content

v1.32.0

Choose a tag to compare

@reuvenharrison reuvenharrison released this 13 Sep 14:49
· 112 commits to main since this release
560d26e

56 new checks, cycle-proof diff and flatten

The generated-rule engine now covers every increase and decrease of every bound keyword (catalog: 699 to 755 checks), and recursive schemas are handled end to end: no more stack overflows in diff or flatten, deterministic structured output, and flattened recursion that always serializes under stable names.

CLI changes

Detection rules

  • Every bound keyword's increase and decrease is now checked (#1232). The rule engine that generates set/unset checks now also generates increased/decreased ones, closing 56 gaps at once: response headers get their first increase/decrease checks, parameters gain maxProperties/minProperties/minContains/maxContains coverage, and the widening response directions (for example response-body-max-decreased) are reported at info level. multipleOf is deliberately excluded: numeric order does not decide its effect, so it keeps its dedicated changed/generalized/specialized checks.
  • Exclusive bounds join the generated rules, fixing three latent bugs (#1226). In the OpenAPI 3.0 boolean form, exclusiveMaximum: false to true used to report nothing (it is a breaking set), adding exclusiveMaximum: false was reported as breaking (it changes nothing, false means not exclusive), and the false-to-true transition could be misreported as a value increase.
  • Added and deleted properties under an unflattened allOf carry the disclaimer (#1229). Existence changes inside allOf branches now get the same warning cap and --flatten-allof hint as other findings there, and a schema that itself has an allOf is recognized by presence rather than only when the allOf changed.
  • oasdiff checks shows each rule's guards (#1227). A GUARDS column and a --tags dimension expose the read-only / write-only guards, so a verdict downgraded by a guard is explained by the catalog instead of looking like a bug.

Recursive schemas: no crashes, deterministic output, serializable flatten

  • Diffing ref-less cyclic schemas no longer overflows the stack (#1231, thanks @dimitropoulos). Schemas that reference themselves through in-memory links rather than $ref (for example after --flatten-allof merges a recursive component) are cut safely at the point of re-entry, whatever shape the cycle has.
  • oasdiff flatten of recursive allOf merges always serializes (#1233, #1240, #1245). A cycle keeps its $ref where one exists, a set that merges to a single schema reuses that schema with its name, and a genuinely anonymous merged cycle is hoisted into components.schemas under a name built from the merged component names (AllOfMerged_NodeA_NodeB), so the same cycle keeps the same name in every revision. Documented in docs/ALLOF.md (#1244).
  • A merge mixing a recursive branch with other constraints keeps them all (#1243). Such a node becomes an allOf of the named cycle and the merged remaining constraints instead of silently dropping them, which could previously hide breaking changes in the flattened comparison.
  • Structured output for multi-cycle schemas is deterministic (#1237, thanks @BigMichi1 for the precise report in #1230). A schema participating in more than one reference cycle produced one of two different --format json/yaml outputs at random; identical inputs now produce identical bytes, and the output is also more complete, each cycle edge carrying its own diff. Diffs of such schemas change once when you upgrade.
  • The circularRef output field is removed (#1238). Cyclic-reference mismatches now appear as ordinary field-level diffs, which say strictly more; a pure rename of a cyclic $ref is no longer reported, matching how non-cyclic $ref renames behave.

Validate

  • New lint: mutability flags no request or response can ever see (#1228). A readOnly on a schema reachable only from requests, or writeOnly only from responses, can never take effect; oasdiff validate now flags both, walking webhooks and callbacks too.

Misc

  • Ignore and severity-level files no longer swallow read errors (#1234). A failed read, for example a line past the scanner's size limit, is reported instead of silently dropping the unread entries.
  • The install script is quoting-safe (#1241). install.sh handles paths containing spaces, and the repo's shell (including workflow run: blocks) is now gated by shellcheck and actionlint.

Go package changes

  • Breaking: diff.SchemaDiff.CircularRefDiff is removed (#1238), together with the ref-string circular guard it powered; the in-flight pair guard introduced in #1231 handles cycle termination for every cycle shape.
  • Breaking: checker.BoundSetUnsetCheck is renamed BoundCheck (#1232), reflecting that it now reports increase and decrease as well.
  • diff.SchemaBound gains WasIncreased and WasDecreased (#1232), completing the bound classification API alongside WasSet and WasUnset.
  • checker.GetTransitions exposes transition metadata (#1225): the named transition recognizers with the change kinds they claim and the checks that report them, powering the public OpenAPI Changes Model export.
  • flatten/allof: MergeSpec guarantees marshalable output for recursive inputs (#1233, #1240, #1243): it repairs shared-reference identity after the in-place merge and names every anchored cycle. Merge (single schema, no components section) documents that a nameless recursive input yields an in-memory cycle that does not marshal.
  • Go 1.27 (#1224): toolchain moved to Go 1.27 and direct dependencies updated.