feat(docs): OpenAPI spec sync with CI validation and PR previews#1550
feat(docs): OpenAPI spec sync with CI validation and PR previews#1550
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: c69b37a The changes in this PR will be included in the next version bump. This PR includes changesets to release 18 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📝 WalkthroughWalkthroughAdds OPENAPI_GENERATE_MODE to start ENSApi with a mock config exposing /openapi.json; a TypeScript CLI fetches, validates, formats and writes the spec; CI runs ENSApi in generate mode, polls Changes
Sequence Diagram(s)sequenceDiagram
participant GH as GitHub Actions
participant ENS as ENSApi (OPENAPI_GENERATE_MODE)
participant CLI as generate-openapi.ts
participant Repo as Repo (committed openapi.json)
participant Mint as Mintlify API
GH->>ENS: start ENSApi with OPENAPI_GENERATE_MODE=true
activate ENS
ENS->>ENS: load mock config, expose /openapi.json
GH->>CLI: run readiness loop (poll /openapi.json)
loop poll until ready or timeout
CLI->>ENS: GET /openapi.json
ENS-->>CLI: 200 + JSON
end
CLI->>CLI: validate JSON, format, write `docs/docs.ensnode.io/openapi.json`
CLI->>Repo: produce generated spec (in-memory)
GH->>GH: diff generated spec vs committed `docs/docs.ensnode.io/openapi.json`
alt specs match
GH->>Mint: submit spec for Mintlify validation
Mint-->>GH: validation result
else specs differ
GH->>GH: fail job
end
GH->>ENS: stop ENSApi
deactivate ENS
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR adds OpenAPI specification generation and documentation capabilities to the ENSNode project. It introduces a script to fetch and save the OpenAPI spec from a running ENSApi instance, integrates it with Mintlify documentation, and adds CI checks to ensure the spec stays in sync with production.
Changes:
- Added a 5,106-line OpenAPI specification file documenting all ENSApi endpoints
- Created a generation script to fetch and update the spec from a running instance
- Configured Mintlify docs to reference both production and local OpenAPI specs
- Added CI workflow to validate spec synchronization on the main branch
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/docs.ensnode.io/openapi.json | Complete OpenAPI 3.1.0 specification documenting all ENSApi endpoints including resolution, meta, explore, and ENSAwards APIs |
| apps/ensapi/scripts/generate-openapi.ts | TypeScript script to fetch OpenAPI spec from running instance and save to docs directory |
| apps/ensapi/package.json | Added npm script openapi:generate to run the generation script |
| docs/docs.ensnode.io/docs.json | Updated configuration to reference production API spec and added hidden preview section for local spec |
| .github/workflows/test_ci.yml | Added CI job to verify OpenAPI spec stays in sync with production on main branch |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Fix all issues with AI agents
In @.github/workflows/test_ci.yml:
- Around line 51-55: The openapi-sync-check job currently only runs when
github.ref == 'refs/heads/main', which lets PRs merge with out-of-sync specs;
update the condition on the openapi-sync-check job (the if: line) to also run
for pull requests (e.g., include github.event_name == 'pull_request' or
github.head_ref checks) and mark it non-blocking for PRs by using
continue-on-error: true (or alternatively remove the if entirely and rely on
branch protection or add contributor documentation). Target the job named
openapi-sync-check and the existing if: github.ref == 'refs/heads/main'
condition when making the change.
In `@apps/ensapi/scripts/generate-openapi.ts`:
- Around line 23-24: ensapiUrl may end with a trailing slash causing openapiUrl
to become "//openapi.json"; normalize ensapiUrl before composing openapiUrl (the
variables to change are ensapiUrl and openapiUrl in generate-openapi.ts) by
trimming any trailing '/' from ensapiUrl (or using a URL-safe join) so
openapiUrl is built as `${normalizedEnsapiUrl}/openapi.json` even when
ENSAPI_URL or process.argv[2] includes a trailing slash; ensure
DEFAULT_ENSAPI_URL remains fallback and normalization runs after selecting the
value.
- Line 12: Update the header comment string that reads "Writes openapi.json to
the docs directory for Mintilify" and correct the product name typo to
"Mintlify" so the comment reads "Writes openapi.json to the docs directory for
Mintlify"; locate this exact comment text in generate-openapi.ts and make the
single-word change.
- Around line 28-33: Add a timeout to the fetch in generate-openapi.ts by
creating an AbortSignal via AbortSignal.timeout(ms) and passing it as the signal
option to the fetch(openapiUrl) call; handle the abort case by catching the
thrown error (check for AbortError or error.name === 'AbortError') and log a
clear timeout message before exiting, and ensure the existing non-ok response
handling remains unchanged.
In `@docs/docs.ensnode.io/docs.json`:
- Around line 29-34: The docs.json "Preview" group references a non-existent
page "ensapi/preview"; fix by either adding a new page file named preview.mdx
under the docs/docs.ensnode.io/ensapi/ folder (so the path matches
"ensapi/preview") or remove the entire Preview group entry (the object with
"group": "Preview", "pages": ["ensapi/preview"], "openapi": "./openapi.json",
"hidden": true) from docs.json; update whichever you choose and ensure the
"pages" array references only existing MDX/MD files.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @.github/workflows/test_ci.yml:
- Around line 58-70: The CI step runs the openapi:generate npm script which
currently relies on a hardcoded production default; make the behavior explicit
by passing the production URL via the ENSAPI_URL env in the workflow step or by
updating the openapi:generate script to accept an ENSAPI_URL argument and
default it to https://api.alpha.ensnode.io; update the step that invokes
openapi:generate to export ENSAPI_URL or call the script with the URL so the
action is explicit and maintainable.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
lightwalker-eth
left a comment
There was a problem hiding this comment.
@notrab Thanks for updates. Reviewed and shared feedback 👍
| # ENS_HOLIDAY_AWARDS_END="2025-12-31T23:59:59Z" | ||
|
|
||
| # OpenAPI Generate Mode | ||
| # Optional. When set to "true", ENSApi starts with a minimal mock configuration, |
There was a problem hiding this comment.
Feedback:
- Please document specific references to each of the other environment variables that are ignored when this is set to true. Or, alternatively, document something like: causes all other environment variable configurations to be ignored except for X, Y, and Z as it might be easier to say what isn't ignored, than to make a big list of everything that is ignored.
- I believe it's important that when this environment variable is set, ENSApi should refuse to serve any route other than the route for the
openapi.jsonfile. I understand we can achieve this as follows:- Introduce some new "global" middleware, such as can be seen here.
- This new "global" middleware can have some simple logic:
- If this environment variable has been set and the route is not the route for the openapi.json file: return a HTTP 503 service unavailable error with some little message about how ENSApi was started in this OpenAPI generate mode and therefore only route X is available.
- Else: pass through the request.
- Update the docs for this environment variable to note how when it is set, all APIs return HTTP 503 service unavailable with the exception of route X to get the openapi.json file.
- The logic for how the "config" object in ENSApi is built should be refined. More specifically:
EnsApiConfig/EnsApiConfigSchemaas defined inapps/ensapi/src/config/config.schema.tsshould be updated to include a new boolean field named something likeinOpenApiGenerateMode. This should be implemented such that the value will befalseunless the related environment variable is explicitly set to "true". The logic in the new "global" middleware should then read from this variable to decide its behaviour.
There was a problem hiding this comment.
@lightwalker-eth great idea about the middleware. Makes things a bit simpler and more isolated, thanks!
| /** | ||
| * Environment variables for OpenAPI generation mode. | ||
| * | ||
| * When enabled, ENSApi starts with a minimal mock configuration, |
There was a problem hiding this comment.
Please see my related comment for how activating this flag should not only impact how ENSApi starts, but also how it handles all requests to all routes except for the route for the openapi.json file.
| * Mock configuration used exclusively for OpenAPI spec generation. | ||
| * | ||
| * When OPENAPI_GENERATE_MODE is enabled, ENSApi uses this mock config | ||
| * to start without requiring real database or indexer connections. |
There was a problem hiding this comment.
Please see my related comment for how activating this flag should not only impact how ENSApi starts, but also how it handles all requests to all routes except for the route for the openapi.json file.
| with: | ||
| slack_webhook: ${{ secrets.SLACK_WEBHOOK_URL }} | ||
| slack_title: "⚠️ Mintlify Docs Rebuild Failed" | ||
| slack_message: "Failed to trigger Mintlify docs rebuild during environment switch to ${{ inputs.target }}" |
There was a problem hiding this comment.
@notrab This is a nice suggestion from Copilot. Appreciate your advice.
| slack_webhook: ${{ secrets.SLACK_WEBHOOK_URL }} | ||
| slack_title: "⚠️ Mintlify Docs Rebuild Failed" | ||
| slack_message: "Failed to trigger Mintlify docs rebuild during environment switch to ${{ inputs.target }}" | ||
|
|
There was a problem hiding this comment.
@notrab I'd also like to see an additional separate Slack notification sent to notify us of successfully rebuilt Mintlify docs. This notification ideally should also include a reference to the specific URL to the OpenAPI.json that the new production Mintlify API docs were successfully built from.
Goal: Help everyone in our team build a stronger mental model for how all these pieces are working together.
|
|
||
| - name: Validate OpenAPI spec with Mintlify | ||
| run: pnpm dlx mintlify openapi-check docs/docs.ensnode.io/openapi.json | ||
|
|
There was a problem hiding this comment.
@notrab I like the idea of following this best practice as suggested by Copilot.
| - uses: actions/checkout@v4 | ||
| - uses: ./.github/actions/setup_node_environment | ||
|
|
||
| - name: Start ENSApi in OpenAPI generate mode |
There was a problem hiding this comment.
@notrab There's currently many ideas in this file (.github/workflows/test_ci.yml) for coordinating the whole process of updating the committed openapi spec. Could we move those ideas into some bash script or something that could not only be used in CI, but also be used locally in development? The goal here is to make it so that the instructions in the "Generating the Spec" section of docs/docs.ensnode.io/README.md could be made more simple so that it doesn't require multiple commands across separate terminals.
| --retry 2 \ | ||
| --retry-delay 5 \ | ||
| --request POST \ | ||
| --url "https://api.mintlify.com/v1/project/update/${{ vars.MINTLIFY_PROJECT_ID }}" \ |
There was a problem hiding this comment.
We need to implement this operation more defensively.
Specifically:
- When we request an update from Mintlify, we should capture the
statusIdfrom the response: https://www.mintlify.com/docs/api/update/trigger#response-status-id - the CI should then use https://www.mintlify.com/docs/api/update/status in a loop waiting for mintlify to respond with an appropriate status to identify if the redeployment was a success or failed. Then, depending on that outcome, send the appropriate messages to Slack.
There was a problem hiding this comment.
I love this thinking! Great idea
lightwalker-eth
left a comment
There was a problem hiding this comment.
@notrab One other suggestion.
| "group": "Preview", | ||
| "pages": ["ensapi/preview"], | ||
| "openapi": "/openapi.json", | ||
| "hidden": true |
There was a problem hiding this comment.
Please update the description of this PR to include a section for post-merge follow-up actions. This needs to include the following goal:
- Ensure that the "hidden" preview API docs remain truly hidden from search engines once we merge this PR. It's possible they are only hidden in preview environments but may not be hidden in production.
Co-authored-by: lightwalker.eth <126201998+lightwalker-eth@users.noreply.github.com>
Co-authored-by: lightwalker.eth <126201998+lightwalker-eth@users.noreply.github.com>
Co-authored-by: lightwalker.eth <126201998+lightwalker-eth@users.noreply.github.com>
Co-authored-by: lightwalker.eth <126201998+lightwalker-eth@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 17 changed files in this pull request and generated 1 comment.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Lite PR
Summary
openapi:generatescript to fetch and save OpenAPI spec from ENSApiopenapi.jsonstays in sync with productionWhy
Production API docs were getting out of sync with deployed API, and there was no way to preview API doc changes in PRs.
This setup ensures:
Testing
pnpm --filter ensapi openapi:generatelocally to verify spec generationNotes for Reviewer (Optional)
Pre-Review Checklist (Blocking)