Skip to content

Commit 62bb139

Browse files
padovanclaude
andcommitted
Scaffold the AgStack documentation site
Hugo + Docsy site that pulls component documentation out of other AgStack repositories and publishes it as one set of docs. agstack/pancake is wired in live as the single real import; its docs/ tree is, with palefire's, the only substantial one in the organisation today. Everything else in AgStack documents itself in a README, which is a content problem rather than a pipeline problem — hence one real import rather than a speculative five. The site is the documentation: sections live at the content root, so / is the index itself rather than a splash page in front of it. MECHANISM Each documented repo is a git submodule under external/, pinned to a commit. Hugo mounts its docs/ into assets/, and a content adapter turns those files into pages. Two deliberate departures from the kernelci.org precedent this follows: * Module mounts instead of tracked symlinks. Symlinked directories inside content/ are a fragile corner of Hugo that its maintainers have discussed removing, and kernelci is still pinned to Hugo 0.97.3 as a result. * Mount into assets/ and generate pages, rather than straight into content/. Upstream Markdown has no front matter, and Hugo does not derive a title from the filename, so the direct mount yields a blank <title>, an empty Docsy <h1> above the document's own heading, and blank sidebar labels. The adapter takes the title from upstream front matter if present, else the leading H1, else the filename, and lifts that heading out of the body either way. Importing GitHub-oriented Markdown charges two further taxes, both paid here: * layouts/_markup/render-link.html rewrites repo-relative *.md cross-links to real permalinks. pancake had ten; all resolve. * The adapter sets Docsy's github_repo / github_subdir / path_base_for_github_subdir page params. Adapter-generated pages do have a .File — it resolves to the adapter template — so without this, "View page source" and "Edit this page" send readers to _content.gotmpl instead of the Markdown they are reading. Dependabot's gitsubmodule ecosystem bumps the pinned pointers weekly, which is what stops imported docs from silently freezing at the commit they were added at. `make update` is scoped to external/ so it cannot drag the theme off its release tag. RUNNING IT Native: Node >= 24, and Hugo pinned in package.json via hugo-extended, so nothing is installed globally. `make serve`. Docker: `docker compose up serve` on a bare clone, with no host toolchain. The entrypoint fetches submodules into the bind mount and installs the toolchain on first run. Notable details, each of which cost a round to find: * No named volumes. Docker creates a volume's mountpoint inside the bind mount as root, which blocks both the submodule checkout and npm ci for the unprivileged container user. * node_modules therefore lives in the working tree, shared with the host — fine on Linux, a trap if installed on macOS or Windows, since hugo-extended and sass-embedded ship platform-specific binaries. The entrypoint tests that Hugo actually runs rather than that the file exists, and reinstalls if not. * The bind mount carries :z. On an SELinux-enforcing host a checkout under $HOME is labelled user_home_t, which container processes may not read, so the mount fails with "Permission denied" despite being world-readable. * Hugo is not baked into the image: `npm ci` installs the version pinned in package.json, so the container and a local checkout share one binary; CI will inherit that by running the same command. BRANDING Palette and marks derive from the AgStack logo, whose <style> block defines exactly five fills: #0570d1 primary, #34a37e secondary, #1eafc6 info, #a3d641 warning, #2b2b2b body. $danger stays Bootstrap's red — none of the five reads as "danger" and inventing one would make destructive states ambiguous. Bootstrap's named $blue/$cyan/$green are set too, since Docsy's box and link utilities resolve to those rather than the theme colours. Measuring each SVG path's bounding box separated the mark from the wordmark cleanly, giving a monochrome navbar mark, the full lockup for the landing page, and a complete favicon set including a hand-built multi-resolution .ico. LICENSING A page keeps the licence of the repository it was written in; rendering a document does not re-license it. Documentation authored here is CC BY-SA 4.0, the site machinery is Apache-2.0, and imported pages carry their source's licence — pancake is EUPL-1.2, so this is a real distinction rather than a formality. Stated in the footer, on each imported page's banner, and in full at /contributing/licensing/. STATE Verified with Hugo 0.166.0 extended and Docsy v0.17.0: 26 pages, zero build warnings, every imported page titled and ordered from its own content, exactly one <h1> per page, no unresolved cross-links, and repository links resolving to agstack/pancake. Checked in a browser at 1400/900/390px in both colour modes. A missing submodule fails the build with exit 1 rather than publishing empty sections, and `make check` exits non-zero on an unresolved cross-link. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016mn32g3xvTVhT79ZVEbfUe
0 parents  commit 62bb139

