mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
docs: scaffold docs/.style for the prose style guide (#25466)
Adds a private contributor-tooling directory at `docs/.style/` that will host the canonical prose style guide and the custom Vale rules used to enforce it. The directory's contents do not deploy to `coder.com/docs`. This PR is the scaffold only. The Vale configuration, the rule set, and the per-rule style-guide sections all land in follow-up PRs. ## What changes - New `docs/.style/` directory with: - `README.md` explaining the convention - `style-guide.md` as a table-of-contents scaffold - `styles/Coder/README.md` placeholder so Git tracks the empty Vale rules dir - `.github/workflows/deploy-docs.yaml`: skip the workflow on `.style`-only pushes, and exclude `.style` paths from the surgical-reindex git diff on mixed commits. Defense-in-depth on top of the manifest-driven coder.com routing. - `.github/.linkspector.yml`: add `docs/.style` to `excludedDirs` - `AGENTS.md` and `.claude/docs/DOCS_STYLE_GUIDE.md`: cross-link to the new style guide for agents ## Verification - `make pre-commit-light` clean (`fmt/markdown`, `lint/markdown`, `lint/typos`, `lint/emdash`, `lint/actions/actionlint`, `lint/shellcheck`). - `markdown-table-formatter --check` and `markdownlint-cli2` both process the new files (existing globs are `find docs -name '*.md'`). - `actionlint` clean on the modified workflow. - coder.com exclusion works because route discovery and Algolia indexing are manifest-driven; this directory is not in `docs/manifest.json`. The workflow changes are defense in depth. <details> <summary>Implementation plan and decision log</summary> ### Decisions - **Location**: `docs/.style/` (leading dot, mirrors `.github/`, `.vscode/`, `.claude/`). Vale's `StylesPath` will be `docs/.style/styles/`; `.vale.ini` lands at repo root in a follow-up. - **Existing public page `docs/about/contributing/documentation.md`**: untouched in this PR. Nick's separate information-architecture rework will redirect it to GitHub at the right time. - **Placeholder for empty `styles/Coder/`**: real `README.md`, not `.gitkeep`. Discoverable on GitHub, lints with the existing tooling, lists the planned starter rules. - **CONTRIBUTING.md**: not touched. It's a 2-line redirect to `coder.com/docs/CONTRIBUTING`; bloating it would defeat the redirect. - **`.claude/docs/DOCS_STYLE_GUIDE.md`**: kept as the structure/research companion. A blockquote at the top points at the new canonical prose guide. ### coder.com exclusion mechanism (verified by inspection) Direct inspection of `coder/coder.com`: - Route discovery in [`src/utils/docs/docs.ts`](https://github.com/coder/coder.com/blob/master/src/utils/docs/docs.ts) iterates `routes` from `docs/manifest.json`. Files not in the manifest never become routes. - The Algolia surgical indexer at [`src/utils/algoliaDocs/surgical.ts`](https://github.com/coder/coder.com/blob/master/src/utils/algoliaDocs/surgical.ts) explicitly skips paths not in the manifest, incrementing `pathsSkipped`. Net result: not adding anything from `docs/.style/` to `manifest.json` is the only thing that has to be true for the exclusion to work. The `deploy-docs.yaml` tweaks are defense in depth. ### deploy-docs.yaml changes (pre-mortem) 1. Trigger path negation `!docs/.style/**` skips the workflow on `.style`-only pushes. GitHub Actions only suppresses when every changed file matches a negation, so mixed commits still trigger. 2. The git-diff pathspec `:(exclude)docs/.style/**` drops `.style` paths from the surgical-reindex payload on mixed commits. Risks considered: - **Test contract**: `.github/workflows/test-deploy-docs-diff.sh` only exercises the downstream awk parser, not the git-diff invocation. The exclusion happens at git-diff time; the parser sees the same `<status>\0<path>\0` format. No test change needed. - **First push to a brand-new branch**: the workflow falls back to whole-branch reindex when `BEFORE_SHA` is all zeros. Whole-branch reindex re-extracts records from the manifest, which still excludes `.style` files because they are not in the manifest. - **Workflow-dispatch**: takes the whole-branch path; same reasoning. Safe. ### Why a real README in `styles/Coder/` instead of `.gitkeep` It explains intent, lists the upcoming rules, and lints with the existing tooling. The cost is one extra Markdown file; the upside is that a contributor browsing GitHub sees the plan without clicking around. </details> --- *Filed via [Coder Agents](https://coder.com/docs/ai-coder/agents) on Nick's behalf.* Linear: DOCS-180
This commit is contained in:
@@ -6,6 +6,9 @@ excludedDirs:
|
||||
- docs/reference
|
||||
# Older changelogs may contain broken links
|
||||
- docs/changelogs
|
||||
# Contributor-facing style guide and Vale config. Not deployed to
|
||||
# coder.com/docs; chasing external links here is overkill.
|
||||
- docs/.style
|
||||
ignorePatterns:
|
||||
- pattern: "localhost"
|
||||
- pattern: "example.com"
|
||||
|
||||
@@ -45,7 +45,14 @@ on:
|
||||
# Intentionally only docs/**. Edits to this workflow file must not
|
||||
# auto-trigger a production reindex; use workflow_dispatch instead.
|
||||
# See DOCS-121 (incident) and DOCS-124 (fix).
|
||||
#
|
||||
# docs/.style/** is contributor tooling and never deploys to
|
||||
# coder.com/docs. Negating it here skips the workflow on .style-only
|
||||
# commits. GitHub Actions only suppresses when every changed file
|
||||
# matches a negation, so mixed commits still trigger; the surgical
|
||||
# diff step below drops .style paths from the payload.
|
||||
- "docs/**"
|
||||
- "!docs/.style/**"
|
||||
release:
|
||||
# Fires when a draft release is published, when a release goes from
|
||||
# prerelease to non-prerelease, or when a release is created already
|
||||
@@ -174,7 +181,11 @@ jobs:
|
||||
# + save) from deleted/renamed-old-side (delete only), and
|
||||
# so paths containing whitespace or quotes survive intact.
|
||||
DIFF_FILE=$(mktemp)
|
||||
git diff --name-status -z "$BEFORE_SHA" "$AFTER_SHA" -- 'docs/**/*.md' > "$DIFF_FILE"
|
||||
# 'docs/**/*.md' to keep markdown-only paths, ':(exclude)docs/.style/**'
|
||||
# so contributor-tooling pages never reach the surgical-reindex payload
|
||||
# on mixed commits. The trigger filter already short-circuits .style-only
|
||||
# pushes; this is defense in depth.
|
||||
git diff --name-status -z "$BEFORE_SHA" "$AFTER_SHA" -- 'docs/**/*.md' ':(exclude)docs/.style/**' > "$DIFF_FILE"
|
||||
# Parse the NUL-delimited diff into <path>\t<status> lines.
|
||||
# `--name-status -z` uses NUL between fields and between
|
||||
# records, with a special twist for renames: the record is
|
||||
|
||||
@@ -24,6 +24,12 @@ on:
|
||||
- reopened
|
||||
paths:
|
||||
- "docs/**"
|
||||
# docs/.style/** is contributor tooling and never deploys to coder.com.
|
||||
# Skipping the workflow on .style-only PRs avoids posting a preview
|
||||
# link that 404s, since manifest-driven coder.com routing rejects
|
||||
# paths under .style. Mixed PRs still trigger; the selection logic
|
||||
# below filters .style files out of the preview-target pick.
|
||||
- "!docs/.style/**"
|
||||
|
||||
concurrency:
|
||||
group: docs-preview-${{ github.event.pull_request.number }}
|
||||
@@ -69,11 +75,18 @@ jobs:
|
||||
"repos/${REPO}/pulls/${PR_NUMBER}/files" \
|
||||
--jq '.[] | select(.status != "removed") | .filename')
|
||||
|
||||
# Pick the first Markdown file under docs/. `|| true` keeps
|
||||
# the pipeline from failing when grep finds no matches or
|
||||
# head triggers SIGPIPE under `set -o pipefail`.
|
||||
# Pick the first Markdown file under docs/, excluding the
|
||||
# contributor-tooling subtree at docs/.style/**. Mixed PRs that
|
||||
# touch both .style and a public docs page should land the
|
||||
# preview link on the public page; .style-only PRs already get
|
||||
# short-circuited by the trigger filter above and never reach
|
||||
# this code path.
|
||||
#
|
||||
# `|| true` keeps the pipeline from failing when grep finds no
|
||||
# matches or head triggers SIGPIPE under `set -o pipefail`.
|
||||
first_doc=$(printf '%s\n' "$all_files" \
|
||||
| grep -E '^docs/.*\.md$' \
|
||||
| grep -v '^docs/\.style/' \
|
||||
| head -n 1) || true
|
||||
|
||||
if [ -z "$first_doc" ]; then
|
||||
|
||||
Reference in New Issue
Block a user