-
Notifications
You must be signed in to change notification settings - Fork 0
ci: deterministic docs checks to replace Mintlify Automate workflows #15
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
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,11 @@ | ||
| extends: existence | ||
| message: "Avoid '%s' as link text — use descriptive link text (STYLE_GUIDE.md)." | ||
| link: https://github.com/sei-protocol/sei-docs/blob/main/STYLE_GUIDE.md | ||
| level: warning | ||
| ignorecase: true | ||
| # STYLE_GUIDE.md: links should be descriptive — "click here" / "[here]" tell | ||
| # the reader nothing about where they're going. | ||
| tokens: | ||
| - 'click here' | ||
| - '\[here\]\(' | ||
| - '\[this link\]\(' | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| extends: capitalization | ||
| message: "Use sentence case for headings: '%s'." | ||
| link: https://github.com/sei-protocol/sei-docs/blob/main/AGENTS.md | ||
| level: warning | ||
| scope: heading | ||
| # AGENTS.md: "Sentence case for headings." Only the first word and proper nouns | ||
| # are capitalized. Proper nouns below are exempt so they may appear mid-heading. | ||
| match: $sentence | ||
| exceptions: | ||
| - Sei | ||
| - Sei Giga | ||
| - Sei EVM | ||
| - Sei Network | ||
| - SeiDB | ||
| - EVM | ||
| - CosmWasm | ||
| - Cosmos | ||
| - Ethereum | ||
| - Solidity | ||
| - Hardhat | ||
| - Foundry | ||
| - MetaMask | ||
| - Compass | ||
| - Rabby | ||
| - Ledger | ||
| - Twin Turbo Consensus | ||
| - Autobahn | ||
| - Pectra | ||
| - RPC | ||
| - API | ||
| - CLI | ||
| - SDK | ||
| - NFT | ||
| - IBC | ||
| - VRF | ||
| - JSON | ||
| - RocksDB | ||
| - StateSync | ||
| - IPv4 | ||
| - IPv6 | ||
| - I |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| extends: existence | ||
| message: "'%s' is often unnecessary qualifying language — consider removing it." | ||
| link: https://github.com/sei-protocol/sei-docs/blob/main/STYLE_GUIDE.md | ||
| level: suggestion | ||
| ignorecase: true | ||
| # STYLE_GUIDE.md: "Avoid qualifying language, which is quite often completely | ||
| # unnecessary." Suggestion-level — informational, never blocks a PR. | ||
| tokens: | ||
| - very | ||
| - really | ||
| - quite | ||
| - simply | ||
| - completely | ||
| - totally | ||
| - basically | ||
| - essentially | ||
| - obviously | ||
| - of course |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| extends: substitution | ||
| message: "Use '%s' instead of '%s' (Sei terminology)." | ||
| link: https://github.com/sei-protocol/sei-docs/blob/main/AGENTS.md | ||
| level: warning | ||
| ignorecase: false | ||
| action: | ||
| name: replace | ||
| # observed (wrong) form : preferred form. Patterns are written so the correct | ||
| # spelling never matches itself. | ||
| swap: | ||
| 'the Sei blockchain': Sei | ||
| 'Sei [Cc]hain': Sei | ||
| 'gas fees?': gas | ||
| '\bCW\b': CosmWasm | ||
| '[Cc]osmwasm': CosmWasm | ||
| '[Mm]etamask': MetaMask | ||
| 'Sei-?[Jj][Ss]': sei-js | ||
| 'seijs': sei-js |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| Sei | ||
| seid | ||
| sei-js | ||
| SeiDB | ||
| Sei Giga | ||
| CosmWasm | ||
| Cosmos | ||
| Tendermint | ||
| CometBFT | ||
| Autobahn | ||
| Pectra | ||
| Mintlify | ||
| MetaMask | ||
| Compass | ||
| Rabby | ||
| Hardhat | ||
| Foundry | ||
| Solidity | ||
| wagmi | ||
| viem | ||
| ethers | ||
| RainbowKit | ||
| Ankr | ||
| DRPC | ||
| Nirvana | ||
| Takara | ||
| Citrex | ||
| Symphony | ||
| DragonSwap | ||
| Cambrian | ||
| precompile | ||
| precompiles | ||
| mempool | ||
| calldata | ||
| multicall | ||
| statesync | ||
| gigagas | ||
| dApp | ||
| dApps |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| name: External link check | ||
|
|
||
| # Scheduled check for external link rot (dead third-party URLs) with lychee — | ||
| # the free, no-AI complement to the existing link-check workflow (which runs | ||
| # `mint broken-links` for internal links). Config lives in lychee.toml. On | ||
| # failure it opens/updates a tracking issue instead of blocking any PR. | ||
| # | ||
| # Triggers: | ||
| # - workflow_dispatch (manual) | ||
| # - schedule (weekly, Mondays 09:00 UTC) | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| schedule: | ||
| - cron: '0 9 * * 1' | ||
|
|
||
| permissions: | ||
| contents: read | ||
| issues: write | ||
|
|
||
| defaults: | ||
| run: | ||
| shell: bash | ||
|
|
||
| jobs: | ||
| lychee: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 15 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Check external links | ||
| id: lychee | ||
| uses: lycheeverse/lychee-action@v2 | ||
| with: | ||
| args: "--config lychee.toml --no-progress '**/*.md' '**/*.mdx'" | ||
| fail: false | ||
| format: markdown | ||
| output: ./lychee-report.md | ||
|
|
||
| - name: Open or update tracking issue on broken links | ||
| if: steps.lychee.outputs.exit_code != 0 | ||
| uses: peter-evans/create-issue-from-file@v5 | ||
| with: | ||
| title: 🔗 Broken external links detected | ||
| content-filepath: ./lychee-report.md | ||
| labels: broken-links, automated |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| name: Prose style | ||
|
|
||
| # Advisory prose/style linting on PRs — the free, no-AI replacement for | ||
| # Mintlify's "Apply style guide" workflow and the grammar half of "Fix grammar | ||
| # & typos". Rules live in .github/styles/Sei (derived from AGENTS.md and | ||
| # STYLE_GUIDE.md). Annotations are posted on *changed lines only* and never | ||
| # fail the build, so the existing heading backlog doesn't create noise. | ||
|
|
||
| on: | ||
| pull_request: | ||
|
|
||
| permissions: | ||
| contents: read | ||
| checks: write | ||
| pull-requests: read | ||
|
|
||
| defaults: | ||
| run: | ||
| shell: bash | ||
|
|
||
| jobs: | ||
| vale: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Vale | ||
| uses: errata-ai/vale-action@v2 | ||
| with: | ||
| version: 3.14.2 | ||
| reporter: github-pr-check | ||
| filter_mode: added | ||
| fail_on_error: false | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| name: SEO audit | ||
|
|
||
| # Deterministic SEO + page-structure audit on every PR — the free, no-AI | ||
| # replacement for Mintlify's "Audit SEO metadata" workflow. Walks docs.json so | ||
| # it only checks published pages. Fails only on missing title/description | ||
| # (regressions); length/heading issues are warnings. See scripts/audit-seo.mjs. | ||
|
|
||
| on: | ||
| pull_request: | ||
| workflow_dispatch: | ||
|
|
||
| defaults: | ||
| run: | ||
| shell: bash | ||
|
|
||
| jobs: | ||
| audit: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up Node | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version-file: '.nvmrc' | ||
|
|
||
| - name: Audit SEO metadata and structure | ||
| run: node scripts/audit-seo.mjs |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| name: Spelling | ||
|
|
||
| # Deterministic spell-check on every PR — the free, no-AI replacement for the | ||
| # spelling half of Mintlify's "Fix grammar & typos" workflow. Config + the | ||
| # allowlist of protocol terms live in _typos.toml. | ||
|
|
||
| on: | ||
| pull_request: | ||
| workflow_dispatch: | ||
|
|
||
| defaults: | ||
| run: | ||
| shell: bash | ||
|
|
||
| jobs: | ||
| typos: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Check spelling | ||
| uses: crate-ci/typos@master | ||
|
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. Unpinned GitHub Action uses mutable branch referenceMedium Severity
Reviewed by Cursor Bugbot for commit fc0ec5d. Configure here. |
||
| with: | ||
| config: _typos.toml | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # Vale configuration — https://vale.sh | ||
| # Free, deterministic prose/style linting in CI: the no-AI replacement for | ||
| # Mintlify's "Apply style guide" workflow and the grammar half of "Fix grammar | ||
| # & typos". Rules in .github/styles/Sei are derived from AGENTS.md and | ||
| # STYLE_GUIDE.md. Spelling is handled by `typos` (see _typos.toml), so Vale's | ||
| # own spell-checker is disabled here to avoid double-reporting. | ||
|
|
||
| StylesPath = .github/styles | ||
| MinAlertLevel = suggestion | ||
|
|
||
| Vocab = Sei | ||
|
|
||
| # Lint MDX as Markdown. | ||
| [formats] | ||
| mdx = md | ||
|
|
||
| [*.{md,mdx}] | ||
| # Only the Sei style. typos owns spelling, and Vale's built-in Repetition rule | ||
| # false-positives on fenced code nested inside MDX/JSX components (e.g. a `bash` | ||
| # block inside <Accordion>), so we don't enable the bundled `Vale` style. | ||
| BasedOnStyles = Sei | ||
|
|
||
| # Skip MDX/JSX so Vale lints prose, not markup: | ||
| # - {expression} braces (e.g. cols={2}, {/* comments */}) | ||
| # - import / export statements at the top of MDX files | ||
| TokenIgnores = (\{[^}]*\}) | ||
| BlockIgnores = (?m)^(?:import|export) .*$ | ||
|
|
||
| # Deprecated section (SIP-3) — don't lint it. | ||
| [cosmos-sdk/**] | ||
| BasedOnStyles = '' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # typos configuration — https://github.com/crate-ci/typos | ||
| # Free, deterministic spell-checking in CI: the no-AI replacement for the | ||
| # spelling half of Mintlify's "Fix grammar & typos" workflow. | ||
| # | ||
| # typos only flags *known* misspellings (not every unknown word), so the | ||
| # false-positive surface is small — the [default.extend-words] list below | ||
| # allowlists the few protocol terms it would otherwise "correct". | ||
|
|
||
| [files] | ||
| extend-exclude = [ | ||
| "llms.txt", | ||
| "llms-full.txt", | ||
| "*.lock", | ||
| "package-lock.json", | ||
| "pnpm-lock.yaml", | ||
| "yarn.lock", | ||
| "assets/**", | ||
| "logo/**", | ||
| "favicons/**", | ||
| "*.svg", | ||
| "*.min.js", | ||
| "cosmos-sdk/**", | ||
| "google*.html", # Google Search Console site-verification tokens | ||
| ] | ||
|
|
||
| [default] | ||
| # Don't treat hex addresses / hashes as words to be spell-checked. | ||
| extend-ignore-re = ['0x[0-9a-fA-F]{6,}'] | ||
|
|
||
| [default.extend-identifiers] | ||
| # "UPnP" is a real protocol name; typos splits it and flags the "Pn". | ||
| # It appears in the auto-generated config block in node/node-operators.mdx. | ||
| UPnP = "UPnP" | ||
|
|
||
| [default.extend-words] | ||
| # Allowlist (word = same word). Populated from a real `typos` run over the repo. | ||
| # "maxiumum" is an upstream typo in CometBFT's config.toml comments, inlined by | ||
| # scripts/sync-default-configs.mjs — fixing it here would be reverted on re-sync. | ||
| maxiumum = "maxiumum" |


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Vale existence tokens can't match raw markdown syntax
Low Severity
The tokens
'\[here\]\('and'\[this link\]\('attempt to match raw markdown link syntax like[here](url). However, Vale'sexistenceextension operates on the processed text scope by default, not raw markup. Vale strips markdown syntax before matching, so the brackets and parentheses in these patterns will never appear in the text being checked, making both tokens effectively dead. The first token'click here'works fine since it's plain text. To catch standalone[here](…)links, ascope: rawdirective or a different rule extension would be needed.Reviewed by Cursor Bugbot for commit fc0ec5d. Configure here.