Run an OpenAPI diff in GitHub Actions
A useful pull-request check compares the consumer-visible contract from the base revision with the candidate contract, then fails only when policy says the change is unsafe. Cryonel's public npm CLI works directly in GitHub Actions without access to a private repository.
Use an immutable baseline
Check out the pull request code and read the base spec directly from the base commit. Do not compare against a mutable production URL unless monitoring production drift is the explicit goal. A remote file can change while the workflow runs and makes the result difficult to reproduce.
name: OpenAPI compatibility
on: pull_request
permissions:
contents: read
jobs:
openapi:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Read base contract
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
run: git show "$BASE_SHA:openapi.yaml" > "$RUNNER_TEMP/openapi-base.yaml"
- name: Check OpenAPI compatibility
run: |
set +e
npx --yes @semihbugrasezer/cryonel@0.2.0 diff \
"$RUNNER_TEMP/openapi-base.yaml" openapi.yaml \
--format markdown > "$RUNNER_TEMP/cryonel-openapi-report.md"
status=$?
set -e
cat "$RUNNER_TEMP/cryonel-openapi-report.md" >> "$GITHUB_STEP_SUMMARY"
exit "$status"
The pinned public package writes the report to the job summary and preserves the CLI exit code, so confirmed breaking changes fail the check. The workflow needs only read access to repository contents.
Run the same policy locally
npx @semihbugrasezer/cryonel diff openapi-main.yaml openapi-current.yaml
npx @semihbugrasezer/cryonel diff openapi-main.yaml openapi-current.yaml --format json
npx @semihbugrasezer/cryonel diff openapi-main.yaml openapi-current.yaml --fail-on potentially-breaking
Exit code 0 passes, 1 means the configured compatibility policy failed, and 2 means the input or command is invalid. npm downloads the public CLI package and runs the cryonel binary locally.
Keep policy in the repository
{
"failOn": "breaking",
"ignoreRules": ["path.add"],
"ignoreLocations": ["paths./internal/*"]
}
Save the file as .cryonelrc.json and the CLI loads it automatically. Patterns accept * wildcards. Keep ignore entries narrow and review them like code: they suppress a finding from both the report counts and exit decision. Use --config path/to/policy.json only when the policy lives elsewhere.
Validate before comparing
Run structural validation on both documents first. A diff from one invalid document is not a trustworthy compatibility decision. Validation failures should identify which revision is invalid and stop the comparison with a clear message.
Separate severity from workflow policy
Have the diff step classify breaking, potentially breaking, and non-breaking changes. Let a small policy layer decide the exit code. Confirmed removals or narrowed request schemas can fail the job. Additive operations can be reported in the summary without blocking. Potential changes should request review when client behavior is unknown.
Publish a durable report
Console logs are hard to scan and disappear into long workflows. The example appends Cryonel's Markdown report to the native GitHub Actions job summary. Reports contain classifications and schema locations, never the full specification.
Protect the workflow
Pull request content is untrusted. The workflow reads the changed specification as data and does not execute repository code. Use the pull_request event; do not switch to pull_request_target to run an untrusted head revision. Fork workflows may receive a read-only token, so a comment can be skipped while the job summary and compatibility result still work. Pin action versions according to your repository security policy.
Test the gate itself
Keep small fixture pairs for one breaking, one additive, and one invalid change. Run them in the same CI job so a dependency update cannot silently turn a failing rule into a passing one. A green diff workflow is meaningful only when its negative case is regularly exercised.
Prove the gate can fail
Download Cryonel's reviewed base fixture and breaking fixture. Run npx --yes @semihbugrasezer/cryonel@0.2.0 diff base.yaml breaking.yaml. The command must report that /users/{id} was removed, then exit with status 1. Run this negative case after dependency updates so a permanently green workflow cannot hide a disabled gate.
Verification notes and primary sources
The workflow and negative fixture were reviewed by Semih Buğra Sezer on 14 August 2026. Contract semantics follow the OpenAPI Specification; workflow permissions and untrusted pull-request guidance follow GitHub's Actions security guidance. The public CLI reports supported compatibility rules and does not execute the specification.
Frequently Asked Questions
Which file should be the baseline?
Use the exact file from the pull request base revision, not a separately downloaded mutable URL.
Should every detected change fail CI?
No. Fail confirmed breaking changes and report additions unless your policy says otherwise.
Should the workflow compare generated or source specs?
Compare the artifact consumers receive, while also validating its source generation path.
Related Tools and Guides
Need it installed for you? Request the fixed-price CI Guard Setup.