docs: add Sphinx documentation build and deploy workflow
Some checks failed
CVE Scan & Docker Build / security-scan (push) Successful in 3m12s
CVE Scan & Docker Build / build-and-push (push) Successful in 2m38s
Build & Deploy Docs / build-and-deploy (push) Failing after 1m31s

- Add Gitea Actions workflow to build and deploy docs on push to main
- Generate Sphinx reference documentation for all apps and modules
- Deploy versioned and latest docs via rsync over SSH
This commit is contained in:
2026-05-23 06:11:05 -04:00
parent 50dffe688b
commit f8a2cf0c3d
114 changed files with 1797 additions and 2 deletions

102
.gitea/workflows/docs.yml Normal file
View File

@@ -0,0 +1,102 @@
name: Build & Deploy Docs
on:
push:
branches: [main]
paths:
- 'mnemosyne/**'
- 'docs/**'
- 'pyproject.toml'
- '.gitea/workflows/docs.yml'
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install package + docs deps
run: |
pip install --upgrade pip
pip install -e ".[docs]"
- name: Read version from pyproject.toml
id: version
run: |
VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
# ─── Failure-debug trio (REQUIRED) ─────────────────────────────────
- name: Build HTML
id: build_html
run: |
cd docs
./regenerate_docs.sh
continue-on-error: true
- name: Print Sphinx error log on failure
if: steps.build_html.outcome == 'failure'
run: |
echo "=== Sphinx error log ==="
cat /tmp/sphinx-err-*.log 2>/dev/null || echo "(no sphinx error log found)"
- name: Fail if build failed
if: steps.build_html.outcome == 'failure'
run: exit 1
# ───────────────────────────────────────────────────────────────────
- name: Install rsync + openssh
run: |
apt-get update
apt-get install -y --no-install-recommends rsync openssh-client
- name: Configure SSH
run: |
mkdir -p ~/.ssh
printf '%s\n' "${{ secrets.DOCS_DEPLOY_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan -p ${{ vars.DOCS_HOST_PORT }} ${{ vars.DOCS_HOST }} >> ~/.ssh/known_hosts
- name: Test SSH connectivity
run: |
ssh -o BatchMode=yes -o ConnectTimeout=10 \
-p ${{ vars.DOCS_HOST_PORT }} -i ~/.ssh/id_ed25519 \
git@${{ vars.DOCS_HOST }} "id && echo 'SSH OK'"
- name: Rsync to versioned path
run: |
rsync -av --delete \
-e "ssh -p ${{ vars.DOCS_HOST_PORT }} -i ~/.ssh/id_ed25519" \
docs/_build/html/ \
git@${{ vars.DOCS_HOST }}:/var/www/docs/mnemosyne/${{ steps.version.outputs.version }}/
- name: Rsync to latest
run: |
rsync -av --delete \
-e "ssh -p ${{ vars.DOCS_HOST_PORT }} -i ~/.ssh/id_ed25519" \
docs/_build/html/ \
git@${{ vars.DOCS_HOST }}:/var/www/docs/mnemosyne/latest/
- name: Regenerate versions index
run: |
ssh -p ${{ vars.DOCS_HOST_PORT }} -i ~/.ssh/id_ed25519 git@${{ vars.DOCS_HOST }} \
'python3 - <<PY
import pathlib
root = pathlib.Path("/var/www/docs/mnemosyne")
versions = sorted(
(p.name for p in root.iterdir() if p.is_dir()),
reverse=True,
)
html = ["<!DOCTYPE html><html><head><title>Mnemosyne Docs</title></head><body>",
"<h1>Mnemosyne Documentation</h1><ul>"]
for v in versions:
html.append(f"<li><a href=\"{v}/\">{v}</a></li>")
html.append("</ul></body></html>")
(root / "index.html").write_text("\n".join(html))
PY'