Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/test_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,33 @@
- uses: ./.github/actions/setup_node_environment
- run: pnpm test

openapi-sync-check:
name: "OpenAPI Spec Sync Check"
runs-on: blacksmith-4vcpu-ubuntu-2204
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup_node_environment
- name: Generate OpenAPI spec
run: pnpm generate:openapi
- name: Verify spec is in sync
run: |
if ! git diff --quiet docs/docs.ensnode.io/ensapi-openapi.json || \
! git ls-files --error-unmatch docs/docs.ensnode.io/ensapi-openapi.json >/dev/null 2>&1; then
echo "Error: OpenAPI spec is out of sync"
echo ""
echo "The committed ensapi-openapi.json differs from what the code generates:"
echo ""
git diff --color docs/docs.ensnode.io/ensapi-openapi.json
echo ""
echo "To fix, run: pnpm generate:openapi"
echo "Then commit the updated ensapi-openapi.json."
exit 1
fi
echo "OpenAPI spec is in sync with codebase"
- name: Validate OpenAPI spec with Mintlify
run: pnpm dlx mint@^4.1.0 openapi-check docs/docs.ensnode.io/ensapi-openapi.json

integrity-check:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium test

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
name: "Integrity Check"
runs-on: blacksmith-4vcpu-ubuntu-2204
services:
Expand Down
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,42 @@ ENSNode is a modern, multichain indexer for ENS. It supports backwards-compatibl

Documentation for the ENSNode suite of apps is available at [ensnode.io](https://ensnode.io).

## API Reference

The API Reference is generated from an OpenAPI spec. Two sources are used depending on context:

| Context | OpenAPI Source | Page |
| --------------- | ------------------------------------------- | --------------------------------------------------------------- |
| **Production** | Fetched from `https://api.alpha.ensnode.io` | API Reference |
| **PR Previews** | Committed `openapi.json` file | [Preview page](https://docs.ensnode.io/ensapi/preview) (hidden) |

This means production docs always reflect the live API, while PR previews can show upcoming API changes before they're deployed.

Mintlify deploys automatically: preview deploys on each branch, production deploys on merge to `main`.

| Content Type | Source | Behavior |
| ----------------- | ------------------ | ------------------------------------------- |
| **API Reference** | Production API URL | Always in sync with deployed production API |
| **Other docs** | Committed files | Deploys immediately on merge to main |

Non-API documentation (guides, concepts, etc.) may be published before the corresponding code is released to production. The API Reference always reflects the actual production API since Mintlify fetches it from the production URL at build time.

## OpenAPI Spec Sync Check

On every PR, CI runs an `openapi-sync-check` job that:

1. Regenerates the OpenAPI spec from the ENSApi route definitions by running `pnpm generate:openapi`
2. Compares the freshly generated spec against the committed [`ensapi-openapi.json`](docs/docs.ensnode.io/ensapi-openapi.json), failing with a diff if they don't match
3. Validates that Mintlify can parse the spec with `openapi-check`

If you modify any API route schemas in `apps/ensapi`, you must regenerate and commit the updated spec:

```sh
pnpm generate:openapi
```

Then commit the updated `docs/docs.ensnode.io/ensapi-openapi.json`.

## Contributions

We welcome community contributions and feedback—please see [CONTRIBUTING.md](CONTRIBUTING.md) for more information.
Expand Down
57 changes: 34 additions & 23 deletions docs/docs.ensnode.io/ensapi-openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"openapi": "3.1.0",
"info": {
"title": "ENSApi APIs",
"version": "1.5.1",
"version": "1.6.0",
"description": "APIs for ENS resolution, navigating the ENS nameforest, and metadata about an ENSNode"
},
"servers": [
Expand Down Expand Up @@ -101,6 +101,34 @@
"ensIndexerPublicConfig": {
"type": "object",
"properties": {
"databaseSchemaName": { "type": "string", "minLength": 1 },
"ensRainbowPublicConfig": {
"type": "object",
"properties": {
"version": { "type": "string", "minLength": 1 },
"labelSet": {
"type": "object",
"properties": {
"labelSetId": {
"type": "string",
"minLength": 1,
"maxLength": 50,
"pattern": "^[a-z-]+$"
},
"highestLabelSetVersion": { "type": ["number", "null"] }
},
"required": ["labelSetId", "highestLabelSetVersion"]
},
"recordsCount": { "type": "integer", "minimum": 0 }
},
"required": ["version", "labelSet", "recordsCount"]
},
"indexedChainIds": {
"type": "array",
"items": { "type": "integer", "exclusiveMinimum": 0 },
"minItems": 1
},
"isSubgraphCompatible": { "type": "boolean" },
"labelSet": {
"type": "object",
"properties": {
Expand All @@ -114,12 +142,6 @@
},
"required": ["labelSetId", "labelSetVersion"]
},
"indexedChainIds": {
"type": "array",
"items": { "type": "integer", "exclusiveMinimum": 0 },
"minItems": 1
},
"isSubgraphCompatible": { "type": "boolean" },
"namespace": {
"type": "string",
"enum": ["mainnet", "sepolia", "sepolia-v2", "ens-test-env"]
Expand All @@ -129,37 +151,26 @@
"items": { "type": "string" },
"minItems": 1
},
"databaseSchemaName": { "type": "string", "minLength": 1 },
"versionInfo": {
"type": "object",
"properties": {
"nodejs": { "type": "string", "minLength": 1 },
"ponder": { "type": "string", "minLength": 1 },
"ensDb": { "type": "string", "minLength": 1 },
"ensIndexer": { "type": "string", "minLength": 1 },
"ensNormalize": { "type": "string", "minLength": 1 },
"ensRainbow": { "type": "string", "minLength": 1 },
"ensRainbowSchema": { "type": "integer", "exclusiveMinimum": 0 }
"ensNormalize": { "type": "string", "minLength": 1 }
},
"required": [
"nodejs",
"ponder",
"ensDb",
"ensIndexer",
"ensNormalize",
"ensRainbow",
"ensRainbowSchema"
],
"additionalProperties": false
"required": ["nodejs", "ponder", "ensDb", "ensIndexer", "ensNormalize"]
}
},
"required": [
"labelSet",
"databaseSchemaName",
"ensRainbowPublicConfig",
"indexedChainIds",
"isSubgraphCompatible",
"labelSet",
"namespace",
"plugins",
"databaseSchemaName",
"versionInfo"
]
}
Expand Down
Loading