Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: docs

# Build the main Clawpack documentation (doc/doc) and fail on any NEW
# reStructuredText / docstring warning relative to the committed baseline
# (doc/doc/tools/doc_warnings_baseline.txt). This only parses/renders the
# docs (the `dummy` builder writes no HTML) and does not deploy.
#
# NOTE on the baseline: the set of warnings depends on the build environment
# (which clawpack packages are importable, which optional deps are mocked).
# The committed baseline must therefore be regenerated in THIS environment,
# not on a developer's full source checkout. Run the workflow manually
# (workflow_dispatch) to produce an updated baseline artifact, then commit it.
# Until that is done, treat this check as informational in branch protection.

on:
pull_request:
branches: [dev, v5.14.x]
push:
branches: [dev, v5.14.x]
workflow_dispatch:
inputs:
update_baseline:
description: 'Regenerate the warning baseline and upload it as an artifact'
type: boolean
default: false

jobs:
checkwarnings:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: '3.12'

# gfortran is needed to build the clawpack Fortran extensions on install.
- name: Install system build dependencies
run: sudo apt-get update && sudo apt-get install -y gfortran

- name: Install the documentation toolchain
run: pip install -r doc/tools/requirements-docs.txt

# autodoc imports the clawpack subpackages; petclaw/petsc4py is optional
# and mocked in conf.py, so it is intentionally NOT installed here. If a
# different subpackage fails to import, add it to autodoc_mock_imports in
# doc/conf.py rather than installing heavy/optional deps.
- name: Install clawpack (for autodoc imports)
run: pip install clawpack

- name: Check for new documentation warnings
if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.update_baseline) }}
working-directory: doc
run: make checkwarnings

# Manual path: regenerate the baseline in the CI environment and upload it
# so a maintainer can commit the environment-consistent version.
- name: Regenerate baseline
if: ${{ github.event_name == 'workflow_dispatch' && inputs.update_baseline }}
working-directory: doc
run: make checkwarnings-update

- name: Upload regenerated baseline
if: ${{ github.event_name == 'workflow_dispatch' && inputs.update_baseline }}
uses: actions/upload-artifact@v4
with:
name: doc_warnings_baseline
path: doc/tools/doc_warnings_baseline.txt
14 changes: 13 additions & 1 deletion doc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ else
LAYOUT = _themes/flask_local/layout.html
endif

.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest checkwarnings checkwarnings-update checkwarnings-strict

help:
@echo "Please use \`make <target>' where <target> is one of"
Expand All @@ -39,6 +39,9 @@ help:
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " checkwarnings to fail on any NEW reST/docstring warning (vs the baseline)"
@echo " checkwarnings-update to regenerate the warning baseline (tools/doc_warnings_baseline.txt)"
@echo " checkwarnings-strict to fail on ANY reST/docstring warning, ignoring the baseline"

