SRD-080 — Documentation site on GitHub Pages¶
| Field | Value |
|---|---|
| Status | Accepted |
| Date | 2026-08-05 |
| Owner | Ruslan Gabitov |
| Implements | — (standalone tooling landing; no parent ADR — the engine concept is untouched) |
| Related | the blocking linkcheck gate this site build complements, and the CI core/examples workflow split whose conventions docs.yml follows (both landed by earlier one-shot fix records; per the hierarchy rule an SRD does not reference FIX docs downward) |
§1 Background¶
docs/guides/ is a 90-page developer manual (find docs/guides -name '*.md' →
90), every page carrying title:/description: frontmatter, published today
only as raw Markdown browsed on GitHub. GitHub's file view gives no site-wide
search, no navigation sidebar, no readable entry URL — a manual of this size
deserves a real documentation site, and the repository already pays the
authoring cost.
The obstacle to publishing just the guides is the link graph. Measured on the current tree:
- guides →
docs/design/— 148 links (ADR/SAD rationale pins); - design →
docs/bpmn-spec/— 230 links (the vendored BPMN 2.0 extract); - design →
docs/srd/— 8, →docs/analytics/— 1 (two former links intodocs/camunda7/are paraphrased away in this branch, FR-2a); - guides →
examples/(outsidedocs/) — 65 links, plus a handful topkg/…,adapters/…, and the repository root.
Any published subset of docs/ leaves hundreds of dead links; links that
escape docs/ entirely can never resolve on a docs site and must be rewritten
to GitHub URLs at build time. The repository's make ci already runs a
blocking relative-link checker (make link-check), so the source tree is known-clean —
the site build must preserve that property, not erode it.
"Kept up to date" must be a property of CI, not a ritual: the site redeploys
itself whenever a docs-touching change lands on master.
§2 Requirements¶
Functional¶
- FR-1 — the
docs/tree publishes as a static site athttps://dr-dobermann.github.io/gobpm/, built by MkDocs with the Material theme;docs/guides/index.mdis the featured entry point, and a new top-leveldocs/index.mdlanding page routes readers to guides / design / BPMN extract (MkDocs requires a homepage;docs/has none today —ls docs/*.md→backlog.mdonly). - FR-2 — every intra-
docs/relative link resolves on the published site (guaranteed by publishing the whole tree +mkdocs build --strict, which fails on unresolved links). - FR-2a —
docs/camunda7/is excluded from the published site (exclude_docs: /camunda7/) — internal migration-analysis material, not developer documentation. Its sources stay in the repo untouched. The two inbound links (design/ADR-005en + ru, References) are replaced with link-free paraphrases in this branch — no version bump, the References inventory is not a contract change — so no link into the excluded path remains and--strictstays green by construction. - FR-3 — links escaping
docs/(../../examples/…,../../../pkg/…, repo root) are rewritten at build time tohttps://github.com/dr-dobermann/gobpm/tree/master/<path>by an MkDocs hook — zero churn in the Markdown sources, so in-repo browsing, Obsidian, and the existinglinkcheckgate are untouched. - FR-4 — a
docs.ymlGitHub Actions workflow (a) on pull requests touchingdocs/**or the site config: runsmkdocs build --strictas a validation check; (b) on push tomasterwith the same paths (plusworkflow_dispatch): builds and deploys viaactions/deploy-pages— nogh-pagesbranch. Actions pinned by commit SHA with a release comment, matchingcheck.yml. - FR-5 — the MkDocs toolchain is version-pinned (
mkdocs-material==9.7.7, which pinsmkdocstransitively) in one place consumed by both CI and the local target, per the parity rules. - FR-6 —
make docs-build(strict build) andmake docs-serve(live preview) exist for local use, guarded byrequire-command; they are not part of themake ciumbrella (Python is not a prerequisite of the core gate — same reasoning that keeps CI-pinned tool installs out of the Makefile,check.yml"Install tools" comment). - FR-7 —
README.md(and its translated twins, if any) link the published site;CHANGELOG.md[Unreleased]records the addition.
Non-functional¶
- NFR-1 — the deploy needs no manual step beyond the one-time repository setting Settings → Pages → Source: GitHub Actions (owner-only; recorded in §10 when done).
- NFR-2 —
.obsidian/never publishes (MkDocs excludes dot-prefixed files/directories by default). - NFR-3 — no Go code changes; the diff-coverage gate is trivially green.
make cistays green across modules. - NFR-4 — workflow permissions are minimal (
contents: read,pages: write,id-token: writeon the deploy job only).
§3 Models¶
Three new artifacts, one edited:
mkdocs.yml (repo root):
site_name: gobpm
site_url: https://dr-dobermann.github.io/gobpm/
repo_url: https://github.com/dr-dobermann/gobpm
docs_dir: docs
theme:
name: material
features: [navigation.sections, navigation.top, search.suggest, content.code.copy]
palette: # light + dark toggle
exclude_docs: |
/camunda7/
validation: # harden --strict: these default to `info`, which strict ignores
omitted_files: warn
unrecognized_links: warn
anchors: warn
hooks:
- scripts/mkdocs_hooks.py
No nav: key in v1 — MkDocs auto-derives the tree, and the curated
index.md pages (guides/index.md and the new docs/index.md) remain the
primary navigation surface (see §4.3 and Open questions Q3).
scripts/mkdocs_hooks.py — one on_page_markdown hook: for each
relative link, resolve it against the page's location; if the target lies
outside docs/, rewrite to
https://github.com/dr-dobermann/gobpm/tree/master/<repo-relative-path>.
Links inside docs/ pass through untouched. Worked example — in
docs/guides/getting-started/first-process.md:
[`basic-process`](../../../examples/basic-process/) # source
[`basic-process`](https://github.com/dr-dobermann/gobpm/tree/master/examples/basic-process/) # built
.github/workflows/docs.yml — two jobs: build (PR + push: pinned
actions/setup-python, pip install mkdocs-material==9.7.7,
mkdocs build --strict, upload the artifact) and deploy
(if: github.ref == 'refs/heads/master', environment github-pages,
actions/deploy-pages).
Makefile — docs-build / docs-serve targets behind
require-command, reading the pin from a MKDOCS_MATERIAL_VERSION variable
so scripts/check-tool-pins.sh can adopt it later.
Plus the new content page docs/index.md (landing: what gobpm is, three
doors — Developer Manual / Design docs / BPMN extract) — kept useful for
in-repo browsing too.
§4 Analysis¶
§4.1 Generator — MkDocs Material over the alternatives¶
- Jekyll ("Pages from /docs") — zero workflow, but no search, no sidebar, fragile Markdown handling, and no strict-link gate; the out-of-tree links stay broken. Rejected.
- Hugo / mdBook / Docusaurus — capable, but none consumes the existing
title:/description:frontmatter as-is across a plain nested-directory tree without restructuring (mdBook wantsSUMMARY.md; Docusaurus wants a JS project). Rejected for churn. - MkDocs + Material — consumes the tree and frontmatter as they are,
ships search + light/dark theme,
--strictgives a second link gate, and thehooks:mechanism solves the escaping-links problem without touching sources. Chosen.
§4.2 Scope — whole docs/ over a subset¶
Guides-only strands 148 design links; guides+design strands 230 BPMN-extract
links plus the srd/camunda7/analytics stragglers (§1). Publishing the whole
tree closes the intra-docs/ link graph by construction and keeps the scope
rule trivial ("everything under docs/ is public — as it already is in the
repository"). SRD/FIX one-shots publish as the historical records they are.
§4.3 Navigation — auto-derived in v1¶
A hand-maintained nav: over 337 files is unmaintainable and would go stale
at the first added page (the exact drift class the link gate exists to kill).
Plugins (literate-nav, awesome-pages) can curate ordering but add
dependencies and per-directory dot-files; deferred until the auto sidebar
proves inadequate in practice. The curated index pages already provide the
reading order.
§4.4 Deploy — actions/deploy-pages over a gh-pages branch¶
A pushed gh-pages branch is mutable repo state outside review and bloats
clone size with built HTML. The Pages deployment API keeps built output out
of git entirely and its permission surface is job-scoped. Also rejected:
mkdocs gh-deploy (same branch-push model, plus it pushes from CI with
contents: write).
§5 API¶
No library API surface. The user-facing surface is:
https://dr-dobermann.github.io/gobpm/— the site;make docs-build/make docs-serve— local build/preview;- the
docs.ymlPR check — a redmkdocs build --stricton a docs-touching PR.
§6 Tests / Verification¶
No Go code, so verification is build-level, each step mechanical:
| # | Check | How |
|---|---|---|
| V-1 | Strict build green | make docs-build (→ mkdocs build --strict) exits 0 on the current tree |
| V-2 | Escaping links rewritten | grep the built site/ HTML: zero href climbing out of the site root; examples/-links point at github.com/dr-dobermann/gobpm/tree/master/examples/… |
| V-3 | Intra-docs links resolve | --strict (fails on warnings) + spot-check guides→ADR and ADR→bpmn-spec pages in the built HTML |
| V-4 | Exclusions absent | find site -name '.obsidian' → empty; test ! -d site/camunda7; no site/ in git status (gitignored) |
| V-5 | Repo gate intact | make ci green (link-check, lint, tests, coverage untouched) |
| V-6 | CI validation works | the PR for this branch shows the docs / build check green |
| V-7 | Deploy works | post-merge, first docs.yml run on master deploys; site reachable (user confirms — needs the one-time Pages setting, NFR-1) |
§7 Milestones¶
- M1 — site skeleton:
mkdocs.yml,scripts/mkdocs_hooks.py,docs/index.md,.gitignoreentry forsite/; V-1…V-4 green locally. - M2 — CI:
.github/workflows/docs.yml(build check + master deploy), Makefile targets + pin variable; V-5, V-6. - M3 — surfacing: README (+ twins) site link,
CHANGELOG.mdentry, linked-docs sweep.
§8 Cross-doc references¶
None. This SRD implements no ADR and pins no versioned doc; the two related one-shot fix records (link gate, CI split) are described in prose only — an SRD does not reference FIX docs downward. No ADR/SAD contract is touched; no version bumps.
§9 Definition of Done¶
- [ ] V-1…V-6 green; V-7 confirmed after merge.
- [ ] The site self-updates: a later docs-touching merge to
mastertriggers a redeploy with no manual step. - [ ] README + CHANGELOG updated (FR-7).
- [ ]
make cigreen across modules (NFR-3). - [ ] §10 filled with commit SHAs and the Pages-setting confirmation.
§10 Implementation summary¶
Landed on feat/docs-site-gh-pages in three milestones:
- M1
32ed338—mkdocs.yml(Material, whole-docs scope minuscamunda7/andbpmn-spec/scripts/, hardened--strictvalidation),scripts/mkdocs_hooks.py(out-of-tree link rewrite + GitHub-compatible heading slugify — an addition over the §3 model: the repo's in-page anchors are authored against GitHub's slugs, which Python-Markdown's default breaks),docs/index.mdanddocs/design/index.mdlanding pages,site/gitignored. Strict mode surfaced link rot beyondlinkcheck's relative-file scope, fixed at the source: bare directory links inbpmn-spec/index.md(→ code spans), guides (→design/index.md), SAD-001 / ADR-024 / SRD-051 (→bpmn-spec/index.md, mechanical retargets, no version bumps); ADR-005 en/ru paraphrase away the camunda7 links. - M2
153bd83—.github/workflows/docs.yml(PR strict-build check; master push + dispatch →actions/deploy-pages, SHA-pinned, job-scoped permissions), MakefileMKDOCS_MATERIAL_VERSION+docs-build/docs-servebehindrequire-mkdocs;scripts/check-tool-pins.shlearns apypi:source and per-tool workflow, gains the missinglinkcheckentry, and bumps only the Makefile pin line (a version-string collision with the covercheck comment would have corrupted prose). - M3
2daafd1— README en/ru +README_INDEX.mdsite links,CHANGELOG.mdentry,docs/guides/CONTRIBUTING.mdsite-facing authoring rules,CLAUDE.mdcommand inventory. Sweep found no stale claims in the roadmap or backlog.
Verification: V-1…V-5 green (strict build 8.2s exit 0; 30 built guide pages
carry rewritten GitHub examples/ links, zero escaping hrefs; exclusions
absent from site/; make ci exit 0 across modules; make link-check
green). The /check-srd audit passed with no red findings. Post-merge tail:
V-6 (the docs / build PR check) proves out on the pushed branch; the owner
flips Settings → Pages → Source: GitHub Actions once, and V-7 (first
deploy, site reachable at https://dr-dobermann.github.io/gobpm/) closes
with the first master run.
Open questions¶
None — all resolved with the owner (2026-08-05):
- Scope — the whole
docs/tree publishes:guides/(the manual),design/(SAD + ADRs, incl. the.rutwins), the vendoredbpmn-spec/extract, plussrd/,fix/,audit/,analytics/, andbacklog.md(all already public in the repository; required for link-graph closure, §4.2). Excluded:camunda7/(FR-2a) — internal migration-analysis material; its two inbound links (ADR-005 en/ru References) are paraphrased away in this branch, no version bump. - Navigation — auto-derived sidebar in v1; no curated-nav plugin (§4.3).
- Local toolchain — plain
pip install mkdocs-material==9.7.7; no Docker fallback (FR-6). - PR check — the
docs / buildcheck stays advisory; making it a required status check is a possible later branch-protection change (owner-side, out of scope).