Skip to main content

Review APIs in CI

Speccy's GitHub Action compares OpenAPIOpenAPIA machine-readable standard for describing HTTP APIs, including their operations, parameters, request bodies, responses, and schemas. documents with the pull request's base branch, checks the current documents for API health problems, and publishes one persistent review comment.

See Review API health for the rule categories and how the same findings appear in the renderer and Studio.

Add the GitHub Action

Check out the full Git history so Speccy can read the base branch:

.github/workflows/api-review.yml
name: API review

on: pull_request

permissions:
contents: read
pull-requests: write

jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: mcclowes/speccy@v1
with:
specs: |
Public API=openapi.yaml

List several named documents when a repository owns more than one API:

with:
specs: |
Admin=reference/admin.yml
Public=reference/public.yml

For a generated document, provide explicit base and revision artifacts with base-path=>revision-path.

Configure repository rules

Add an optional .speccyrc JSON file at the repository root. Without one, Speccy uses speccy:recommended and the default severity for every rule.

.speccyrc
{
"extends": ["speccy:recommended"],
"rules": {
"new-operation-lifecycle": {
"severity": "suggestion",
"maxAgeDays": 30,
"allowedStages": ["new", "coming-soon", "beta", "early-access"]
},
"request-example": false,
"response-example": "warning"
},
"ignore": [
{
"rules": ["operation-security", "request-example"],
"paths": ["/public/**"]
}
]
}

A rule accepts:

  • true to keep its default severity
  • false to disable it
  • "suggestion", "warning", or "issue" to override its severity
  • an options object for rules with additional settings

Unknown rules, properties, severities, and options fail the check. This catches misspelled configuration instead of silently weakening review. Contract-correctness rules, including duplicate operation IDs and broken path parameters, cannot be disabled or ignored.

Ignore rules by API path

An ignore entry applies one or more rules to matching OpenAPIOpenAPIA machine-readable standard for describing HTTP APIs, including their operations, parameters, request bodies, responses, and schemas. paths. * matches within one path segment; ** crosses segments.

{
"ignore": [
{
"rules": ["operation-security"],
"paths": ["/public/**", "/health"]
}
]
}

These patterns match API paths such as /public/forms/{formId}, not files in the repository.

Mark new operations

Change-aware linting suggests lifecycle metadata when a pull request adds an operation. Add the stage and the date it became available:

paths:
/exports:
post:
summary: Create an export
x-speccy-lifecycle: new
x-speccy-lifecycle-since: 2026-08-13

Speccy suggests removing new when the date is older than maxAgeDays. coming-soon, beta, and custom allowed stages do not expire automatically.

Disable this policy when it does not suit the repository:

.speccyrc
{
"rules": {
"new-operation-lifecycle": false
}
}

See OpenAPI extensions for how lifecycle metadata appears in the reference.

Run the same checks locally

speccy lint reads the same .speccyrc file from the directory it runs in. speccy diff doesn't use the config; its severity is controlled by --fail-on alone:

npx speccy-cli lint openapi.yaml --against origin/main:openapi.yaml
npx speccy-cli diff origin/main:openapi.yaml openapi.yaml

Use --format markdown for output suitable for a pull request comment. Lint exits with code 1 when a finding reaches --fail-on; diff does the same for its configured change severity. Tool and parsing failures use code 2.

Action inputs

InputDefaultPurpose
specsrequiredNamed spec paths, one per line
versionlatestPublished speccy-cli version
fail-onbreakingDiff severity that fails the action
health-fail-onneverHealth severity that fails the action
commenttruePublish or update the pull request comment
github-tokenGitHub tokenToken used to publish the comment