From 1d3fed9a68a2c538abec703f61e147299aee37c7 Mon Sep 17 00:00:00 2001 From: thodson-usgs Date: Thu, 28 May 2026 17:12:16 -0400 Subject: [PATCH 1/2] ci: pass API_USGS_PAT to docs + test workflows when the secret is set Both workflows hit the live Water Data API: the doc build executes every notebook with no committed outputs (nbsphinx ``nbsphinx_execute`` defaults to ``'auto'`` and the project convention is no committed outputs); the test workflow runs the live ``tests/waterdata_test.py`` suite. Without an API key both run unauthenticated (~60 req/min), which is fragile as the demo notebook set and live-test count grow. Add ``env: API_USGS_PAT: ${{ secrets.API_USGS_PAT }}`` to the relevant step in each workflow. If the secret is not configured the variable resolves to an empty string and both workflows fall back to unauthenticated behavior (no change from today); once the secret is added in repo settings, both workflows pick up the higher authenticated quota automatically. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/python-package.yml | 6 ++++++ .github/workflows/sphinx-docs.yml | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 0ab3d142..4f02c7e8 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -47,6 +47,12 @@ jobs: python -m pip install --upgrade pip pip install .[test,nldi] - name: Test with pytest and report coverage + env: + # The live-API portion of ``tests/waterdata_test.py`` benefits + # from the authenticated rate limit. Undefined + # ``secrets.API_USGS_PAT`` resolves to an empty string — + # falling back to unauthenticated, same as today. + API_USGS_PAT: ${{ secrets.API_USGS_PAT }} run: | coverage run -m pytest tests/ coverage report -m diff --git a/.github/workflows/sphinx-docs.yml b/.github/workflows/sphinx-docs.yml index 2018279e..42e2d489 100644 --- a/.github/workflows/sphinx-docs.yml +++ b/.github/workflows/sphinx-docs.yml @@ -21,6 +21,15 @@ jobs: cache: "pip" - name: Install dataretrieval, dependencies, and Sphinx then build docs shell: bash -l {0} + env: + # nbsphinx executes every notebook with no committed outputs + # (the project convention; ``nbsphinx_execute`` defaults to + # ``'auto'``). Without an API key the doc build hits the + # unauthenticated rate limit (~60 req/min); the secret raises + # the ceiling so the build is reliable as the demo notebook set + # grows. Undefined ``secrets.API_USGS_PAT`` resolves to an + # empty string — falling back to unauthenticated, same as today. + API_USGS_PAT: ${{ secrets.API_USGS_PAT }} run: | python -m pip install --upgrade pip pip install .[doc,nldi] From b9f576ab0234294817a1276d24c57f718afbcef6 Mon Sep 17 00:00:00 2001 From: thodson-usgs Date: Thu, 28 May 2026 17:13:17 -0400 Subject: [PATCH 2/2] ci(docs): cache Sphinx build outputs across runs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sphinx tracks source mtimes against doctrees in ``${BUILDDIR}/.doctrees/``: unchanged sources skip re-parsing, which for nbsphinx (``nbsphinx_execute='auto'``) means unchanged notebooks aren't re-executed. Persisting ``docs/build/`` across CI runs picks up that free incremental behavior — most PRs touch a handful of source files, so the doc build only re-executes the actually-changed notebooks instead of the whole 19-notebook set. The cache key hashes every input that affects the rendered docs (notebooks, RST/MD, ``conf.py``, and the Python package — autodoc reads docstrings); any change invalidates exact-match. The ``restore-keys: sphinx-`` fallback gives partial-match recovery so even a cache-key miss restores recent doctrees, and Sphinx then only re-builds the files whose source actually changed. A proper jupyter-cache adoption via MyST-NB is the deeper migration path (``nb_execution_mode = 'cache'`` integrates jupyter-cache natively) but it requires reworking the existing ``.nblink`` references to external notebooks. This caches the equivalent via the build dir without the doc-tree rewrite. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/sphinx-docs.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.github/workflows/sphinx-docs.yml b/.github/workflows/sphinx-docs.yml index 42e2d489..42191d99 100644 --- a/.github/workflows/sphinx-docs.yml +++ b/.github/workflows/sphinx-docs.yml @@ -19,6 +19,25 @@ jobs: with: python-version: "3.13" cache: "pip" + + # Cache Sphinx's doctree + intermediate build outputs across CI runs, + # keyed on the hash of every source that affects the rendered docs + # (notebooks, RST/MD, conf.py, and the Python package — autodoc reads + # docstrings). Any source change invalidates the key, forcing a full + # rebuild; otherwise Sphinx skips re-parsing unchanged files, which + # for nbsphinx (``nbsphinx_execute='auto'``) means unchanged + # notebooks aren't re-executed. The HTML output is rebuilt against + # whatever doctrees we restore. (A proper jupyter-cache adoption via + # MyST-NB is the deeper migration path; this caches the equivalent + # via the build dir without the doc-tree rewrite.) + - name: Cache Sphinx build outputs + uses: actions/cache@v4 + with: + path: docs/build + key: sphinx-${{ hashFiles('demos/**/*.ipynb', 'docs/source/**/*.rst', 'docs/source/**/*.md', 'docs/source/conf.py', 'dataretrieval/**/*.py') }} + restore-keys: | + sphinx- + - name: Install dataretrieval, dependencies, and Sphinx then build docs shell: bash -l {0} env: