Automated Doxygen deployment on GitHub Pages with diagrams
It took me almost 5 hours to figure out how to use Github Actions to automatically build and deploy Doxygen documentation on GitHub Pages when commits are pushed into a GitHub repository. There are some basic tutorials out there but what I was interested in was configuring Doxygen to use PlantUML
and Graphwiz/dot
to draw the class hierarchy, as well as some other handy diagrams. Once you get used to the procedure, you can find your way around quite easily, but since I usually end up forgetting how I solved a specific issue, here I will go through the steps that one needs to do, to deploy a working Github Action for Doxygen with PlantUML
and Dot
support.
Assumptions
Let’s assume that:
- We have a basic CMake C++ project.
- The sources are located in
src
directory. - The project has a lot of dependencies with no ready-to-use packages to install them from.
Goals
We are trying to achieve these goals:
- Set up a Github Action to build and deploy Doxygen documentation on the repository’s GitHub Page.
- The Action should be triggered on every push to the
main
branch of the repo. - The Doxygen-generated files should be hosted in the same repository but in a different branch that is automatically created in case it does not exist (
gh-pages
). - The Action should not require installing all the dependencies that our project needs to compile, since we are not interested in building the project, but to build the documentation of it.
- The Github Page to be accessible at:
<USERNAME>.github.io/<REPOSITORYNAME>
Steps
Create two Doxygen configs
Since we do not want the Doxygen config file to be dependent on configuring the CMake script and consequently,
having all the project dependencies installed, we need to have two Doxygen config files,
one for office-building the project on the premises, and another for the GitHub Action. This is required since we want PlantUML
and Graphwiz/dot
support. The path to plantuml.jar
and dot
executables should be specified in the Doxygen config file. Usually, this is done using CMake and its FindProgram()
and FindFile()
functionalities (check out these examples: FindPlantUML.cmake, FindDot.cmake) but for GitHub Actions we want to isolate building the project from building the Doxygen documentation to avoid installing all the dependencies that the project needs to be built. So, have a Doxygen.in
file that looks like this and another copy of it named DoxygenGithubAction
that looks like this. Store both files in the root directory of your repository. Note that one can use doxygen -g <FILENAME>
to generate a basic configuration file, but then the content should be modified further to meet the objectives.
The important tags are as follows:
INPUT
: The space-separated list of the files and folders that should be processed by Doxygen. PutREADME.md
here as well, if you want Doxygen to use it as the main page.RECURSIVE
: Should be set toON
. This way the nested directories are also going to be scanned for sources.PROJECT_NAME
EXCLUDE_PATTERNS
: Could be used mutiple times as inEXCLUDE_PATTERNS += */cmake-build-release/*
andEXCLUDE_PATTERNS += */build/*
to exclude these directories from the scanning process.HTML_OUTPUT
: Set it tobuild/doc
where the output files are going to be stored. Doxygen will create the last directory (doc
) if it does not exist, but thebuild
directory should exist.GENERATE_LATEX
: Set toNO
. We are not interested in generating a PDF file.HAVE_DOT
: Set toYES
. This is required to render the caller/callee diagrams.UML_LOOK
: Set toYES
. This is required to render the collaboration and inheritance diagrams.CALL_GRAPH
: Set toYES
to render the call dependency diagrams.CALLER_GRAPH
: Set toYES
to render the caller dependency diagrams.DOT_IMAGE_FORMAT
: Set topng:cairo:cairo
.DOT_PATH
: Set to/usr/bin/dot
. This is where thedot
executable is usually stored in an Ubuntu image (in GitHub Actions).PLANTUML_JAR_PATH
: Set to/usr/share/plantuml/plantuml.jar
. This is where theplatuml.jar
file is stored in an Ubuntu image. For ArchLinux it is/usr/share/java/plantuml/plantuml.jar
.
The nice-to-have tags are as follows:
JAVADOC_AUTOBRIEF
MARKDOWN_SUPPORT
: Should be set toYES
.AUTOLINK_SUPPORT
BUILTIN_STL_SUPPORT
EXTRACT_ALL
EXTRACT_PRIVATE
EXTRACT_PRIV_VIRTUAL
EXTRACT_PACKAGE
EXTRACT_STATIC
EXTRACT_LOCAL_METHODS
EXTRACT_ANON_NSPACES
USE_MDFILE_AS_MAINPAGE
: Set it toREADME.md
to use it as the main page. Make sure thatREADME.md
is also present inINPUT
tag.SOURCE_BROWSER
GENERATE_TREEVIEW
: Set toYES
to have a tree view on the left-hand side of the webpage.USE_MATHJAX
: Set toYES
to have the math formulas written in LaTeX math format rendered in the output HTML files.TEMPLATE_RELATIONS
: Set toYES
.
Create main.yml
:
Create the hidden .github
folder. Inside, create another folder named workflows
. (mkdir -p .github/workflows
)
Then create a file named main.yml
inside workflows
directory with the content:
# This is a basic workflow to help you get started with Actions
name: Doxygen Action
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3.5.2
- name: Install plantuml
run: sudo apt-get update && sudo apt-get install -y plantuml
- name: actions-setup-cmake
uses: jwlawson/actions-setup-cmake@v1.14.0
with:
cmake-version: 'latest'
- name: configure our build dir
run: mkdir -p build/doc
- name: Doxygen Action
uses: mattnotmitt/doxygen-action@v1.9.5
with:
# Path to Doxyfile
doxyfile-path: "./DoxyfileGithubAction"
# Working directory
working-directory: "."
- name: Deploy
uses: peaceiris/actions-gh-pages@v3.9.3
with:
github_token: $
publish_dir: $/build/doc
- Set your master branch’s name in
branches: [<HERE>]
. Mine is calledmain
. - Set the image name to Ubuntu with
runs-on: ubuntu-latest
. We have hardcoded the paths toplantuml.jar
anddot
in the Doxygen config file for an Ubuntu image, so we need to use Ubuntu here. - Use
actions/checkout
so you can access your repository in$GITHUB_WORKSPACE
or$
. - Install
plantuml
withsudo apt-get update && sudo apt-get install -y plantuml
. - (you might have to install
mathjax
as well. - Install
cmake
withjwlawson/actions-setup-cmake
in case you do not want to hardcode the files paths into the Doxygen config file. (NOT NEEDED HERE) - Set up our output directories with
mkdir -p build/doc
. - Use
mattnotmitt/doxygen-action
to handle Doxygen generation. Setdoxyfile-path
to./DoxyfileGithubAction
. Do not forget that our relative path is based on theworking-directory
which is set to.
, meaning the root directory of your repository copy on the server. - Use
peaceiris/actions-gh-pages
to automatically publish the content of<ROOT REPO DIR>/build/doc
on the repository’s GitHub Page. Setpublish_dir
to$/build/doc
. It will handle creating thegh-pages
branch and pushing the files there. - On your local machine, commit the changes and push them to Github.
- Wait for the Action to finish.
- Make sure there are no errors.
- Go to your Github repository, click on the
Settings
menu, click onPages
from the left menu bar, and selectDeploy from a branch
forSources
. Finally, selectgh-pages
andRoot /
for the branch combo boxes. - You might need to allow Actions to write into your repository. Github Repo -> Settings -> Actions -> General: Select
Read and Write Permissions
radio button and check theAllow Github Actions to create and approve pull requests
checkbox.
Have a cup of coffee and enjoy the results
Now, you can access the deployed Github Page of the repository at https://<USERNAME>.github.io/<REPO NAME>
.
References
actions-gh-pages
doxygen-action
Github-Documentation-With-Doxygen
learn-github-actions
CGenCpp