Use oasdiff to compare a committed Loom OpenAPI contract with a regenerated
revision. This workflow reports compatibility changes before they reach API
consumers.
Loom does not include a diff engine. The consuming repository owns its oasdiff version, policy, severity overrides, and ignores.
Loom emits OpenAPI 3.2 by default. oasdiff v1.29.1 reads 3.2 documents, but
its documentation says that 3.2 coverage remains under development.
Use Loom's 3.1 compatibility target for this conservative baseline:
var _ = API("MyAPI", func() {
Meta("openapi:version", "3.1")
Meta("openapi:output", "json")
})OpenAPI 3.1 support is generally available in oasdiff. Review the oasdiff OpenAPI support guide before changing this target.
This guide uses these tested versions:
- oasdiff CLI
v1.29.1 - oasdiff action
v0.1.13, commit2649ebe137aeb72a95707671204e829f86e091fc
Install the pinned CLI without adding it to the service module:
go install github.com/oasdiff/oasdiff@v1.29.1Pin the action to its full commit SHA in CI. Keep the release tag in a comment so reviewers can identify the version.
For an upgrade:
- Read the oasdiff CLI and action release notes.
- Update both pins in one change.
- Review OpenAPI version support and changed checks.
- Run the normal comparison and the known-breaking canary below.
- Review every policy or ignore-file change separately.
Replace the design package if your module uses another path.
DESIGN_PACKAGE=example.com/myservice/design
OPENAPI_SPEC=gen/http/openapi.json
go tool loom gen "$DESIGN_PACKAGE"
git diff --exit-code -- gen/http/openapi.json gen/http/openapi.yaml
oasdiff breaking \
--fail-on ERR \
--format githubactions \
--allow-external-refs=false \
-- \
"origin/main:${OPENAPI_SPEC}" \
"$OPENAPI_SPEC"Run the command from the repository that contains the generated specification.
Fetch origin/main first when the local Git object is missing.
--fail-on ERR blocks definite breaking changes. oasdiff still reports WARN
findings for review. Use --fail-on WARN when project policy blocks both
levels.
Create a non-blocking Markdown changelog for review:
oasdiff changelog \
--format markdown \
--allow-external-refs=false \
-- \
"origin/main:${OPENAPI_SPEC}" \
"$OPENAPI_SPEC" \
> openapi-changelog.mdThe changelog command does not set a blocking threshold in this recipe.
Run this canary when adopting or upgrading oasdiff:
- Create a temporary branch.
- Remove one published success response from the Loom design.
- Regenerate the OpenAPI contract.
- Run the local
oasdiff breakingcommand above. - Make sure the command exits with status
1and reports anERRfinding. - Revert the temporary design change and regenerate.
This canary proves that the selected version and project policy block a known breaking change.
Copy the pinned GitHub Actions example to
.github/workflows/oasdiff.yml. Replace DESIGN_PACKAGE when required.
The example performs these tasks in order:
- Fetch the pull request's base branch.
- Regenerate the Loom contract.
- Fail when committed JSON or YAML output is stale.
- Add a non-blocking Markdown changelog to the job summary.
- Report
WARNfindings and blockERRfindings.
The revision input reads the regenerated working-tree file. The base input uses the committed file from the pull request's base Git revision.
Store project policy in the consuming repository. Common files include:
.oasdiff.yaml- a severity override file
- a narrow
ERRignore file - a narrow
WARNignore file
Loom does not generate or overwrite these files. Give each ignore an owner, reason, and removal condition. Prefer a severity override when project policy classifies a check differently.
Start with ERR as the blocking threshold and review every WARN. A project
can later block WARN after it has removed noisy or ambiguous findings.
The CLI resolves external $ref values by default. Keep
--allow-external-refs=false for untrusted pull requests.
The oasdiff action defaults this setting to false. The example sets it
explicitly. Enable external references only after defining safe file and
network loading rules.
The action also enables encrypted hosted review by default. It uploads an encrypted comparison to oasdiff.com and can add a review link to the pull request.
Set review: false when no specification data can leave CI. The example uses
this setting. For the CLI, omit --open to keep review data local.
| Contract area | Required coverage |
|---|---|
| Published standard OpenAPI fields | oasdiff breaking gate and changelog |
| Generated transport responses | Loom response-contract scaffold |
x-loom-* extension behavior |
Loom-owned focused tests |
| Business behavior and fixtures | Application-owned tests |
oasdiff can report text changes inside extensions. It cannot prove the runtime
meaning of Loom-specific extensions such as x-loom-async.
Use both layers. oasdiff protects the published standard contract, while Loom scenarios prove that the implementation produces each declared response.