#!/usr/bin/env bash # Build the member-readable documentation site from this repository. # # The repository is the single source of truth. This script: # 1. stages a mirror of the documents into .site-src/ (generated, gitignored), # because MkDocs cannot read the repository root directly; # 2. renders .site-src/ to .site-build/ with MkDocs + Material. # # No document is moved, renamed, or rewritten — the staging copy is a build # artifact and disappears with `--clean`. # # Usage: # publishing/build.sh # create/use .venv-docs and build # publishing/build.sh /path/to/venv # use an existing venv # # In CI (Woodpecker), install the toolchain and run MkDocs directly: # pip install -r publishing/requirements.txt && mkdocs build --strict set -euo pipefail REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$REPO_DIR" VENV="${1:-$REPO_DIR/.venv-docs}" SITE_SRC="$REPO_DIR/.site-src" # 1. Stage the documents (Markdown at the root, maintenance/, incidents/) plus # the publishing assets (fonts, CSS, icon). Exclude tooling and build output. rm -rf "$SITE_SRC" mkdir -p "$SITE_SRC" tar cf - \ --exclude='.git' \ --exclude='.site-src' \ --exclude='.site-build' \ --exclude='.venv-docs' \ --exclude='*.sh' \ --exclude='publishing/webhook-receiver.py' \ --exclude='publishing/webhook-receiver.service' \ --exclude='mkdocs.yml' \ --exclude='.gitignore' \ --exclude='requirements.txt' \ . | tar xf - -C "$SITE_SRC" # A file that must sit at the site root (crawler rules), not under publishing/. cp publishing/robots.txt "$SITE_SRC/robots.txt" # The documents sometimes link to a directory (`incidents/`) the way Gitea # renders it. A static site has no directory listing, so generate a small # index page for any documented subdirectory that lacks one. This is a build # artifact — the documents themselves are never touched. (cd "$SITE_SRC" && find . -mindepth 1 -type d ! -path './publishing*' | while read -r dir; do if compgen -G "$dir"/*.md >/dev/null && [ ! -f "$dir/index.md" ]; then dir_name="$(basename "$dir")" title="$(echo "$dir_name" | sed 's/-/ /g' | sed 's/^./\u&/')" { echo "# $title" echo echo "Landing page for this directory, generated by the publishing layer — the" echo "documents themselves live untouched in the repository." echo for f in "$dir"/*.md; do [ "$(basename "$f")" = "index.md" ] && continue heading="$(grep -m1 '^# ' "$f" | sed 's/^# //' || true)" echo "- [${heading:-$(basename "$f" .md)}]($(basename "$f"))" done } > "$dir/index.md" fi done) # 2. Build. if [ ! -x "$VENV/bin/mkdocs" ]; then echo "Creating build venv at $VENV" python3 -m venv "$VENV" "$VENV/bin/pip" install --quiet --upgrade pip "$VENV/bin/pip" install --quiet -r "$REPO_DIR/publishing/requirements.txt" fi echo "Building site -> $REPO_DIR/.site-build" "$VENV/bin/mkdocs" build --clean echo "Done: $REPO_DIR/.site-build"