No description
  • CSS 63.7%
  • JavaScript 29.4%
  • Python 5.4%
  • HTML 1.5%
Find a file
2026-05-09 23:15:03 +00:00
buildtools fix: use root-relative URLs in stork search index 2026-05-09 22:27:58 +00:00
docs feat: simplified build, use lato 2026-04-27 20:13:01 -04:00
static fix: apply Lato font to #toc-label 2026-05-09 23:15:03 +00:00
templates chore: complete update of templates/docinfo 2026-05-09 14:28:49 -04:00
.gitignore feat: docbuilder for asciidoc docs across all of simplefast 2026-04-22 13:30:03 -04:00
action.yml Update search placeholder text to 'Search all docs' 2026-05-09 17:01:25 +00:00
AGENTS.md docs: document mkMultiSite API and multi-source site composition 2026-05-09 17:36:13 +00:00
README.md docs: document mkMultiSite API and multi-source site composition 2026-05-09 17:36:13 +00:00

Docbuilder

A Forgejo custom action and Nix library that builds Asciidoc documentation into a static HTML site with full-text Stork search. Designed to be reusable across any repository that has a docs/ directory containing .adoc files.

Nix API

Docbuilder exposes two functions for use by other flakes:

mkSite — single docs tree

Builds a site from one docs/ directory:

inputs = {
  docbuilder = {
    url = "git+ssh://git@git.simple.fast/simplefast/docbuilder.git?shallow=1";
    inputs.nixpkgs.follows = "nixpkgs";
    inputs.flake-utils.follows = "flake-utils";
  };
};

outputs = { self, nixpkgs, flake-utils, docbuilder, ... }:
  flake-utils.lib.eachDefaultSystem (system: {
    packages.default = docbuilder.lib.${system}.mkSite {
      docs-src = self + "/docs";
    };
  });

Parameters:

Parameter Required Description
docs-src yes Path to the docs directory. Contains .adoc files and any project-specific assets.
site-title no Override site.nix title
site-subtitle no Override site.nix subtitle
search-placeholder no Override search input placeholder

The output is a derivation with the static site contents directly in $out/.

mkMultiSite — unified site from multiple source trees

Builds a single site from a root docs directory plus docs from multiple source repositories. All pages share one Stork search index.

Use case: a central nixpkgs flake builds a sitewide docs site at packages.simple.fast that aggregates documentation from every package.

# In nixpkgs flake.nix
nixpkgs-docs = callPackage ./pkgs/nixpkgs-docs {
  docbuilder = docbuilder;
  src = self;
  sources = {
    bot = inputs.bot-src;
    pi = inputs.pi-mono;
    skills = inputs.skills-src;
    rfd = inputs.rfd-src;
  };
};
# In pkgs/nixpkgs-docs/default.nix
{ docbuilder, lib, src, sources ? {} }:

let
  # Auto-discover: include only sources with a docs/ directory containing .adoc files.
  # The attr name becomes the URL path segment (e.g. "bot" -> /bot/).
  hasAdocDocs = path:
    builtins.pathExists path &&
    builtins.length (
      builtins.filter (name: lib.strings.hasSuffix ".adoc" name)
        (builtins.attrNames (builtins.readDir path))
    ) > 0;

  sections = lib.flatten (lib.mapAttrsToList (name: source:
    lib.optional (hasAdocDocs (source + "/docs")) {
      path = name;
      docs-src = source + "/docs";
    }
  ) sources);
in
docbuilder.mkMultiSite {
  root.docs-src = src + "/docs";
  inherit sections;
}

Parameters:

Parameter Required Description
root.docs-src yes Path to the root docs directory. Must contain site.nix; may contain index.adoc and other .adoc files that become top-level pages.
sections no List of { path, docs-src } attrsets. Each docs-src is copied into <path>/ in the output. Sections with no .adoc files are silently skipped.
site-title no Override site.nix title
site-subtitle no Override site.nix subtitle
search-placeholder no Override search input placeholder

Output structure

Given the nixpkgs config above (with bot, rfd having docs; pi and skills having none):

index.html                    # root docs: index.adoc
bot.html                      # root docs: bot.adoc (overview with links into bot/)
pi.html                       # root docs: pi.adoc
skills.html                   # root docs: skills.adoc
rfd.html                      # root docs: rfd.adoc
bot/
  architecture.html           # bot-src/docs/architecture.adoc
  observability.html          # bot-src/docs/observability.adoc
rfd/
  001.html, 002.html, ...    # rfd-src/docs/*.adoc
index.st                      # ONE Stork index across all pages
stork.js / stork.wasm
styles.css / fonts/

Cross-references between sections use relative links. From a root page, link to a section page with link:bot/architecture.html[Bot Architecture]. From within a section, link back with link:../pi.html[Pi].

Forgejo Action

Upload as artifact

Build docs and attach the site as a workflow artifact for download or use in later jobs:

# .forgejo/workflows/build-docs.yml
on:
  push:
    branches: [main]
  pull_request:

jobs:
  build-docs:
    runs-on: nix
    steps:
      - uses: actions/checkout@v4

      - name: Build documentation site
        id: docbuilder
        uses: https://git.simple.fast/Simple.Fast/docbuilder@main

      - name: Upload site artifact
        uses: actions/upload-artifact@v3
        with:
          name: docs-site
          path: ${{ steps.docbuilder.outputs.site-path }}

Deploy via rsync

Build and push the site to a server in one job:

# .forgejo/workflows/deploy-docs.yml
on:
  push:
    branches: [main]

jobs:
  deploy-docs:
    runs-on: nix
    steps:
      - uses: actions/checkout@v4

      - name: Build documentation site
        id: docbuilder
        uses: https://git.simple.fast/Simple.Fast/docbuilder@main

      - name: Deploy to server
        run: |
          rsync -avz --delete \
            ${{ steps.docbuilder.outputs.site-path }}/ \
            deploy@webserver.example.com:/var/www/docs/

Custom docs directory

If documentation lives somewhere other than docs/:

- uses: https://git.simple.fast/Simple.Fast/docbuilder@main
  with:
    docs-dir: src/documentation

Landing page

Docbuilder generates the landing page using niccup (hiccup-style HTML generation in Nix). Configuration comes from a site.nix file in the root docs directory:

# docs/site.nix
{
  site-title = "My Project";
  site-subtitle = "My Org";
  search-placeholder = "Search docs…";
}

All fields are optional. Defaults are Documentation, empty, and Search <title>….

If index.adoc exists in the root docs, it becomes the landing page. Otherwise, docbuilder generates a landing page with the site title and a search input.

Inputs

Input Default Description
docs-dir docs Path to docs directory relative to repo root

Outputs

Output Description
site-path Path to the static site root ready for serving or deployment

How it works

  1. Copies the docs directory (or merged tree for mkMultiSite) into the build sandbox
  2. Recursively finds all .adoc files and converts each to HTML via asciidoctor
  3. Preserves the folder structure in the output
  4. Copies binary assets (images, video, PDF) through, maintaining relative paths
  5. Reads site.nix from root docs for landing page configuration
  6. Generates landing page HTML via niccup with the configured title, subtitle, and search
  7. Builds a Stork full-text search index across all generated HTML (one index for the entire site)
  8. Bundles fonts, CSS, JS, and stork runtime into a self-contained output

Requirements

The runner must have Nix with flakes enabled. The runs-on: nix label must map to a host with nix in PATH and experimental-features = nix-command flakes configured.