Skip to content

Commit e041352

Browse files
committed
Add CLAUDE.md documenting codebase structure and workflows
Covers dev/test/lint commands, the content/data/translations model, request-rendering pipeline, and generated REST/GraphQL/webhook docs for future Claude Code sessions working in this repo. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDqxsqz2YkydC6mnfJ5T2o
1 parent bf941bc commit e041352

1 file changed

Lines changed: 93 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## What this repository is
6+
7+
This is the source for [docs.github.com](https://docs.github.com) — a Next.js/Express application that renders Markdown content (with Liquid templating and versioning) into GitHub's product documentation site. The vast majority of contributions are content changes (Markdown in `content/`); application code (Node.js/Express/React/Next.js) is a smaller, separate concern.
8+
9+
Note: GitHub's Docs team writes pre-production content in a private repo (`docs-internal`) that syncs with this public repo, so some workflows referenced in docs (e.g. Early Access) assume that private counterpart.
10+
11+
## Commands
12+
13+
```sh
14+
npm ci # install deps (run once per pulled branch)
15+
npm ci --include=optional # also installs test-only deps like puppeteer (needed to run full test suite locally)
16+
npm run build # next build — creates static assets (run once per pulled branch, and again if tests fail complaining about missing production build)
17+
npm start # dev server at localhost:4000, only 'en' and 'ja' enabled by default (NODE_ENV=development)
18+
npm run debug # dev server with --inspect for VS Code's Node debugger
19+
20+
npm test # run full jest suite
21+
npm test -- <TEST_NAME> # run tests matching a filename/partial filename/path
22+
NODE_OPTIONS=--experimental-vm-modules npx jest tests/unit # run a specific test directory directly
23+
npm run test-watch # watch mode with coverage
24+
25+
npm run lint # eslint on **/*.{js,mjs,ts,tsx}
26+
npm run tsc # typescript check (tsc --noEmit)
27+
npm run prettier # auto-format ts/tsx/js/mjs/scss/yml/yaml
28+
npm run prettier-check # check formatting without writing
29+
```
30+
31+
- Node version is pinned to **16.x** (see `.node-version` / `engines` in `package.json`).
32+
- To enable more languages locally, temporarily edit `ENABLED_LANGUAGES` in the `start` script in `package.json` (language codes defined in `lib/languages.js`).
33+
- Visit `localhost:4000/dev-toc` while the dev server is running to see the full site table of contents (internal-only route, not on production).
34+
- Git LFS is required (`pre-push`/`post-checkout`/`post-merge` husky hooks call into `git-lfs`).
35+
- `husky` pre-commit hook runs `script/prevent-translation-commits.js` (blocks commits that touch `translations/`, since those are Crowdin-managed) and `lint-staged` (eslint --fix + prettier on staged files).
36+
- `script/` follows the ["Scripts to Rule Them All"](https://githubengineering.com/scripts-to-rule-them-all/) pattern: `script/bootstrap` = install, `script/server` = start dev server, `script/test` = run tests. Prefer writing new scripts in JavaScript over Bash (repo is developed cross-platform, including Windows).
37+
38+
## Architecture
39+
40+
### Request flow
41+
42+
`server.mjs` boots an Express app (`lib/app.js`) that composes middleware from `middleware/index.js` in a specific, order-sensitive pipeline: language detection → request `context` building → redirects → `find-page` (resolves URL to a content file) → Next.js page rendering. Two middleware subdirectories matter:
43+
- `middleware/contextualizers/` — populate `req.context` (the object templates/pages render from).
44+
- `middleware/redirects/` — handle the various redirect mechanisms (external sites, language-code redirects, `redirect_from` frontmatter, etc).
45+
46+
Pages live under `pages/[versionId]/...` using Next.js file-system routing; most product content is served through the catch-all `pages/[versionId]/[productId]/[...restPage].tsx`, with a few products (REST, GraphQL, Admin release notes) having dedicated page files because they need custom rendering.
47+
48+
### Content model (the part contributors touch most)
49+
50+
- **`content/`** — all English Markdown source, organized by product/category. Every Markdown file has YAML frontmatter validated against a schema in `lib/frontmatter.js` (see `contributing/content-markup-reference.md` for the full field reference). Key frontmatter:
51+
- `versions` (required on every page) — which products/releases (`fpt`, `ghes`, `ghae`, etc., see `lib/all-versions.js`) the page applies to. Drives both routing and in-page Liquid conditionals.
52+
- `redirect_from` — old URLs that should redirect to this page.
53+
- `children` (required on `index.md`) — the site only knows about pages listed in some ancestor's `children`; anything not reachable via `children` 404s. `childGroups` is additionally required on the homepage `index.md`.
54+
- Filenames must be a kebab-case match of `title` (enforced by tests) unless `allowTitleToDifferFromFilename: true` is set.
55+
- **`data/`** — YAML/Markdown exposed to templates via the `{% data %}` Liquid tag. Subdirectories: `reusables/` (long reusable text blocks, one per Markdown file), `variables/` (short reusable strings), `features/` (feature-based versioning), `glossaries/`, `learning-tracks/`, `graphql/` (schema synced from `github/github`), `webhooks/` (payload JSON), `release-notes/`. Most YAML/Markdown under `data/` and `content/` is translated via Crowdin by default.
56+
- **`includes/`** — Liquid include templates (`.html`), notably `includes/liquid-tags/` for custom tags.
57+
- **Rendering pipeline**`lib/render-content/` turns Markdown + Liquid + context into HTML, built on `remark`/`unified` with custom plugins in `lib/render-content/plugins/` (link rewriting per language/version, asset path rewriting, code block headers, etc).
58+
- **Versioning happens at two layers**: frontmatter `versions` (page-level availability) and inline Liquid conditionals (`{% ifversion %}` etc., can appear in `content`, `data`, and `includes`) for version-specific content within a single page. See `contributing/liquid-helpers.md` and `contributing/permalinks.md`.
59+
- **Custom Markdown extensions**: callout tags (`{% note %}`/`{% warning %}`), OS tags (`{% mac %}`/`{% windows %}`/`{% linux %}`), tool tags (`{% webui %}`/`{% cli %}`/`{% desktop %}`/`{% curl %}`/`{% codespaces %}`/`{% vscode %}`/`{% importer_cli %}`/`{% graphql %}`), Octicons (`{% octicon "name" %}`) — see `contributing/content-markup-reference.md`.
60+
- **Local links** must start with a product ID (e.g. `/actions`); image paths must start with `/assets`. These get rewritten server-side per language/version (`lib/render-content/plugins/rewrite-local-links.js`). To stop a link from being enterprise-ified, use raw HTML with `class="dotcom-only"`.
61+
62+
### Translations
63+
64+
`translations/<lang>/` mirrors `content/` and `data/` per locale (currently `es-ES`, `ja-JP`, `pt-BR`, `zh-CN`), synced via Crowdin. **Never hand-edit files under `translations/`** — the pre-commit hook (`script/prevent-translation-commits.js`) blocks this by default; it's only overridable via `ALLOW_TRANSLATION_COMMITS` for the sync tooling itself.
65+
66+
### REST/GraphQL/webhook docs
67+
68+
Reference docs for REST, GraphQL, and webhooks are largely generated/synced rather than hand-authored:
69+
- REST: `script/rest/update-files.js` pulls OpenAPI schemas from `github/github`, dereferences, and decorates them; served via `pages/[versionId]/rest/`.
70+
- GraphQL: `script/graphql/update-files.js` keeps `data/graphql/` in sync with `github/github`'s schema.
71+
- Webhooks: JSON payloads live in `data/webhooks/`.
72+
Avoid hand-editing generated output in these areas; change the source script/schema instead.
73+
74+
### Components
75+
76+
`components/` holds React components rendered via Next.js (server or client). `pages/` is the entry point — file-system routing matches a URL to a page component, which composes components from `components/`. This area is explicitly noted as a work in progress in `components/README.md`, so expect some inconsistency.
77+
78+
## Testing conventions
79+
80+
- Tests use Jest and live under `tests/` (`tests/unit`, `tests/content`, `tests/rendering`, `tests/routing`, `tests/graphql`, `tests/javascripts`, `tests/browser`, `tests/linting`, `tests/meta`, `tests/translations`).
81+
- `tests/linting/lint-files.js` is the content linter — validates frontmatter schema, Markdown structure, filename/title consistency, link/reusable/variable usage, etc. across every content file. This is usually the relevant test when a content change fails CI.
82+
- Content-focused tests are often slow given the size of `content/`; scope test runs with `npm test -- <TEST_NAME>` rather than always running the full suite.
83+
84+
## Repo-specific gotchas
85+
86+
- Don't create new abstractions/refactors for docs content changes — content PRs should stay scoped to the Markdown/data being changed.
87+
- `main` is protected; `script/prevent-pushes-to-main.js` (pre-push hook) blocks direct pushes to `main`.
88+
- When adding a new article, the filename must kebab-case-match the `title` frontmatter, or a test will fail.
89+
- Windows contributors: use `\r?\n` instead of `\n` in regexes, prefer `path.posix`/the `slash` module for forward-slash paths, and prefer JS scripts over Bash — see the Windows section of `CONTRIBUTING.md`.
90+
91+
## Subdirectory READMEs
92+
93+
Many directories have their own README with more detail; consult them before making non-trivial changes in that area: `content/README.md`, `content/graphql/README.md`, `content/rest/README.md`, `contributing/README.md`, `data/README.md`, `data/reusables/README.md`, `data/variables/README.md`, `includes/README.md`, `includes/liquid-tags/README.md`, `components/README.md`, `lib/liquid-tags/README.md`, `lib/render-content/README.md`, `middleware/README.md`, `script/README.md`, `stylesheets/README.md`, `tests/README.md`.

0 commit comments

Comments
 (0)