Sphinx Documentation Build

Overview

cikit integrates generated reports and registered artifacts into a Sphinx documentation build.

The reusable workflow consists of two main macro steps:

registered cikit artifacts
    |
    v
sphinx.prepare()
    |
    +-- docs/_generated/
    +-- docs/_static/badges/
    `-- docs/_static/artifacts/
    |
    v
sphinx.sphinx()
    |
    v
HTML documentation
    |
    v
FOLDER artifact named "html"

Project-specific documentation commands may add additional preparation between prepare() and the final Sphinx build.

The Sphinx macro itself is provider-independent. Publishing the generated HTML through GitLab Pages, Azure DevOps, or another CI platform is a separate deployment concern.

Typical Project Command

A project normally wraps the reusable Sphinx macros in a ci_commands module.

A minimal command can look like this:

import argparse
from pathlib import Path

from cikit import CiSection
from cikit.ci import run_ci_script
from cikit.macros import sphinx


def run(env, status, args: argparse.Namespace):
    docs_dir = env.resolve_path(args.docs_dir)

    with CiSection("Preparing sphinx", status=status):
        sphinx.prepare(env, docs_dir)

    with CiSection("Generating badge include", status=status):
        sphinx.generate_badges_include(env, docs_dir)

    with CiSection("Running sphinx", status=status):
        sphinx.sphinx(env, docs_dir)


def command(args: argparse.Namespace) -> int:
    return run_ci_script(
        "sphinx",
        lambda env, status: run(env, status, args),
        args=args,
    )


def register(subparsers: argparse._SubParsersAction):
    parser = subparsers.add_parser(
        "sphinx",
        help="Build Sphinx documentation.",
    )
    parser.add_argument(
        "docs_dir",
        nargs="?",
        type=Path,
        default=Path("docs"),
    )
    parser.set_defaults(func=command)

The current cikit repository adds one project-specific step that generates the timeline preset gallery. That step is not part of the reusable Sphinx macro.

Building Documentation

With the project command registered, documentation can be built with:

uv run cikit sphinx

The default Sphinx source directory in the current cikit command is:

docs

A different source directory can be supplied:

uv run cikit sphinx path/to/docs

Preparation

sphinx.prepare(env, docs_dir) prepares the Sphinx source tree from the current artifact registry.

It:

  1. cleans the cikit-managed generated directories

  2. copies registered artifacts into their Sphinx locations

The method processes artifacts from all logical runs visible through env.get_artifacts().

This allows one documentation build to collect reports and outputs produced by earlier workflow commands.

Managed Directories

The preparation step manages:

docs/
|-- _generated/
`-- _static/
    |-- badges/
    `-- artifacts/

Before copying the current artifact set, these directories are removed when present:

docs/_generated/
docs/_static/badges/
docs/_static/artifacts/

They are recreated as needed while artifacts are copied.

The complete docs/_static directory is not removed.

Project-owned static files can therefore remain outside the cikit-managed subdirectories, for example:

docs/_static/logo/
docs/_static/css/
docs/_static/custom.js

Generated reports must be registered before preparation.

Manually maintained files should not be stored in docs/_generated or the cikit-managed static subdirectories because those locations are rebuilt from the artifact registry.

Artifact Mapping

Registered artifacts are mapped into the Sphinx source tree according to their artifact type.

RST Artifacts

RST artifacts are copied to:

docs/_generated/

For example:

public/rst/coverage.rst
    |
    v
docs/_generated/coverage.rst

Generated report pages can then be referenced from normal Sphinx toctrees.

Badge Artifacts

BADGE artifacts are copied to:

docs/_static/badges/

For example:

public/badges/coverage.svg
    |
    v
docs/_static/badges/coverage.svg

Other Artifacts

All registered artifacts except RST and BADGE artifacts are copied to:

docs/_static/artifacts/

The original artifact target name and directory structure are preserved.

For details about the available artifact types, see Artifacts.

Badge Include

Badge images can be collected into one reusable include file with:

sphinx.generate_badges_include(env, docs_dir)

The default output is:

docs/badges.inc

The generated file contains one image directive for every registered BADGE artifact.

A documentation page can include it with:

.. include:: badges.inc

generate_badges_include() only creates the RST include.

The badge SVG files themselves are copied into docs/_static/badges by sphinx.prepare().

Sphinx Extensions

Projects using cikit-specific RST elements should enable the bundled extension in conf.py:

extensions = [
    "cikit.sphinx_ext",
]

The prepared artifacts reside below docs/_static, so a normal HTML configuration also includes:

html_static_path = ["_static"]

Generated cikit reports can then use cikit-specific roles and directives.

For the extension API and rendering behavior, see Sphinx Extensions.

cikit Data During the Build

sphinx.sphinx() supplies the current local cikit data directory to Sphinx through:

-D cikit_data_dir=${CIKIT_DATA_DIR}

This value is consumed by the cikit-metric extension.

Conceptually, the generated command is:

sphinx-build \
    -b html \
    -D cikit_data_dir=<CIKIT_DATA_DIR> \
    <docs_dir> \
    <temporary_html_dir>

This allows Sphinx to resolve current run values directly from the local cikit data cache without copying that cache into the documentation source tree.

For details about cikit data, see Cikit Data.

Building and Registering HTML

sphinx.sphinx(env, docs_dir) performs the final HTML build.

The macro:

  1. resolves the documentation source directory

  2. creates a temporary HTML output directory

  3. executes sphinx-build -b html

  4. passes CIKIT_DATA_DIR through cikit_data_dir

  5. registers the completed HTML directory as a FOLDER artifact

Sphinx therefore does not build directly into PUBLIC_DIR.

The generated HTML first exists below:

<temporary directory>/html/

After a successful build it is registered through:

env.copy_artifact(
    output_dir,
    ArtifactType.FOLDER,
)

The final artifact has:

artifact type = FOLDER
target name   = html

With the current artifact layout, the persistent result is:

public/artifacts/html/

Consumers should still prefer the returned Artifact or artifact registry instead of constructing that path directly.

Generated Reports

Report macros generate RST artifacts that are collected by sphinx.prepare().

A typical flow is:

producer command
    |
    +-- run data
    +-- generated artifacts
    |
    v
report macro
    |
    v
RST artifact
    |
    v
sphinx.prepare()
    |
    v
docs/_generated/<report>.rst

The handwritten Sphinx source can expose these generated pages through normal toctrees.

For example:

.. toctree::
   :maxdepth: 1

   ../_generated/coverage

The individual report types and their artifact dependencies are documented in their corresponding guides and in Artifacts.

Project-Specific Preparation

Projects may add documentation-generation steps between sphinx.prepare() and sphinx.sphinx().

The current cikit project adds:

sphinx.prepare()
    |
generate_badges_include()
    |
generate_timeline_chart_guide()
    |
sphinx.sphinx()

generate_timeline_chart_guide() is implemented in the project-local ci_commands/sphinx.py and creates the timeline preset gallery.

This keeps reusable Sphinx behavior in cikit.macros.sphinx while project-specific documentation generation remains in the project command.

Provider Independence

The Sphinx macro contains no provider-specific deployment logic.

The same command:

uv run cikit sphinx docs

can run locally or inside a supported CI provider.

The Sphinx build always produces the registered HTML folder artifact first.

Publishing that artifact is handled separately by the active CI configuration.

For example, the current GitLab setup publishes:

public/artifacts/html

through a dedicated Pages deployment job.

Provider-specific publication belongs in the corresponding CI guide rather than in the Sphinx macro.

See Also