-
Notifications
You must be signed in to change notification settings - Fork 1
Vale #14
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?
Vale #14
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,73 @@ | ||
| name: Vale documentation lint | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| filepaths: | ||
| description: "Comma- or newline-separated Markdown/MDX globs to lint." | ||
| required: false | ||
| type: string | ||
| default: | | ||
| **/*.md | ||
| **/*.mdx | ||
| fail_on_error: | ||
| description: "Set to true to fail CI when Vale reports errors." | ||
| required: false | ||
| type: boolean | ||
| default: false | ||
| docs_template_ref: | ||
| description: "docs-template ref to use as the Vale source of truth." | ||
| required: false | ||
| type: string | ||
| default: main | ||
|
|
||
| jobs: | ||
| vale: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| pull-requests: read | ||
| steps: | ||
| - name: Checkout caller repository | ||
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | ||
| with: | ||
| fetch-depth: 0 | ||
| persist-credentials: false | ||
|
|
||
| - name: Checkout central Vale configuration | ||
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | ||
| with: | ||
| repository: tetherto/docs-template | ||
| ref: ${{ inputs.docs_template_ref }} | ||
| path: .tether-vale-source | ||
| persist-credentials: false | ||
|
|
||
| - name: Detect changed documentation files | ||
| id: changed-files | ||
| uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323 # v47.0.5 | ||
| with: | ||
| path: "." | ||
| files: ${{ inputs.filepaths }} | ||
| separator: "," | ||
|
|
||
| - name: List changed documentation files | ||
| if: steps.changed-files.outputs.any_changed == 'true' | ||
| run: | | ||
| echo "The following files were detected for Vale:" | ||
| echo "${{ steps.changed-files.outputs.all_changed_files }}" | ||
|
|
||
| - name: Set up Python for Vale | ||
| if: steps.changed-files.outputs.any_changed == 'true' | ||
| uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v6 | ||
| with: | ||
| python-version: "3.12" | ||
|
|
||
| - name: Vale | ||
| if: steps.changed-files.outputs.any_changed == 'true' | ||
| uses: errata-ai/vale-action@d89dee975228ae261d22c15adcd03578634d429c # v2.1.1 | ||
| with: | ||
| files: ${{ steps.changed-files.outputs.all_changed_files }} | ||
| vale_flags: "--config .tether-vale-source/.vale.ini" | ||
| fail_on_error: ${{ inputs.fail_on_error }} | ||
| reporter: github-pr-check | ||
| separator: "," | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| # Vale configuration | ||
| # See vale_styles/README.md file for details and licensing information | ||
|
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. Shouldn't this README be part of the PR? |
||
|
|
||
| # Styles directory for all packages and config (vocab) files | ||
|
|
||
| StylesPath = ./styles | ||
|
|
||
| # The ignore config references project-words.txt | ||
|
|
||
| Spelling.Ignore = config/ignore/Tether-common | ||
|
|
||
|
|
||
| # Packages to sync with. Remember never adapt the external packages, all changes will be lost on update | ||
|
|
||
| Packages = Google, proselint, write-good | ||
|
|
||
| Vocab = Tether-common | ||
|
|
||
| # The minimum alert level to display (suggestion, warning, or error). | ||
| # Builds not set to fail too many false positives | ||
| MinAlertLevel = warning | ||
|
|
||
| # Treat .mdx files as Markdown so Vale can apply Markdown rules and styles. | ||
| # This does NOT automatically make Vale lint .mdx files; it only defines | ||
| # how .mdx files are parsed once they are matched by a glob below. | ||
|
|
||
| [formats] | ||
| mdx = md | ||
|
|
||
| # Apply Markdown linting rules to both .md and .mdx files. | ||
| # Note: Vale only runs rules on files that match a section glob. | ||
| # Including .mdx here is required; the [formats] mapping alone is not sufficient. | ||
| # Global settings (applied to every syntax) | ||
|
|
||
| [*.{md,mdx}] | ||
|
|
||
| # ignore includes and latex math code | ||
| TokenIgnores = ({![^!}]+!}),\ | ||
| (\$[^\n$`]+\$),\ | ||
| (\$\$[^$`]+\$\$),\ | ||
| (\$\{\{[^}]+\}\}),\ | ||
| ({%[^}]+%}),\ | ||
| ({{[^}]+}}),\ | ||
| (\+\+[A-Za-z]+\+[A-Za-z0-9]+\+\+),\ | ||
| (:[a-z\-]+:),\ | ||
| (^\s*import\s.+\s+from\s+.+$),\ | ||
| (^\s*export\s.+$),\ | ||
| (^\s*<img\b.*$),\ | ||
| (^\s*style=\{\{.*\}\}.*$),\ | ||
| (^\s*src=\{.*\}.*$),\ | ||
| (^\s*\/>\s*$),\ | ||
| (\bPolyfill\b),\ | ||
| (\[!(?:NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]),\ | ||
| ([Pp]ower meters) | ||
|
|
||
| # Ignore MDX import/export lines (React code). | ||
| BlockIgnores = (?m)^\s*import\s+[^\n]*$,\ | ||
| (?m)^\s*export\s+[^\n]*$ | ||
|
|
||
| # List of styles to load | ||
|
|
||
| BasedOnStyles = Tether, Vale, Google, proselint, write-good | ||
|
|
||
| # Allows Tether Headings to take precedence | ||
| Google.Headings = NO | ||
|
|
||
| # Allows using first-person plural like 'We' | ||
| Google.We = NO | ||
| Google.FirstPerson = NO | ||
|
|
||
| # Acronyms are replaced by the Tether list | ||
| Google.Acronyms = NO | ||
|
|
||
| # General terminology preferences are replaced by custom terms | ||
| Google.WordList = NO | ||
|
|
||
| # Quiet quotes: too many false positives | ||
| Google.Quotes = NO | ||
|
|
||
| # Quiet contractions: too many positives | ||
| Google.Contractions = NO | ||
|
|
||
| # Quiet dashes: spaces around em dashes are acceptable | ||
| Google.EmDash = NO | ||
|
|
||
| # Quiet foreign phrases: 'e.g.'/'i.e.' are acceptable in technical docs | ||
| Google.Latin = NO | ||
|
|
||
| # Quiet ellipses: literal '...' is acceptable in technical docs | ||
| Google.Ellipses = NO | ||
|
|
||
| # Allows proselint.Cliches to take precedence | ||
| write-good.Cliches = NO | ||
|
|
||
| # Quiet weasel: is replaced by Tether list | ||
| write-good.Weasel = NO | ||
|
|
||
| # Quiet E-Prime: too many false positives | ||
| write-good.E-Prime = NO | ||
|
|
||
| # Allows Vale.Repetition to take precedence | ||
| write-good.Illusions = NO | ||
|
|
||
| # Quiet too wordy: too many false positives | ||
| write-good.TooWordy = NO | ||
|
|
||
| # Allows write-good passive voice to take precedence | ||
| Google.Passive = NO | ||
| write-good.Passive = NO | ||
|
|
||
| proselint.Hyperbole = warning | ||
|
|
||
| # Quiet typography: literal '...' and straight quotes are acceptable | ||
| proselint.Typography = NO | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -221,7 +221,7 @@ Maintainers decide the final merge strategy. Prefer small, focused pull requests | |||||
| - Use clear MDX headings, stable links, and concise examples | ||||||
| - Keep SEO metadata current when adding or moving docs pages | ||||||
| - Avoid adding new abstractions unless they reduce real duplication or match an existing local pattern | ||||||
| - You may follow this opinionated style guide | ||||||
| - You MAY follow this [opinionated style guide](#opinionated-style-guide) | ||||||
|
|
||||||
| ## Issues and security | ||||||
|
|
||||||
|
|
@@ -239,25 +239,20 @@ Happy contributing, and thanks for helping improve `docs-template`. | |||||
|
|
||||||
| ### Overview | ||||||
|
|
||||||
| Google developer style | ||||||
| US English | ||||||
| Bullet lists no stop (- Avalon not - Avalon.) | ||||||
| Numbered lists stop | ||||||
| Diataxis ia | ||||||
| No positional references ("Swap the filename for any other model from the table” NOT "Swap the filename for any other model from the table above”) | ||||||
|
|
||||||
| ### Frontmatter and linking strategy | ||||||
|
|
||||||
| Links are from relevant text NOT "see ..." (do "The [Worker install pattern][install-pattern] defines the per-Worker mechanics." NOT "See the Worker [install pattern][install-pattern] for the per-Worker mechanics.") | ||||||
|
|
||||||
| Ask maintainer if the page you are building is to be ported to `tether.io`, if so follow reference-style link definitions plus routing comments: | ||||||
|
|
||||||
| /mdk-prv/docs/reference/maintainers/port-signals.md | ||||||
|
Comment on lines
-249
to
-255
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. Why did we remove this? |
||||||
| - [Google developer style](https://developers.google.com/style) | [Vale](./README.md#vale-linting) lints per this guide | ||||||
| - US English | ||||||
| - Bullet lists no stop (- Avalon not - Avalon.) | ||||||
| - Numbered lists stop | ||||||
| - Diataxis ia | ||||||
|
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.
Suggested change
|
||||||
| - No positional references ("Swap the filename for any other model from the table” NOT "Swap the filename for any other model from the table above”) | ||||||
| - Links from relevent text NOT "see ..." (do "The [Worker install pattern][install-pattern] defines the per-Worker mechanics." NOT "See the Worker [install pattern][install-pattern] for the per-Worker mechanics.") | ||||||
|
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.
Suggested change
|
||||||
| - Restrict line length to ~150 chars | ||||||
|
|
||||||
| ### Fixed sections, in order | ||||||
|
|
||||||
| 1. `## Overview` — one paragraph or `## How it works`+ "This page ... | ||||||
| 2. `## Next steps` — bullet list, each item `Description — [link](path)` | ||||||
| 1. `## Overview` or `## How it works`— one paragraph or sentence "This page ..." clarifying page's purpose | ||||||
|
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.
Suggested change
|
||||||
| 2. Body content | ||||||
| 3. Help the user discover more `## Next steps` — bullet list, each item `Description — [link](path)` | ||||||
|
|
||||||
| ### Admonitions | ||||||
|
|
||||||
|
|
@@ -293,7 +288,6 @@ This is a **success** callout — use for success messages. | |||||
| This is an **idea** callout — use for tips or suggestions. | ||||||
| </Callout> | ||||||
|
|
||||||
|
|
||||||
| ### Code blocks | ||||||
|
|
||||||
| - Always fenced with language tag (`bash`, `js`, etc.) except terminal session output which uses plain ` ``` ` | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| # DOCS docs | ||
| # Tether.to documentation template site | ||
|
|
||
| [This site](https://github.com/tetherto/docs-template.git) is the official documentation and single source of truth for the `tether.io` Documentation guild: | ||
|
|
||
|
|
@@ -7,6 +7,20 @@ | |
|
|
||
| The site is a **static export** from a Next.js + [Fumadocs](https://fumadocs.dev) app (`output: 'export'`). SEO behavior is implemented with workspace packages under `@tether/docs-*` (see below). | ||
|
|
||
| ## Table of contents | ||
|
|
||
| - [Installation](#installation) | ||
| - [Monorepo packages (`packages/`)](#monorepo-packages-packages) | ||
| - [Using these packages from another repository](#using-these-packages-from-another-repository) | ||
| - [SEO and frontmatter](#seo-and-frontmatter) | ||
| - [Environment variables](#environment-variables) | ||
| - [Open Graph images (Takumi, static hosting)](#open-graph-images-takumi-static-hosting) | ||
| - [Development](#development) | ||
| - [Vale linting](#vale-linting) | ||
| - [Maintainers](#maintainers) | ||
| - [Build](#build) | ||
| - [Repository layout](#repository-layout) | ||
|
|
||
| ## Installation | ||
|
|
||
| Prerequisites: | ||
|
|
@@ -76,7 +90,7 @@ Important: **set an expiration on the token.** Tokens that never expire are reje | |
|
|
||
| After creating the token, if the `tetherto` organization uses SSO, click **"Configure SSO"** next to the token in the tokens list and authorize it for the org. Without that step the registry returns `403` even with the right scopes. | ||
|
|
||
| A fine-grained personal access token also works, scoped to the `tetherto` resource owner with **Packages: Read** repository permission. Same expiration requirement applies. | ||
| A fine-grained personal access token also works, scoped to the `tetherto` resource owner with **Packages read** repository permission. Same expiration requirement applies. | ||
|
|
||
| #### 3. Save the token locally | ||
|
|
||
|
|
@@ -92,7 +106,7 @@ npm whoami --registry=https://npm.pkg.github.com # should print your GitHub us | |
| npm view @tetherto/docs-seo-schema version --registry=https://npm.pkg.github.com | ||
| ``` | ||
|
|
||
| If `npm whoami` prints your username but the second command 403s, the token authenticates but lacks `read:packages` (and/or SSO authorization). | ||
| If `npm whoami` prints your username but the second command returns HTTP 403, the token authenticates but lacks `read:packages` (and/or SSO authorization). | ||
|
|
||
| #### 5. Install | ||
|
|
||
|
|
@@ -121,7 +135,7 @@ Extended fields are merged in [`source.config.ts`](source.config.ts) via `tether | |
|
|
||
| Per-page metadata, sitemap, robots, and JSON-LD share the same logic through [`src/lib/seo-config.ts`](src/lib/seo-config.ts) and `@tether/docs-seo-next`. | ||
|
|
||
| During `next build` / dev, `getPageSeoState` and `buildDocsMetadata` emit **`[@tether/docs-seo]`** `console.warn` lines for missing optional fields (`ogImage`, `schemaType`, `docType`, `lastModified`, and empty `description` if it bypasses MDX validation). Warnings are deduped per page per Node process. Two env knobs control them: | ||
| During `next build` / dev, `getPageSeoState` and `buildDocsMetadata` emit **`[@tether/docs-seo]`** `console.warn` lines for missing optional fields (`ogImage`, `schemaType`, `docType`, `lastModified`, and empty `description` if it bypasses MDX validation). Warnings are deduplicated per page per Node process. Two env knobs control them: | ||
|
|
||
| - **`DOCS_SEO_SILENT=1`** — silence ALL warnings (including the required-`description` warning). Use sparingly. | ||
| - **`DOCS_SEO_QUIET_GENERATED=1`** — silence only the warnings for fields that have sensible auto-generated/inferred defaults (`ogImage`, `schemaType`, `lastModified`). `description` and `docType` warnings stay loud because neither has a useful default. Recommended when you opt into the Takumi OG prebuild + the `fumadocs-mdx` `lastModified` plugin. | ||
|
|
@@ -162,10 +176,39 @@ Because static export cannot use dynamic OG Route Handlers, images are **generat | |
| - Run the generator alone: **`npm run build:og`** | ||
| - Replace [`public/og-default.png`](public/og-default.png) with a proper **1200×630** asset if you rely on the `SKIP_OG_BUILD` fallback | ||
|
|
||
| **Git:** This template **gitignores** `public/og/docs/` (see [`.gitignore`](.gitignore)). CI and local **`npm run build`** must run **`prebuild`** so those WebP files exist before static export. To vendor generated images instead, stop ignoring that directory and commit the files. | ||
| **Git note:** this template **gitignores** `public/og/docs/` (see [`.gitignore`](.gitignore)). CI and local **`npm run build`** must run **`prebuild`** so those WebP files exist before static export. To vendor generated images instead, stop ignoring that directory and commit the files. | ||
|
|
||
| ## Development | ||
|
|
||
| ### Vale linting | ||
|
|
||
| Vale is available for local documentation linting. Run `vale sync` before linting so Vale downloads the configured package styles into the gitignored `styles/` package directories. | ||
|
|
||
| Use the project vocabulary to check custom spelling. For example, Tether should pass, while Tehtr should fail. | ||
|
|
||
|
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. a short install vale snippet may be helpful here. |
||
| Run Vale against a single file: | ||
|
|
||
| ```bash | ||
| vale sync | ||
| vale README.md | ||
| ``` | ||
|
|
||
| Run Vale against a single folder: | ||
|
|
||
| ```bash | ||
| vale sync | ||
| vale content/docs | ||
| ``` | ||
|
|
||
| Run Vale against the entire repo: | ||
|
|
||
| ```bash | ||
| vale sync | ||
| vale . | ||
| ``` | ||
|
|
||
| Vale can be added to CI as an advisory check, but do not configure it to fail CI. The current rule set has too many false positives for a hard gate. | ||
|
|
||
| Check broken links: | ||
|
|
||
| ```bash | ||
|
|
@@ -184,6 +227,37 @@ For local dev without generating OG files, you can use: | |
| SKIP_OG_BUILD=1 npm run dev | ||
| ``` | ||
|
|
||
| ## Maintainers | ||
|
|
||
| ### Using Vale in downstream CI | ||
|
|
||
| This repository is the source of truth for Tether Vale configuration. Downstream documentation repositories should not copy `.vale.ini` or `styles/`; they can call this repository's reusable workflow instead. | ||
|
|
||
| Add a workflow like this to the downstream repository: | ||
|
|
||
| ```yaml | ||
| name: Vale documentation lint | ||
|
|
||
| on: | ||
| pull_request: | ||
| paths: | ||
| - "**/*.md" | ||
| - "**/*.mdx" | ||
|
|
||
| jobs: | ||
| vale: | ||
| uses: tetherto/docs-template/.github/workflows/vale-docs.yml@main | ||
| with: | ||
| filepaths: | | ||
| **/*.md | ||
| **/*.mdx | ||
| fail_on_error: false | ||
| ``` | ||
|
|
||
| The reusable workflow checks out the downstream repository, checks out this template beside it, detects changed Markdown and MDX files, and runs Vale with this repository's [`.vale.ini`](.vale.ini) and [`styles/`](styles/) configuration. `fail_on_error` defaults to `false` because Vale has too many false positives for a hard CI gate; set it to `true` only after the downstream repository has cleaned up or accepted the rule set. | ||
|
|
||
| Synced package styles such as Google, `proselint`, and `write-good` are generated by `vale sync` during the workflow run. Do not commit those generated package directories to downstream repositories. | ||
|
|
||
| ## Build | ||
|
|
||
| Set **`NEXT_PUBLIC_DOCS_ORIGIN`** for production; add **`NEXT_PUBLIC_INKEEP_API_KEY`** only if you use Inkeep instead of default Fumadocs search (see [`env.example`](env.example)). | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
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.
Why not run this on PRs?