
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
srcdirectory. - 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
mainbranch 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.mdhere 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_NAMEEXCLUDE_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/docwhere the output files are going to be stored. Doxygen will create the last directory (doc) if it does not exist, but thebuilddirectory 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 toYESto render the call dependency diagrams.CALLER_GRAPH: Set toYESto render the caller dependency diagrams.DOT_IMAGE_FORMAT: Set topng:cairo:cairo.DOT_PATH: Set to/usr/bin/dot. This is where thedotexecutable is usually stored in an Ubuntu image (in GitHub Actions).PLANTUML_JAR_PATH: Set to/usr/share/plantuml/plantuml.jar. This is where theplatuml.jarfile 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_AUTOBRIEFMARKDOWN_SUPPORT: Should be set toYES.AUTOLINK_SUPPORTBUILTIN_STL_SUPPORTEXTRACT_ALLEXTRACT_PRIVATEEXTRACT_PRIV_VIRTUALEXTRACT_PACKAGEEXTRACT_STATICEXTRACT_LOCAL_METHODSEXTRACT_ANON_NSPACESUSE_MDFILE_AS_MAINPAGE: Set it toREADME.mdto use it as the main page. Make sure thatREADME.mdis also present inINPUTtag.SOURCE_BROWSERGENERATE_TREEVIEW: Set toYESto have a tree view on the left-hand side of the webpage.USE_MATHJAX: Set toYESto 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.jaranddotin the Doxygen config file for an Ubuntu image, so we need to use Ubuntu here. - Use
actions/checkoutso you can access your repository in$GITHUB_WORKSPACEor$. - Install
plantumlwithsudo apt-get update && sudo apt-get install -y plantuml. - (you might have to install
mathjaxas well. - Install
cmakewithjwlawson/actions-setup-cmakein 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-actionto handle Doxygen generation. Setdoxyfile-pathto./DoxyfileGithubAction. Do not forget that our relative path is based on theworking-directorywhich is set to., meaning the root directory of your repository copy on the server. - Use
peaceiris/actions-gh-pagesto automatically publish the content of<ROOT REPO DIR>/build/docon the repository’s GitHub Page. Setpublish_dirto$/build/doc. It will handle creating thegh-pagesbranch 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
Settingsmenu, click onPagesfrom the left menu bar, and selectDeploy from a branchforSources. Finally, selectgh-pagesandRoot /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 Permissionsradio button and check theAllow Github Actions to create and approve pull requestscheckbox.
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