Commit 4a7e191
authored
🤖 feat: add docs site, Pages deploy, and docs quality checks (#19)
## Summary
Add a Diátaxis-based MkDocs documentation site and automate GitHub Pages
deployment.
Also add docs quality gates in CI for markdown linting, spelling, and
dead links.
## Background
The repository did not yet have a dedicated docs site or CI checks
focused on docs quality.
This change adds a structured docs experience and keeps docs
quality/regression checks
consistent whenever docs are updated.
## Implementation
- Added MkDocs Material site scaffolding under `docs/` with Diátaxis
sections.
- Added `mkdocs.yml` and local docs tooling via `flake.nix` and Make
targets.
- Added docs deployment workflow for GitHub Pages.
- Added docs-quality CI checks:
- `markdownlint-cli2`
- `cspell`
- `lychee` (external dead-link check)
- Added `.cspell.json` and `.markdownlint-cli2.yaml` config files.
- Updated `AGENTS.md` and `README.md` to reflect docs workflow
expectations.
## Validation
- `make verify-vendor`
- `make test`
- `make build`
- `make lint`
- `go run github.com/rhysd/actionlint/cmd/actionlint@v1.7.10`
- `make docs-check`
- `npx --yes markdownlint-cli2@0.18.1 "docs/**/*.md"`
- `npx --yes cspell@8.19.4 --no-progress --config .cspell.json
"docs/**/*.md" "mkdocs.yml"`
- `docker run --rm -v "$PWD":/repo lycheeverse/lychee:latest --verbose
--no-progress --accept 200,429 --max-retries 2 --retry-wait-time 2
/repo/docs/**/*.md`
## Risks
- Low-to-moderate operational risk: docs CI now includes external link
checking,
which may intermittently fail due to remote endpoint behavior/rate
limits.
---
<details>
<summary>📋 Implementation Plan</summary>
# Plan: Deploy Diátaxis docs to GitHub Pages (MkDocs Material)
## Context / Why
You want to add a documentation site for `coder-k8s` that:
- Is **deployed to GitHub Pages** automatically.
- Uses the **Diátaxis** information architecture (Tutorials / How‑to /
Reference / Explanation).
- Uses **CLIs directly** for local authoring (no Docker wrapper),
assuming they’re available via the **Nix devshell**.
The repo currently has developer onboarding in `README.md` and deeper
architecture notes in `AGENTS.md`, but **no docs site scaffolding**.
<details>
<summary>Why I’m planning around MkDocs Material (not
Docusaurus)</summary>
- Fits “docs-as-code” repos well (Markdown-first, minimal moving parts).
- Easy to run locally via a single `mkdocs` CLI.
- Common in Kubernetes-adjacent projects.
- Diátaxis is tooling-agnostic; MkDocs nav maps cleanly to its
quadrants.
(If you decide you *must* have React/MDX, versioned docs, or heavy UI
customization, Docusaurus becomes more compelling—but it adds a Node
toolchain to a Go repo.)
</details>
## Evidence (what I verified)
- No existing docs site scaffolding/config (per explore report + repo
inspection):
- No `docs/` directory.
- No `mkdocs.yml` / Docusaurus config.
- No GitHub Pages workflow dedicated to docs.
- Current devshell (`flake.nix`) is present and minimal (Go + common
CLIs only). (See `flake.nix` + `flake.lock`.)
- `Makefile` has no docs targets; it already uses “install via nix
develop” checks for tools like `golangci-lint` / `govulncheck`. (See
`Makefile`.)
- CI enforces GitHub Actions linting and security scanning via
**actionlint** + **zizmor**, and actions are SHA-pinned. (See
`.github/workflows/ci.yaml`.)
## Implementation plan
### 1) Add a Diátaxis docs skeleton
Create a new `docs/` tree organized by Diátaxis quadrants:
- `docs/index.md` – landing page with “Start here” + links to each
quadrant.
- `docs/tutorials/` – learning-oriented, end-to-end walkthroughs.
- `docs/how-to/` – task-oriented guides (deploy, upgrade, troubleshoot).
- `docs/reference/` – factual reference (CRDs/APIs, flags, config).
- `docs/explanation/` – concepts, architecture, design decisions.
Seed initial pages by **moving/rewriting** existing content:
- Convert `README.md` quickstart into
`docs/tutorials/getting-started.md`.
- Convert user-relevant parts of `AGENTS.md` (architecture, app modes)
into `docs/explanation/architecture.md` (avoid agent/PR workflow parts).
- Add deployment docs that explain what’s in `deploy/` and `config/*`:
- `docs/how-to/deploy-controller.md`
- `docs/how-to/deploy-aggregated-apiserver.md`
- Add a first reference page that links to the CRD YAML and Go types:
- `docs/reference/api/codercontrolplane.md`
- `docs/reference/api/coderworkspace.md`
- `docs/reference/api/codertemplate.md`
> Keep the Diátaxis rule strict: tutorials = guided learning, how-to =
recipes, reference = “what is X”, explanation = “why/how it works”.
### 2) Configure MkDocs Material (`mkdocs.yml`)
Add `mkdocs.yml` at repo root.
Key requirements:
- Material theme with search + good navigation.
- Nav reflects Diátaxis quadrants as **top-level tabs**.
- Enable Markdown extensions used by Material (admonitions, details,
fenced code, Mermaid).
Minimal config shape (tweak as needed):
```yaml
site_name: coder-k8s
repo_url: https://github.com/coder/coder-k8s
edit_uri: edit/main/docs/
theme:
name: material
features:
- navigation.tabs
- navigation.sections
- content.action.edit
- search.suggest
- search.highlight
markdown_extensions:
- admonition
- pymdownx.details
- pymdownx.superfences
- pymdownx.tabbed:
alternate_style: true
- toc:
permalink: true
plugins:
- search
nav:
- Home: index.md
- Tutorials:
- Getting started: tutorials/getting-started.md
- How-to guides:
- Deploy controller: how-to/deploy-controller.md
- Deploy aggregated API server: how-to/deploy-aggregated-apiserver.md
- Troubleshooting: how-to/troubleshooting.md
- Reference:
- API:
- CoderControlPlane: reference/api/codercontrolplane.md
- CoderWorkspace: reference/api/coderworkspace.md
- CoderTemplate: reference/api/codertemplate.md
- Explanation:
- Architecture: explanation/architecture.md
```
<details>
<summary>Optional MkDocs enhancements (keep out of v1 if you want
minimal scope)</summary>
- Add `git-revision-date-localized` plugin to show “Last updated”.
- Add `mkdocs-minify-plugin` for smaller assets.
- Add `mkdocs-redirects` if you expect lots of restructuring.
Each optional plugin should also be added to the Nix python environment
and CI install step.
</details>
### 3) Update Nix devshell (`flake.nix`) to provide the docs toolchain
Goal: inside `nix develop`, contributors can run `mkdocs` directly.
Update `flake.nix` `devShells.default.packages` to include a Python
environment with:
- `mkdocs`
- `mkdocs-material`
- `pymdown-extensions`
Prefer a single `python3.withPackages` environment so `mkdocs` can
import the theme/plugins:
```nix
# flake.nix (inside `let pkgs = ...; in { default = pkgs.mkShell { ... } }`)
let
docsPython = pkgs.python3.withPackages (ps: [
ps.mkdocs
ps."mkdocs-material"
ps."pymdown-extensions"
]);
in
pkgs.mkShell {
packages = with pkgs; [
go
gnumake
git
goreleaser
actionlint
zizmor
golangci-lint
govulncheck
docsPython
];
}
```
Notes:
- Nix attribute names for python packages sometimes require quoting
(e.g. `ps."mkdocs-material"`).
- Keep the devshell lean; only add plugins that are actually enabled in
`mkdocs.yml`.
### 4) Add Makefile targets that use the CLI (no Docker)
Add docs targets that match the repo’s “tool missing → use nix develop”
pattern:
```make
.PHONY: docs-serve docs-build docs-check
docs-serve:
@command -v mkdocs >/dev/null || (echo "mkdocs not found; use nix develop" && exit 1)
mkdocs serve
docs-build:
@command -v mkdocs >/dev/null || (echo "mkdocs not found; use nix develop" && exit 1)
mkdocs build
docs-check:
@command -v mkdocs >/dev/null || (echo "mkdocs not found; use nix develop" && exit 1)
mkdocs build --strict
```
Also update `README.md` “Essential commands” to include `make
docs-serve` / `make docs-check`.
### 5) Ignore build output
Update `.gitignore` to ignore MkDocs output and caches:
- `site/`
- `.cache/` (if it shows up in practice)
### 6) GitHub Pages deployment workflow
Add a dedicated workflow: `.github/workflows/docs.yaml`.
Requirements:
- On **PRs**: build docs (no deploy) so broken docs fail fast.
- On **push to main**: build + deploy to GitHub Pages.
- Use **SHA-pinned** actions (repo policy) and pass `actionlint` +
`zizmor`.
- Use minimal permissions; only the deploy job should get `pages:write`
+ `id-token:write`.
Recommended approach (modern Pages deployment, no `gh-pages` branch):
```yaml
name: Docs
on:
pull_request:
paths:
- docs/**
- mkdocs.yml
push:
branches: [main]
paths:
- docs/**
- mkdocs.yml
jobs:
build:
runs-on: depot-ubuntu-24.04
permissions:
contents: read
steps:
- uses: actions/checkout@<sha> # pin
- uses: actions/setup-python@<sha> # pin
with:
python-version: '3.x'
cache: pip
- run: pip install mkdocs-material
- run: mkdocs build --strict
- uses: actions/upload-pages-artifact@<sha> # pin
if: github.ref == 'refs/heads/main'
with:
path: site
deploy:
if: github.ref == 'refs/heads/main'
needs: build
runs-on: depot-ubuntu-24.04
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/deploy-pages@<sha> # pin
id: deployment
```
Notes:
- Keep the deploy job separate so permissions stay tight.
- If you add plugins beyond `mkdocs-material`, either:
- add them to the `pip install ...` line, or
- introduce a `docs/requirements.txt` and `pip install -r
docs/requirements.txt`.
Manual repo setting (one-time): set GitHub Pages source to **GitHub
Actions**.
### 7) Validation checklist (what to run locally)
- `nix develop` then:
- `mkdocs --version` (sanity)
- `make docs-check` (ensures `--strict` build passes)
- `make docs-serve` and open the local site
- Lint workflows if you changed them:
- `go run github.com/rhysd/actionlint/cmd/actionlint@v1.7.10`
- `zizmor --help` / `zizmor` equivalent (or rely on CI)
## Deliverables (files that will change)
- `docs/**` (new)
- `mkdocs.yml` (new)
- `flake.nix` (update devshell packages)
- `Makefile` (add docs targets)
- `.gitignore` (ignore MkDocs output)
- `.github/workflows/docs.yaml` (new)
- `README.md` (link to docs + new make targets)
</details>
---
_Generated with [`mux`](https://github.com/coder/mux) • Model:
`openai:gpt-5.3-codex` • Thinking: `xhigh` • Cost: `$0.55`_
<!-- mux-attribution: model=openai:gpt-5.3-codex thinking=xhigh
costs=0.55 -->1 parent 1eba173 commit 4a7e191
20 files changed
Lines changed: 628 additions & 3 deletions
File tree
- .github/workflows
- docs
- explanation
- how-to
- javascripts
- reference/api
- tutorials
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
66 | 66 | | |
67 | 67 | | |
68 | 68 | | |
| 69 | + | |
| 70 | + | |
69 | 71 | | |
70 | 72 | | |
71 | 73 | | |
| |||
89 | 91 | | |
90 | 92 | | |
91 | 93 | | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
92 | 97 | | |
93 | 98 | | |
94 | 99 | | |
| |||
111 | 116 | | |
112 | 117 | | |
113 | 118 | | |
| 119 | + | |
| 120 | + | |
114 | 121 | | |
115 | 122 | | |
116 | 123 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
6 | 9 | | |
7 | 10 | | |
8 | 11 | | |
| |||
20 | 23 | | |
21 | 24 | | |
22 | 25 | | |
23 | | - | |
| 26 | + | |
24 | 27 | | |
25 | 28 | | |
26 | 29 | | |
| |||
40 | 43 | | |
41 | 44 | | |
42 | 45 | | |
| 46 | + | |
| 47 | + | |
43 | 48 | | |
44 | 49 | | |
45 | 50 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
0 commit comments