clean:
-rm -rf $(BUILDDIR)/*
Expand Down Expand Up @@ -140,3 +143,12 @@ doctest:
versions:
sphinx-multiversion . _build/html

checkwarnings:
python tools/check_doc_warnings.py

checkwarnings-update:
python tools/check_doc_warnings.py --update

checkwarnings-strict:
python tools/check_doc_warnings.py --strict

29 changes: 28 additions & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,22 @@

import sys, os

# Some optional clawpack subpackages (petclaw, forestclaw) call
# logging.config.fileConfig() at import time with the default
# disable_existing_loggers=True. During the docs build autodoc/pycode import
# these modules *after* Sphinx has installed its warning logger, so that call
# would disable it and silently swallow every subsequent reST/docstring
# warning (they still get embedded in the HTML, but never reported). Force
# disable_existing_loggers=False for any fileConfig call so importing these
# packages can no longer muzzle Sphinx's warnings.
# (The underlying bug is those packages' __init__.py; see the docs CI notes.)
import logging.config as _logging_config
_orig_fileConfig = _logging_config.fileConfig
def _safe_fileConfig(*args, **kwargs):
kwargs['disable_existing_loggers'] = False
return _orig_fileConfig(*args, **kwargs)
_logging_config.fileConfig = _safe_fileConfig

# If your extensions are in another directory, add it here. If the directory
# is relative to the documentation root, use os.path.abspath to make it
# absolute, like shown here.
Expand Down Expand Up @@ -47,6 +63,13 @@
'srclinks']


# autodoc imports the documented modules at build time. petclaw/petsc4py is
# optional, heavy, and currently untested in the pip-only doc-build environment
# (including CI), so mock it to keep autodoc imports from failing. Add further
# entries here if other optional/compiled modules fail to import.
autodoc_mock_imports = ['petsc4py', 'clawpack.petclaw']


mathjax_path = 'https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'


Expand Down Expand Up @@ -261,7 +284,11 @@
#latex_use_modindex = True


keep_warnings = True
# Do not embed docutils warnings as "System Message" nodes in the rendered
# HTML. Warnings are still written to stderr / the sphinx warning log, where
# they are caught by ``make checkwarnings`` (see tools/check_doc_warnings.py)
# and the docs CI workflow, instead of being silently baked into the pages.
keep_warnings = False

inheritance_graph_attrs = dict(rankdir="TB",
fontsize=12,splines='"true"',penwidth=100)
Expand Down
62 changes: 62 additions & 0 deletions doc/howto_doc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,68 @@ Note that we suggest using `_build1` when building a single version so this
can be quickly rebuilt when writing and editing documentation.


.. _howto_doc_warnings:

Checking for documentation warnings
-----------------------------------

Sphinx does not fail the build on reStructuredText or docstring problems
(a missing blank line before a list, a bad cross reference, an autodoc import
issue, and so on). Historically these warnings were also *embedded* into the
rendered HTML as "System Message" boxes (via `keep_warnings = True` in
`conf.py`) while not being obvious on the command line, so they could slip
onto the website unnoticed. `keep_warnings` is now `False`, and the
following `make` targets let you catch warnings before they are merged.

To fail on any warning that is **new** relative to a committed baseline
(`tools/doc_warnings_baseline.txt`)::

cd $CLAW/doc/doc
make checkwarnings

This does a full re-parse using the lightweight `dummy` builder (no HTML is
written) and compares the result against the baseline, which records the
warnings that already existed when the check was introduced. Only newly
introduced warnings cause a non-zero exit, so you can fix the backlog
gradually without the check going red on unrelated pages.

If you intentionally add or remove warnings (e.g. after fixing a batch of
them), regenerate and commit the baseline::

make checkwarnings-update

To ignore the baseline entirely and report **every** remaining warning --
the goal once the backlog has been driven to zero -- use::

make checkwarnings-strict

The same check runs in CI (`.github/workflows/docs.yml`) on pull requests to
`dev` and the current release branch. Because `autodoc` imports the clawpack
packages, CI installs them with `pip`; the optional parallel package
`petclaw` (and `petsc4py`) is not installed but is instead listed in
`autodoc_mock_imports` in `conf.py`.

.. note::

The exact set of warnings depends on which packages are importable, so the
baseline is environment dependent. Regenerate it in the same environment
the CI workflow uses (see `tools/requirements-docs.txt`); the workflow can
be run manually to produce an updated baseline as an artifact.

**Possible future enhancements:**

- Extend the same warning check to the separate `gallery` Sphinx project
(`$CLAW/doc/gallery`), which first requires running the examples that
generate its figures.
- Turn off `keep_warnings` in `gallery/conf.py` and `doc/pyclaw/conf.py`
(used only for standalone pyclaw builds) for consistency.
- Once the baseline is empty, switch CI to `make checkwarnings-strict` and
optionally enable nitpicky (`-n`) cross-reference checking.
- Reconcile the build/deploy directory mismatch: `make html` writes to
`_build1/html`, while deployment (below) rsyncs from `_build/html`, the
`make versions` output.


To generate docs including previous versions
--------------------------------------------

Expand Down
Loading