Skip to content

Convert MkDocs to PDF and CHM #34

Convert MkDocs to PDF and CHM

Convert MkDocs to PDF and CHM #34

Workflow file for this run

name: Convert MkDocs to PDF and CHM
on:
workflow_dispatch:
inputs:
generate_pdf:
description: 'Generate PDF documentation'
type: boolean
default: true
generate_chm:
description: 'Generate CHM help file'
type: boolean
default: true
jobs:
convert-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for git info
- name: Get Git Info
id: git-info
run: |
BRANCH=$(git rev-parse --abbrev-ref HEAD)
HASH=$(git rev-parse --short HEAD)
echo "GIT_INFO=${BRANCH}:${HASH}" >> $GITHUB_OUTPUT
echo "DATE=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
libcairo2-dev \
libpango1.0-dev \
libgdk-pixbuf2.0-dev \
libffi-dev \
shared-mime-info \
fonts-liberation \
fonts-dejavu \
fpc # for "chmcmd", part of Free Pascal
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install \
mkdocs \
mkdocs-material \
weasyprint \
beautifulsoup4 \
markdown \
ruamel.yaml \
pygments \
pymdown-extensions \
markdown-tables-extended \
git+https://github.com/flywire/caption \
htmlmin \
csscompressor \
cssutils
- name: Prepare directories
run: |
# Ensure output directories exist with proper permissions
mkdir -p pdf/output
chmod 755 pdf/output
mkdir -p chm/output
chmod 755 chm/output
# List directory structure for debugging
echo "Directory structure:"
ls -la pdf/
ls -la chm/
- name: Convert MkDocs to PDF
if: ${{ inputs.generate_pdf }}
env:
GIT_INFO: ${{ steps.git-info.outputs.GIT_INFO }}
BUILD_DATE: ${{ steps.git-info.outputs.DATE }}
working-directory: ${{ github.workspace }}
run: |
# Verify required files and directories exist
[ -f "pdf/mkdocs2pdf.py" ] || { echo "pdf/mkdocs2pdf.py not found"; exit 1; }
[ -f "mkdocs.yml" ] || { echo "mkdocs.yml not found in repository root"; exit 1; }
[ -d "pdf/assets" ] || { echo "pdf/assets directory not found"; exit 1; }
[ -f "pdf/config.json" ] || { echo "Error: pdf/config.json not found"; exit 1; }
chmod +x pdf/mkdocs2pdf.py
# Run the conversion script
python pdf/mkdocs2pdf.py \
--mkdocs-yml mkdocs.yml \
--config pdf/config.json \
--project-dir pdf/output \
--assets-dir pdf/assets
- name: Convert MkDocs to CHM
if: ${{ inputs.generate_chm }}
env:
GIT_INFO: ${{ steps.git-info.outputs.GIT_INFO }}
BUILD_DATE: ${{ steps.git-info.outputs.DATE }}
working-directory: ${{ github.workspace }}
run: |
# Verify required files and directories exist
[ -f "chm/mkdocs2chm.py" ] || { echo "chm/mkdocs2chm.py not found"; exit 1; }
[ -f "chm/config.json" ] || { echo "chm/config.json not found"; exit 1; }
[ -f "mkdocs.yml" ] || { echo "mkdocs.yml not found in repository root"; exit 1; }
[ -d "chm/assets" ] || { echo "chm/assets directory not found"; exit 1; }
chmod +x chm/mkdocs2chm.py
# Run the conversion script
python chm/mkdocs2chm.py \
--mkdocs-yml mkdocs.yml \
--project-dir chm/output \
--assets-dir chm/assets \
--config chm/config.json \
--welcome chm/welcome.md \
--git-info "$GIT_INFO" \
--build-date "$BUILD_DATE"
- name: Install yq
run: |
sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
sudo chmod +x /usr/local/bin/yq
- name: Get Version Info
id: version
run: |
# Get X.Y from mkdocs.yml
VERSION_XY=$(yq '.extra.version_majmin' mkdocs.yml)
# Get commit count for Z
COMMIT_COUNT=$(git rev-list --count HEAD)
# Construct full version
echo "VERSION=v${VERSION_XY}.${COMMIT_COUNT}" >> $GITHUB_OUTPUT
echo "Constructed version: v${VERSION_XY}.${COMMIT_COUNT}"
- name: Manage Draft Releases
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Configuration
MAX_DRAFTS=5 # Keep this many most recent drafts
# Function to get next available tag
get_available_tag() {
local base_tag=$1
local tag=$base_tag
local suffix=""
local letter="a"
while gh release view "$tag" &>/dev/null; do
echo "Tag $tag exists, trying next suffix..."
tag="${base_tag}${letter}"
# Increment letter (a -> b -> c etc)
letter=$(echo "$letter" | tr "a-y" "b-z")
done
echo "$tag"
}
# Clean up old draft releases
echo "Cleaning up old draft releases..."
# Get list of draft releases, using JSON output filtered by jq
DRAFTS=$(gh release list --json tagName,isDraft,createdAt \
--jq '.[] | select(.isDraft==true) | [.tagName,.createdAt] | @tsv' \
| sort -k2 | awk '{print $1}')
# Count total drafts
DRAFT_COUNT=$(echo "$DRAFTS" | grep -c "^" || true)
if [ $DRAFT_COUNT -gt $MAX_DRAFTS ]; then
# Calculate how many to delete
TO_DELETE=$((DRAFT_COUNT - MAX_DRAFTS + 1)) # +1 because we're about to create a new one
echo "Found $DRAFT_COUNT drafts, deleting $TO_DELETE oldest..."
# Delete oldest drafts
echo "$DRAFTS" | head -n $TO_DELETE | while read -r tag; do
echo "Deleting draft release $tag..."
gh release delete "$tag" --yes
done
fi
# Create release using version
BASE_TAG="${{ steps.version.outputs.VERSION }}"
RELEASE_TAG=$(get_available_tag "$BASE_TAG")
# Set release name and assets based on what was generated
if ${{ inputs.generate_pdf && inputs.generate_chm }}; then
RELEASE_NAME="Documentation PDFs and CHM $RELEASE_TAG"
ASSETS="pdf/output/*.pdf chm/output/*.chm"
NOTES="Documentation PDFs and CHM help file generated from ${{ steps.git-info.outputs.GIT_INFO }}"
elif ${{ inputs.generate_pdf }}; then
RELEASE_NAME="Documentation PDFs $RELEASE_TAG"
ASSETS="pdf/output/*.pdf"
NOTES="Documentation PDFs generated from ${{ steps.git-info.outputs.GIT_INFO }}"
else
RELEASE_NAME="Documentation CHM $RELEASE_TAG"
ASSETS="chm/output/*.chm"
NOTES="Documentation CHM help file generated from ${{ steps.git-info.outputs.GIT_INFO }}"
fi
echo "Creating new draft release: $RELEASE_TAG"
# Create a draft release with current syntax
gh release create "$RELEASE_TAG" \
$ASSETS \
--draft \
--title "$RELEASE_NAME" \
--notes "$NOTES"