Photo credit James Barnett on Unsplash
Many many months since the last dev log have passed. I’ve worked on and off a lot on this thing though, and there’s massive changes still to be released. So no version to actually point to for the code examples in this blog post, even if develop
is way ahead of master
. Still, I want to cover something, so I figured I can speak about the public documentation and how it’s written, managed, and generated.
Here’s a picture of how it currently looks like:
Every project should have some form of documentation. The baseline is a README.md
file in the root of the repo giving some hints of usage. This is sufficient at the start, but as the project becomes more complex it starts to show its limitations. Some table stakes features to have for a next-level system are: multi-page support, versioned docs linked to releases, Markdown (or equivalent) support, search capabilities, and web integrations (with web search, various micro-formats, etc).
That’s quite a feature list to support, but luckily the OSS friendly Read the Docs project exists and it perfectly fits the bill. It is basically a docs-as-a-service product. You link it with GitHub
and the particular repository you wish to host documentation for. Then you organise your docs in a particular way, configure it appropriately, and you get the kinds of docs jupiter now has.
Linking and configuring the sync is a manual process and is done by squishy humans. Everything else however is automated. The main interaction is responding to a webhook triggered by a code push, and building and publishing the docs. So quite similar to a CI/CD system. There was a bunch of config needed to make this happen, and a bunch of their concepts to get familiar with, but nothing too challenging.
My main and really only gripe with Read The Docs is this integration pattern. It’s quite old school: login with GitHub, everything gets setup in the background, a webhook is installed on the repo. The config is done on their website, by clicking buttons and typing into text fields. I would rather there was some URL to hit from CI/CD or even a GitHub action to use directly. And everything would be configured from a repo-level file. So all the things that happen as a result of a push were described and code and stored centrally in the repo. It’s a small nuisance in the grand scheme of things, but it does feel a little 2010s
.
On to the coding parts now! There is a .readthedocs.yaml
file in the root of the repository which looks like this:
---
version: 2
mkdocs:
configuration: mkdocs.yml
fail_on_warning: true
formats: all
python:
version: 3.7
It essentially tells Read the Docs to use mkdocs as the documentation site generator. There is also the sphinx option, and that’s generally the blessed option, but MkDocs is simpler and a better fit for what Jupiter needs in my opinion. There’s also a Python version requirement. This has nothing to do with the 3.8
used by Jupiter itself, but rather refers to what Read the Docs will use for building and compiling the documentation.
The bulk of the configuration is written in the mkdocs.yaml
file, which obviously targets MkDocs, and it currently looks like this:
---
site_name: Jupiter
site_description: "Documentation for Jupiter, the life planning tool"
site_author: "Horia Coman"
copyright: "(c) 2020 Horia Coman"
repo_url: https://github.com/horia141/jupiter
repo_name: GitHub
docs_dir: docs
theme:
name: mkdocs
highlightjs: true
hljs_style: obsidian
nav:
- Tutorial: 'tutorial.md'
- Concepts: 'concepts.md'
- Installation: 'install.md'
- 'How Tos':
- Workspaces:
- 'Initialize A Workspace': 'how-tos/workspaces/init-a-workspace.md'
- Releases:
- 'Version 0.3.0': 'releases/version-0.3.0.md'
- 'Version 0.2.0': 'releases/version-0.2.0.md'
- 'Version 0.1.6': 'releases/version-0.1.6.md'
- Older:
- 'Version 0.1.5': 'releases/version-0.1.5.md'
- 'Version 0.1.4': 'releases/version-0.1.4.md'
- 'Version 0.1.3': 'releases/version-0.1.3.md'
- 'Version 0.1.2': 'releases/version-0.1.2.md'
- 'Version 0.1.1': 'releases/version-0.1.1.md'
- 'Version 0.1.0': 'releases/version-0.1.0.md'
- 'Version 0.0.5': 'releases/version-0.0.5.md'
- 'Version 0.0.4': 'releases/version-0.0.4.md'
- 'Version 0.0.3': 'releases/version-0.0.3.md'
- 'Version 0.0.2': 'releases/version-0.0.2.md'
- 'Version 0.0.1': 'releases/version-0.0.1.md'
There’s the usual meta stuff there, but what’s interesting is the definition of the site structure and navigation. MkDocs can pick it up from the docs
folder, but through trial and error I’ve found out it’s better to explicitly define it, even if it’s more manual work. It results in a nav bar which looks like this:
For local development there is a make docs
command, which starts a local dev server at 127.0.0.1:8000
where you can check how the docs will look like once a new release is published. It even has hot swapping, which I always find pretty neat!
That’s about it really. It’s not much, but it actually achieves a lot, so the ROI for this work is great.
A thing to include in future work here is running the whole docs
tree through a preprocessing step, and replacing some inline values via macros. Things like the project’s public name, or some particular URL, etc. can change, so it’s better to keep them nice and tidy so that the various tools can use them uniformly. But that’s a problem for later.
That’s about it for this time, see you next time.
Top comments (0)