CtrlK
BlogDocsLog inGet started
Tessl Logo

check-oas

Detect breaking changes in docs/mapi/openapi.yaml and check whether the committed spec is stale; run the OAS checks, interpret findings, and guide fixes.

82

1.56x
Quality

72%

Does it follow best practices?

Impact

100%

1.56x

Average score across 3 eval scenarios

SecuritybySnyk

Advisory

Suggest reviewing before use

Optimize this skill with Tessl

npx tessl skill review --optimize ./docs/agent-standards/skills/check-oas/SKILL.md
SKILL.md
Quality
Evals
Security

OpenAPI Spec Checks

Two independent scripts cover the management API spec at docs/mapi/openapi.yaml:

ScriptWhat it doesExits
oas-staleness-check.shRegenerates the spec from source and diffs against the committed file0 or 1
oas-compat-check.shChecks the committed spec for breaking changes since the merge-base0 or 1

oas-staleness-check.sh

Runs scripts/regen-oas.sh into a temp directory and diffs the result against the committed docs/mapi/openapi.yaml. If they differ, a warning and diff summary are printed.

Exits 1 if the committed spec differs from the regenerated output. The regeneration is deterministic — paths, tags, schemas, and schema properties are all explicitly sorted in GraviteeApiDefinition.afterScan() — so any diff is a genuine mismatch. Internal refactors and model changes that don't affect the REST layer produce no diff.

Exits 0 if the spec is up to date, or if regeneration itself fails (compilation error, missing module). A build failure is not reported as a staleness failure.

First-run note: if the committed spec was previously generated by the running server rather than scripts/regen-oas.sh, there may be one-time differences in formatting or endpoints. Run bash scripts/regen-oas.sh once and commit the result to establish the canonical plugin-generated baseline before this check is enforced.

Requires the management API module to be compiled. In CI this is satisfied by the process_pull_request workspace. Locally, pass --also-make to compile first.

# CI equivalent (module already compiled):
bash .circleci/scripts/oas-staleness-check.sh

# Local (compiles upstream modules first):
bash .circleci/scripts/oas-staleness-check.sh --also-make

If the check warns that the spec is stale, regenerate and commit:

bash scripts/regen-oas.sh           # module already compiled
bash scripts/regen-oas.sh --also-make  # compile + regenerate

See Updating the spec for how regeneration works.


oas-compat-check.sh

Compares docs/mapi/openapi.yaml at the merge-base against HEAD (or the working tree when --use-head false) using oasdiff. Exits 1 if breaking changes are found, unless a version-boundary exemption applies.

If the spec has not changed since the merge-base, the check exits 0 immediately.

Requires oasdiff on PATH:

# macOS:
brew install tufin/tufin/oasdiff

# Linux — pinned to the same version as CI (see .oasdiff-version):
OASDIFF_VERSION=$(cat .oasdiff-version)
curl -sSL "https://github.com/tufin/oasdiff/releases/download/v${OASDIFF_VERSION}/oasdiff_${OASDIFF_VERSION}_linux_amd64.tar.gz" \
  | tar -xz -C /usr/local/bin oasdiff

Baseline resolution

When --base is omitted the baseline is resolved automatically (see .circleci/scripts/_compat_common.sh):

  • master or x.y.x release branches → HEAD~1
  • All other branches → git tracking branch (@{u}) if set to a different branch, else HEAD~1
# Default (auto-resolve merge-base):
bash .circleci/scripts/oas-compat-check.sh

# Explicit baseline — any valid git ref:
bash .circleci/scripts/oas-compat-check.sh --base 4.11.0          # tag
bash .circleci/scripts/oas-compat-check.sh --base origin/master   # branch tip
bash .circleci/scripts/oas-compat-check.sh --base abc1234         # commit SHA
bash .circleci/scripts/oas-compat-check.sh --base HEAD~10         # relative ref

# Include uncommitted (staged + unstaged) changes:
bash .circleci/scripts/oas-compat-check.sh --use-head false

# Run oasdiff directly on two spec files:
oasdiff breaking path/to/old-openapi.yaml docs/mapi/openapi.yaml

Breaking-change exemption

oas-compat-check.sh still runs oasdiff and prints findings, but exits 0 regardless, in two cases detected by comparing pom.xml <version> at baseline vs. HEAD:

  • Minor version bump — e.g. 4.11.x4.12.x. Breaking changes between minor releases are expected.
  • Patch is zero — e.g. 4.12.0. No release of this minor version exists yet, so there are no deployed clients to protect.

What counts as a breaking change

Key categories (not exhaustive — see oasdiff breaking changes):

CategoryExample
Path removedDELETE /domains/{domainId}/applications removed
Operation removedGET removed from an existing path
Required request parameter addedNew required query or path parameter
Required request body property addedNew required field in a request schema
Response property removedField removed from a response schema
Response property type changedstringinteger
Enum value removed"RS256" removed from allowed JWT algorithms
Security scheme changedAuth requirement added or removed

Understanding oasdiff output

☑️ Api Changes:
error	[response-property-removed] at paths./api/organizations/{organizationId}/domains.get.responses.200.content.application/json
        deleted property 'total' from response

warning	[request-parameter-default-value-changed] at paths./api/organizations/{organizationId}/domains.get.parameters[0]
        changed default value from '0' to '1' for path parameter 'page'
  • error — breaking change; oas-compat-check.sh exits 1 unless exempted
  • warning — potentially breaking or informational; exits 0

How to fix breaking changes

ErrorFix
Response property removedKeep the field; mark it deprecated in description
Required request parameter addedMake the new parameter optional with a default
Required request body property addedMake it optional (remove from required) or provide a default
Enum value removedKeep the old value in the enum
Path or operation removedDeprecate first; remove only in a new minor version

Updating the spec

docs/mapi/openapi.yaml can be regenerated without starting the management API server using scripts/regen-oas.sh. It uses swagger-maven-plugin-jakarta to scan JAX-RS annotations at build time — the GraviteeApiDefinition ReaderListener is auto-discovered and invoked, producing the same sorted paths, tags, and security schemes as the runtime output. Two things are patched post-generation:

  • info.version — the plugin reads Version.RUNTIME_VERSION (gravitee-common library version, not the project version); patched from pom.xml via mvn help:evaluate.
  • License header — extracted from the committed spec before overwriting and prepended to the generated file; required by the license-maven-plugin validate check.
bash scripts/regen-oas.sh             # module already compiled
bash scripts/regen-oas.sh --also-make # compile upstream modules first

Alternatively, regenerate via the running server (always authoritative):

# 1. Start the management API locally.
# 2. Fetch the spec:
curl -s http://localhost:8093/management/openapi.yaml > docs/mapi/openapi.yaml

Commit the updated spec alongside your code changes.

Repository
gravitee-io/gravitee-access-management
Last updated
Created

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.