40 files changed

Lines changed: 3030 additions & 0 deletions

‎.dockerignore‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# The image carries no project files — everything, including the entrypoint,
2+
# arrives at run time through the bind mount in docker-compose.yml. Keeping the
3+
# build context empty makes `docker compose build` independent of the working tree.
4+
*

‎.github/dependabot.yml‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
version: 2
2+
3+
updates:
4+
# Bumps the pinned commit of every submodule under external/ and themes/.
5+
#
6+
# This is what keeps imported documentation from silently going stale: a
7+
# submodule records an exact commit, so without these PRs the site would keep
8+
# publishing whatever each component repo looked like on the day it was added.
9+
# Each PR's diff is the upstream documentation change, which makes it a
10+
# reasonable editorial review point rather than pure churn.
11+
- package-ecosystem: "gitsubmodule"
12+
directory: "/"
13+
schedule:
14+
interval: "weekly"
15+
day: "monday"
16+
open-pull-requests-limit: 10
17+
commit-message:
18+
prefix: "deps(submodule)"
19+
labels:
20+
- dependencies
21+
- imported-docs
22+
23+
# Hugo (via hugo-extended) and Dart Sass.
24+
- package-ecosystem: "npm"
25+
directory: "/"
26+
schedule:
27+
interval: "monthly"
28+
commit-message:
29+
prefix: "deps(npm)"
30+
labels:
31+
- dependencies
32+
33+
- package-ecosystem: "github-actions"
34+
directory: "/"
35+
schedule:
36+
interval: "monthly"
37+
commit-message:
38+
prefix: "deps(actions)"
39+
labels:
40+
- dependencies

‎.gitignore‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Hugo
2+
/public/
3+
/resources/
4+
.hugo_build.lock
5+
6+
# Toolchain
7+
/node_modules/
8+
9+
# Editors / OS
10+
.DS_Store
11+
*.swp

‎.gitmodules‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[submodule "external/pancake"]
2+
path = external/pancake
3+
url = https://github.com/agstack/pancake.git
4+
branch = main
5+
[submodule "themes/docsy"]
6+
path = themes/docsy
7+
url = https://github.com/google/docsy.git

‎Dockerfile‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Build/preview container for the docs site.
2+
#
3+
# Hugo is deliberately NOT installed here. `npm ci` pulls the exact hugo-extended
4+
# version pinned in package.json, so this container and a local checkout build with
5+
# the same binary — one place to bump it, and no drift between "works in Docker"
6+
# and "works on my machine". CI, once this repository has any, inherits that for
7+
# free by running the same `npm ci`.
8+
#
9+
# Node 24 / npm 11.18 are Docsy v0.17's stated minimums.
10+
FROM node:24-bookworm-slim
11+
12+
# git is not needed to build the site (enableGitInfo is off), but the entrypoint
13+
# reports on submodule state and contributors expect it to exist in the shell.
14+
RUN apt-get update \
15+
&& apt-get install -y --no-install-recommends git ca-certificates \
16+
&& rm -rf /var/lib/apt/lists/*
17+
18+
WORKDIR /src
19+
20+
# uid 1000, matching the typical host user, so everything written into the bind
21+
# mount — node_modules, public/, resources/, and the fetched submodules — stays
22+
# owned by the person running docker rather than by root.
23+
USER node
24+
25+
EXPOSE 1313
26+
27+
# The entrypoint is read from the bind mount rather than copied into the image, so
28+
# editing it takes effect on the next `docker compose up` with no image rebuild.
29+
# The image is useless without the mount anyway — it carries no site content.
30+
#
31+
# Invoked through `sh` rather than executed directly, so it does not depend on the
32+
# execute bit surviving however the tree reached the host (archive extraction, a
33+
# copy across filesystems, a Windows checkout).
34+
ENTRYPOINT ["/bin/sh", "/src/docker-entrypoint.sh"]
35+
CMD ["npm", "run", "serve"]

0 commit comments

Comments
 (0)