Writing documentation
New documentation is always welcome!
Start by cloning the documentation repository:
git clone \
https://gitlab.com/cki-project/documentation \
documentation
cd documentation
The documentation uses Hugo with the Docsy theme to build the site,
imported using Hugo Modules.
All requirements can be installed via the system package manager, but we recommend,
instead, to execute all of the commands in the shell of a container
with everything preinstalled via make podman.
In case you really want to install the dependencies, look for
“dependencies for documentation” in the hugo-docs Dockerfile.
Add new documentation as markdown files inside the appropriate directory
under content/. Every file should end in .md.
Documentation can be previewed by running make serve. A local web server will
start and automatically refresh the preview each time a change is saved.
Check for syntax problems by running make lint. If you are dealing with URLs,
check if any of them is broken with make link-check.
To submit changes, fork the repository, add the fork as a remote to the checkout and commit the changes. Push them to a new branch in the fork, and start a merge request against the parent.
TL;DR
make podman: Start the development containermake lint: Check for errorsmake link-check: Check for broken URLsmake serve: Run documentation web server
Testing with local module branches
The documentation pulls content from other CKI repositories via Hugo Modules:
cki-lib, cki-tools, datawarehouse, pipeline-data, and containers. To
test changes to those modules before they are merged, you can use local checkouts.
With direnv (recommended):
If you have the CKI repositories checked out as siblings under a common parent
directory (e.g., /path/to/cki/), create an .envrc file in the parent or
documentation directory:
# Example .envrc in /path/to/cki/
export CKI_LIB_REPO_PATH="${PWD}/cki-lib"
export CKI_TOOLS_REPO_PATH="${PWD}/cki-tools"
export DATAWAREHOUSE_REPO_PATH="${PWD}/datawarehouse"
export PIPELINE_DATA_REPO_PATH="${PWD}/pipeline-data"
export CONTAINERS_REPO_PATH="${PWD}/containers"
export DOCUMENTATION_REPO_PATH="${PWD}/documentation" # For internal-documentation
Then local checkouts are used automatically:
cd /path/to/cki/documentation
direnv allow # First time only
make serve # Uses sibling repos
Manual (absolute paths required):
CKI_LIB_REPO_PATH=/path/to/cki/cki-lib make serve
Supported variables:
| Variable | Module path / Purpose |
|---|---|
CKI_LIB_REPO_PATH |
gitlab.com/cki-project/cki-lib |
CKI_TOOLS_REPO_PATH |
gitlab.com/cki-project/cki-tools |
DATAWAREHOUSE_REPO_PATH |
gitlab.com/cki-project/datawarehouse |
PIPELINE_DATA_REPO_PATH |
gitlab.com/cki-project/pipeline-data |
CONTAINERS_REPO_PATH |
gitlab.com/cki-project/containers |
DOCUMENTATION_REPO_PATH |
For internal-documentation |
Changes in the local module repositories are reflected immediately via Hugo’s live reload.
Internal repository
The CKI documentation is open by default and maintained via the public repository. Additionally, an internal repository exists to be able to provide further confidential information.
The contents of these two repositories are used to generate two different versions of the documentation:
- the public documentation, solely based on information from the public repository
- the internal documentation, based on information from the public repository, supplemented by confidential details about internal infrastructure from the internal documentation repository. This is done using Hugo Modules to interleave files from the repositories, with files from the internal repository taking precedence. This allows the internal repository to add or overwrite files from the public repository.
The internal documentation is redeployed when changes to the public repository are merged.
To contribute to the internal repository, clone it next to the public repository
and ensure the parent directory has DOCUMENTATION_REPO_PATH set (see
“Testing with local module branches” above):
git clone https://internal/documentation/repository.git internal-documentation
cd internal-documentation
echo -e "source_up\nsource .envrc.defaults" > .envrc
direnv allow
./symlink-public-repo.sh
make serve # Available at http://localhost:1314/
The .envrc.defaults sets HUGO_PORT=1314 (to run alongside public docs) and
HUGO_ENV=internal. The symlink-public-repo.sh script creates symbolic links
to the Makefile and linting configuration from the public repository.
Links and stable URLs
Page URLs are not stable. Pages may be reorganized at any time. Use /l/
aliases for links that need to remain valid.
Link format by context
| Context | Format | Example | Why |
|---|---|---|---|
| Same page bundle | Relative .md |
other-page.md |
Content moves together |
| Same section | Relative path | ../other-section/page.md |
Section moves together |
| Cross-section | Full URL + /l/ |
https://cki-project.org/l/writing-documentation |
Survives reorganization |
| External (CI, repos) | Full URL + /l/ |
https://cki-project.org/l/writing-documentation |
Must be absolute; survives reorg |
Hugo’s link render hook converts https://cki-project.org/... URLs to relative
links in the rendered site, so there is no performance penalty for full URLs.
Creating aliases
Add a /l/ alias to pages that are referenced externally or cross-section:
---
title: "Writing documentation"
aliases: [/l/writing-documentation]
---
Add an alias when the page is:
- Referenced from other CKI repositories or CI configurations
- Linked cross-section within the documentation
- Mentioned in merge request templates or comments
Adding confidential information
With Hugo, content is organized into page bundles.
As an example, consider the following structure in the public repository:
documentation/content/
\- _index.md
\- page1.md
\- page2/
\- index.md
This will generate three pages: an index page for the top-level _index.md,
and two content pages for page1.md and page2/index.md.
To include confidential content from additional Markdown files supplied via the internal repository:
-
In the public repository, move content Markdown files in branch bundles (directories with a
_index.mdfile) into separate leaf bundles. In the example, this means movingpage1.mdinto a separate directory:documentation/content/ \- _index.md \- page1/ \- index.md \- page2/ \- index.md -
In the internal repository, add the confidential content as a separate Markdown file in the appropriate page bundle:
internal-documentation/content/ \- page1/ \- confidential-section.mdThis is what
content/page1/confidential-section.mdin the internal repository could look like:--- build: list: never publishResources: false render: never --- <!-- markdownlint-disable first-line-heading --> ## Confidential section Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ... -
In the front matter of
content/page1/index.mdin the public repository, mark the page as having a companion page:--- companion: true --- ...Include the file with the confidential content with the
includeshortcode:... {{% include "confidential-section.md" %}} ...When the public documentation is rendered, the missing include is ignored gracefully.