feat: add Spectral lint rules enforcing API design guidelines#317
feat: add Spectral lint rules enforcing API design guidelines#317
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR introduces a Spectral OpenAPI linter configuration ( The intent is solid and the rule coverage maps well to the design guidelines — however several of the rule implementations have correctness gaps (covered in prior review threads: Key findings:
Confidence Score: 3/5
|
| Filename | Overview |
|---|---|
| .spectral.yaml | New Spectral ruleset with several correctness issues: no-inline-*-schema rules need resolved: false to work correctly, pagination-envelope-has-hasMore JSONPath filter is a no-op, pagination-envelope-has-data will false-positive on non-list GETs, and enum-values-upper-snake-case misses property-level enums — most flagged in previous review threads. |
| Makefile | Adds lint-spectral Make target but does not wire it into the primary lint target, leaving Spectral out of CI enforcement. |
| package.json | Adds @stoplight/spectral-cli as a devDependency; no lint:spectral npm script added, which is consistent with the direct npx invocation in the Makefile. |
| openapi/README.md | Adds "Avoid Inline Schemas" section documenting the $ref-only pattern; documentation is clear and accurate. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
PR[Pull Request / Push] --> CI[".github/workflows/lint.yml\nruns: make lint"]
CI --> MAKELINT["make lint\n→ npm run lint"]
MAKELINT --> REDOCLY["npm run lint:openapi\n(Redocly bundle + lint)"]
REDOCLY --> PASS["✅ CI passes"]
MAKELINT -.->|"NOT called\n(gap introduced by this PR)"| SPECTRAL
SPECTRAL["make lint-spectral\n→ npx spectral lint openapi.yaml"]
SPECTRAL --> RULES
subgraph RULES["Spectral Rules (.spectral.yaml)"]
R1["Naming: camelCase fields,\nparams, paths-kebab-case"]
R2["Enums: UPPER_SNAKE_CASE"]
R3["No inline request/response schemas\n⚠️ needs resolved: false"]
R4["oneOf must have discriminator"]
R5["Pagination envelope:\ndata + hasMore\n⚠️ hasMore filter is a no-op"]
R6["DELETE returns 204"]
R7["Properties need descriptions\n+ examples"]
end
SPECTRAL -.->|"must be run\nmanually"| DEV["👤 Developer only"]
Prompt To Fix All With AI
This is a comment left during a code review.
Path: Makefile
Line: 22-23
Comment:
**Spectral not wired into the main `lint` target**
The `lint` Make target calls `npm run lint`, which maps to only `lint:openapi` (Redocly). The new `lint-spectral` target is entirely separate, so CI (`.github/workflows/lint.yml` runs `make lint`) will never execute Spectral. This means the rules added in this PR are effectively advisory — a PR introducing a camelCase violation, missing discriminator, or inline schema will pass CI without complaint.
To enforce Spectral in CI, `lint-spectral` needs to be added as a dependency of `lint` (or chained in):
```suggestion
lint:
npm run lint
$(MAKE) lint-spectral
```
Alternatively, add a `lint:spectral` script to `package.json` and extend the `lint` script: `"lint": "npm run lint:openapi && npx spectral lint openapi.yaml --fail-severity=error"`.
Note also that `.spectral.yaml` is absent from the `paths` trigger in `.github/workflows/lint.yml`, so changes to the rule file alone won't re-run CI.
How can I resolve this? If you propose a fix, please make it concise.Reviews (2): Last reviewed commit: "feat: add Spectral lint rules enforcing ..." | Re-trigger Greptile
Add Spectral OpenAPI linter with rules matching openapi/README.md: - field-names-camelCase: schema properties must be camelCase (error) - enum-values-upper-snake-case: enum values must be UPPER_SNAKE_CASE (error) - query/path-params-camelCase: parameter names must be camelCase (error) - paths-kebab-case: path segments must be kebab-case (error) - no-inline-request/response-schema: must use $ref not inline (error) - oneOf-must-have-discriminator: oneOf needs discriminator (warn) - pagination-envelope-has-data/hasMore: list responses need envelope (warn) - delete-returns-204: DELETE should return 204 (warn) - schema-properties-have-descriptions: properties need descriptions (warn) - schema-properties-have-examples: properties should have examples (info) Spectral is not yet wired into `make lint` — run `make lint-spectral` to check. Will be added to CI after existing violations are fixed. Also adds "Avoid Inline Schemas" section to openapi/README.md. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
f5273d4 to
1acd438
Compare
| lint: | ||
| npm run lint |
There was a problem hiding this comment.
Spectral not wired into the main
lint target
The lint Make target calls npm run lint, which maps to only lint:openapi (Redocly). The new lint-spectral target is entirely separate, so CI (.github/workflows/lint.yml runs make lint) will never execute Spectral. This means the rules added in this PR are effectively advisory — a PR introducing a camelCase violation, missing discriminator, or inline schema will pass CI without complaint.
To enforce Spectral in CI, lint-spectral needs to be added as a dependency of lint (or chained in):
| lint: | |
| npm run lint | |
| lint: | |
| npm run lint | |
| $(MAKE) lint-spectral |
Alternatively, add a lint:spectral script to package.json and extend the lint script: "lint": "npm run lint:openapi && npx spectral lint openapi.yaml --fail-severity=error".
Note also that .spectral.yaml is absent from the paths trigger in .github/workflows/lint.yml, so changes to the rule file alone won't re-run CI.
Prompt To Fix With AI
This is a comment left during a code review.
Path: Makefile
Line: 22-23
Comment:
**Spectral not wired into the main `lint` target**
The `lint` Make target calls `npm run lint`, which maps to only `lint:openapi` (Redocly). The new `lint-spectral` target is entirely separate, so CI (`.github/workflows/lint.yml` runs `make lint`) will never execute Spectral. This means the rules added in this PR are effectively advisory — a PR introducing a camelCase violation, missing discriminator, or inline schema will pass CI without complaint.
To enforce Spectral in CI, `lint-spectral` needs to be added as a dependency of `lint` (or chained in):
```suggestion
lint:
npm run lint
$(MAKE) lint-spectral
```
Alternatively, add a `lint:spectral` script to `package.json` and extend the `lint` script: `"lint": "npm run lint:openapi && npx spectral lint openapi.yaml --fail-severity=error"`.
Note also that `.spectral.yaml` is absent from the `paths` trigger in `.github/workflows/lint.yml`, so changes to the rule file alone won't re-run CI.
How can I resolve this? If you propose a fix, please make it concise.
Add Spectral OpenAPI linter with rules matching openapi/README.md:
Also adds "Avoid Inline Schemas" section to openapi/README.md.
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com