Documentation (DRAFT)

Tablet of Contents

Developer Documentation

TBD

Technical Documentation

I have created a template/demo repository for technical documentation:

For technical documentation, a user should not have to browse through the code repository on GitHub.  The user should also have many options to read the technical documentation: Easily navigatable web page, PDF, ePub for eReaders, etc.  The following is a proposal on how to approach technical documentation that is simple for contributors to manage the documentation and simple for readers to take in. 

Sphinx

Sphinx is a tool that allows us to create documentation using simple markup languages and generate multiple output formats: HTML, LaTeX, PDF, Confluence, ePub, and plain text.  It has an easy to understand hierarchical structure with automatic indices. More importantly, it has a large community building plugins & extensions.

To learn more, visit: https://www.sphinx-doc.org

Plugins/Extensions

The power of Sphinx is in its plugin support.  We are currently using 4 plugins to make life easier for a contributor:

  • sphinx_rtd_theme - Read the Docs (https://docs.readthedocs.io) is used quite a bit in the open-source community and providing a familiar experience using their theme with our documentation for users and contributors has obvious benefits. 
  • sphinxcontrib-drawio - This allows direct reference of *.drawio files directly within the documentation, so no need to export as png every time you make a simple edit eliminating the chance of out-of-sync files and images.
    • reStructuredText:

      .. drawio-figure:: my-awesome-model.drawio
    • Markdown:

      ```{drawio-figure} my-awesome-model.drawio
      ```
  • myst-parser - By default, Sphinx uses reStructuredText (another markup language similar to Markdown).  This plugin allows Markdown support within Sphinx to make it easier to those not wanting to learn another language. For more information, please see: https://myst-parser.readthedocs.io
  • sphinxcontrib-plantuml - similar to the drawio plugin.  It allows PlantUML files to be directly referenced in the documentation.

There are so many more plugins that we can use to make our life easier since documentation is never anyone's favorite task:  https://github.com/sphinx-contrib/

Docker

It is often necesseary to generate the documentation locally to verify your changes before commiting.  To make life easier for a contributor, I have packaged all of the installation, plugins, and configurations in a docker image so that the same container that builds the documentation locally is the same container that the CI environment builds for deployment. 

Source: https://github.com/jaredweinfurtner/sphinx-drawio-docker
Docker Hub: https://hub.docker.com/repository/docker/jaredweinfurtner/sphinx-drawio-docker

Simply run the following in the /docs folder to generate the static html with the Read the Docs theme:

docker run --rm -v `pwd`:/docs jaredweinfurtner/sphinx-drawio-docker make html

Structure

Inside the /docs folder, the following structure is proposed:

build
│
├───html
│   ├─  ...
│   └─  index.html
│      
└───latex
    ├─  ...
    └─  docs-project-layout.pdf

source
│   ├─ index.rst    
│   └─ conf.py
│
├───section
│   ├─  overview.md
│   └─  my-drawing.drawio
│   
└───section
    ├─  overview.md
    └─  my-drawing.drawio


/build/**
Contains generated documentation and should be ignored via .gitignore

/build/html/**
Contains static html that can be deployed as any other static html site - for example to: Read the Docs, GitHub Pages, etc

/build/latex/**
Contains mainly cached files for quicker follow-up generation of the pdf, but your *.pdf should be buried in here somewhere

/source/index.rst|md
This is your landing page and should contain the tree structure of your documentation. I highly recommend separating each section & subsection into its own folder so that you can include any diagrams alongside the .rst file.

/source/conf.py
This is the Sphinx configuration file and is the only thing you need to copy & configure into your own project. Simply set the properties listed at the top for your particular project:

# -- Project information -----------------------------------------------------

project = 'My Awesome Project'
author = 'Max Mustermann'
copyright = '© 1984-2021 Max Mustermann'

# The full version, including alpha/beta/rc tags
release = '0.0.1'

GitHub Pages

GitHub Pages offers static html hosting of our generated Sphinx documentation with the ReadTheDocs theme.  It nicely binds the project's GitHub repo with technical documentation so the user experience is seamless.  It offers automatic publishing by designating a git branch and a subfolder that contains the documentation (i.e. docs branch with a /docs subfolder).  Normally GitHub uses Markdown to generate the documentation, but it doesn't have the capabilities of Sphinx plugin support (such as draw.io, PlantUML, PDF support).

For more information, please see: https://pages.github.com

Compatibility with Sphinx

Out-of-the-box GitHub Pages is not compatible with Sphinx structure; however, it is easily fixed.  To configure GitHub pages to simply host the statically generated Sphinx documentation (instead of its own processing/theme), we simply add an empty.nojekyll file in the /docs folder. There's even an extension sphinx.ext.githubpages that takes care of that automatically (example).

Build / Deployment

It is good standard practice to never check-in generated code to a git repo, so we do not check-in the generated Sphinx html from our local environments.  Therefore, it is necessary to generate the documentation (static html) in a CI environment and push it to the docs branch under the /docs folder so that GitHub Pages can automatically deploy it.

GitHub Actions

GitHub Actions is GitHub's CI system (think Jenkins) and allows us to trigger our static html generation whenever a change is made to the master branch.  We simply generate the static html via the same docker command we use locally during development, move the static html to the root /docs folder for GitHub Pages, add the .nojekyll to tell GitHub Pages to simply host our own static html.

Example GitHub Action for GitHub Pages integration (example result: https://jaredweinfurtner.github.io/docs-project-layout/):

doc-generation.yml
# This is a basic workflow to help you get started with Actions

name: Documentation

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the main branch
  push:
    branches: [ main ]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
      with:
        persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token
        fetch-depth: 0 # otherwise, you will failed to push refs to dest repo
    - name: Generate Documentation
      run: |
        docker run --rm -v `pwd`/docs:/docs jaredweinfurtner/sphinx-drawio-docker make html
        cp -r docs/build/html/* ./docs
        touch docs/.nojekyll
    - name: Commit files
      run: |
        git add --all
        git config --local user.email "business-partner-agent[bot]@noreply.github.com"
        git config --local user.name "business-partner-agent[bot]"
        git commit -m "[bot] docs generation" -a
    - name: Push changes
      uses: ad-m/github-push-action@v0.6.0
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        branch: docs
        force: true