-
Notifications
You must be signed in to change notification settings - Fork 82
LCORE-1958: Correct OpenAPI spec violations in docs/openapi.json, add OpenAPI linting to CI #1565
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| # OpenAPI: regenerate check (Spectral + committed docs/openapi.json drift). | ||
| # - scripts/generate_openapi_schema.py builds the spec from FastAPI (app.main). | ||
| # - CI fails if docs/openapi.json does not match generator output (run locally: | ||
| # uv run scripts/generate_openapi_schema.py docs/openapi.json). | ||
| name: OpenAPI (Spectral) | ||
|
|
||
| on: | ||
| - push | ||
| - pull_request | ||
|
|
||
| jobs: | ||
| spectral: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| pull-requests: read | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Install uv | ||
| uses: astral-sh/setup-uv@v5 | ||
| with: | ||
| python-version: "3.12" | ||
| - name: Install dependencies | ||
| # Same pattern as local dev (CONTRIBUTING.md): dev + llslibdev for a full app import. | ||
| run: uv sync --group dev --group llslibdev | ||
| - name: Install PDM | ||
| # scripts/generate_openapi_schema.py asserts OpenAPI info.version matches `pdm show --version`. | ||
| run: uv pip install pdm | ||
| - name: Verify docs/openapi.json matches generator | ||
| run: | | ||
| set -euo pipefail | ||
| uv run python scripts/generate_openapi_schema.py /tmp/openapi-generated.json | ||
| if ! diff -u docs/openapi.json /tmp/openapi-generated.json; then | ||
| echo "::error::docs/openapi.json is out of date. Regenerate with: uv run scripts/generate_openapi_schema.py docs/openapi.json" | ||
| exit 1 | ||
| fi | ||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: "22" | ||
| - name: Spectral lint | ||
| run: npx --yes @stoplight/spectral-cli@6 lint docs/openapi.json --fail-severity error --display-only-failures | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # Spectral (OpenAPI) — https://meta.stoplight.io/docs/spectral/ | ||
| # | ||
| # Full Stoplight OAS ruleset. `oas3-valid-media-example` is off: examples in | ||
| # docs/openapi.json are often partial and produced ~600 warnings with little | ||
| # signal until examples are aligned with schemas. Re-enable when tightening | ||
| # examples (set to "warn" or "error"). | ||
| extends: spectral:oas | ||
| rules: | ||
| oas3-valid-media-example: off |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| # OpenAPI tags and Spectral | ||
|
|
||
| ## Global tag list (`_OPENAPI_TAGS`) | ||
|
|
||
| In `src/app/endpoints/`, route tags come from **`APIRouter(tags=[...])`**, which FastAPI uses when it builds the OpenAPI description for each operation. | ||
|
|
||
| The OpenAPI document must list those tags at the top level for tools like [Spectral](https://stoplight.io/open-api/) rule **`operation-tag-defined`** to pass, so we keep **`_OPENAPI_TAGS`** in **`src/app/main.py`** and pass it into the **`FastAPI`** app as **`openapi_tags`**. | ||
|
|
||
| **When you add a new router or change `tags=[...]` to use a new tag name**, add a matching entry to **`_OPENAPI_TAGS`** (same `name` string, plus a short `description` for the docs). | ||
|
|
||
| The schema generator **`scripts/generate_openapi_schema.py`** passes **`tags=app.openapi_tags`** into **`get_openapi()`** so **`docs/openapi.json`** includes the top-level `tags` array. Regenerate after tag changes: | ||
|
|
||
| ```bash | ||
| uv run scripts/generate_openapi_schema.py docs/openapi.json | ||
| ``` | ||
|
|
||
| ## Linting (`make lint-openapi`) | ||
|
|
||
| Spectral is configured in **`.spectral.yaml`** (extends `spectral:oas`). Run: | ||
|
|
||
| ```bash | ||
| make lint-openapi | ||
| ``` | ||
|
|
||
| This is part of **`make verify`**. If **`npx`** is not on your **`PATH`**, the Makefile **skips** Spectral and prints a short message so **`make verify`** can still pass; install Node.js to run the check locally. **CI** (`.github/workflows/openapi_spectral.yaml`) always runs Spectral. Failures are driven by **error**-severity rules. | ||
|
coderabbitai[bot] marked this conversation as resolved.
Comment on lines
+21
to
+25
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use the This page already uses 📝 Proposed update-make lint-openapi
+uv run make lint-openapi-This is part of **`make verify`**.
+This is part of **`uv run make verify`**.🧰 Tools🪛 LanguageTool[style] ~25-~25: Consider using the synonym “brief” (= concise, using a few words, not lasting long) to strengthen your wording. (QUICK_BRIEF) [uncategorized] ~25-~25: The official name of this software platform is spelled with a capital “H”. (GITHUB) 🤖 Prompt for AI Agents |
||
|
|
||
| The rule **`oas3-valid-media-example`** (examples must match schemas) is **turned off** in **`.spectral.yaml`** because the generated spec carries many partial examples and produced hundreds of noisy warnings. Turn it back on when examples are brought in line with schemas. | ||
Uh oh!
There was an error while loading. Please reload this page.